From cf6acc909685bf5bfa927e17b28da014bc8907b2 Mon Sep 17 00:00:00 2001 From: Cristian Silaghi Date: Thu, 7 Sep 2017 19:51:41 +0000 Subject: [PATCH 001/125] Pontoon: Update Romanian (ro) localization of Test Pilot: Notes Localization authors: - Cristian Silaghi --- locales/ro/notes.properties | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 locales/ro/notes.properties diff --git a/locales/ro/notes.properties b/locales/ro/notes.properties new file mode 100644 index 000000000..86b807a5a --- /dev/null +++ b/locales/ro/notes.properties @@ -0,0 +1,30 @@ +welcomeTitle2=Bună! + +emptyPlaceHolder=Ia notițe… + + +openingLogin=Se deschide autentificarea… +forgetEmail=Uită acest e-mail + +syncNotes=Sincronizează-ți notițele +syncProgress=Se sincronizează schimbările… +# LOCALIZATION NOTE (disableSync): Sync is intended as a generic +# synchronization, not Firefox Sync. +disableSync=Dezactivează sincronizarea +# LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this +# structure doesn't work for your locale, you can translate this as "Last sync: +# {date}". +syncComplete=Sincronizat în {date} + +# Tooltips for toolbar buttons +fontSizeTitle=Dimensiunea fontului +boldTitle=Aldin +italicTitle=Cursiv +numberedListTitle=Listă numerotată +bulletedListTitle=Listă cu marcatori +textDirectionTitle=Direcția textului + +# Settings page labels +themeLegend=Temă +defaultThemeTitle=Implicită +darkThemeTitle=Întunecată From c83c6f18c8eeb067a059bd665577f5c99cc5cb14 Mon Sep 17 00:00:00 2001 From: Cristian Silaghi Date: Thu, 7 Sep 2017 20:11:26 +0000 Subject: [PATCH 002/125] Pontoon: Update Romanian (ro) localization of Test Pilot: Notes Localization authors: - Cristian Silaghi --- locales/ro/notes.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/locales/ro/notes.properties b/locales/ro/notes.properties index 86b807a5a..216b258d5 100644 --- a/locales/ro/notes.properties +++ b/locales/ro/notes.properties @@ -1,11 +1,14 @@ welcomeTitle2=Bună! +welcomeText2=Bine ai venit pe acest carnețel cu o singură pagină, încorporat în Firefox. Navighează pe web. Scrie notițe. Este atât de simplu. emptyPlaceHolder=Ia notițe… +giveFeedback=Clic aici pentru a ne oferi feedback openingLogin=Se deschide autentificarea… forgetEmail=Uită acest e-mail +syncNotReady2=Ne pare rău, sincronizarea notițelor nu este chiar pregătită. Vom considera clicul tău drept un vot pentru a implementa sincronizarea mai rapid! syncNotes=Sincronizează-ți notițele syncProgress=Se sincronizează schimbările… # LOCALIZATION NOTE (disableSync): Sync is intended as a generic @@ -20,6 +23,7 @@ syncComplete=Sincronizat în {date} fontSizeTitle=Dimensiunea fontului boldTitle=Aldin italicTitle=Cursiv +strikethroughTitle=Taie textul numberedListTitle=Listă numerotată bulletedListTitle=Listă cu marcatori textDirectionTitle=Direcția textului From 5dd5e9d3999c3f222745f94cedb1dd4facb9495d Mon Sep 17 00:00:00 2001 From: Hyeonseok Shin Date: Thu, 14 Sep 2017 03:31:35 +0000 Subject: [PATCH 003/125] Pontoon: Update Korean (ko) localization of Test Pilot: Notes Localization authors: - Hyeonseok Shin --- locales/ko/notes.properties | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 locales/ko/notes.properties diff --git a/locales/ko/notes.properties b/locales/ko/notes.properties new file mode 100644 index 000000000..cc2b890d3 --- /dev/null +++ b/locales/ko/notes.properties @@ -0,0 +1,17 @@ +welcomeTitle2=안녕하세요! + + + +forgetEmail=이 이메일 없애기 + +# LOCALIZATION NOTE (disableSync): Sync is intended as a generic +# synchronization, not Firefox Sync. +# LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this +# structure doesn't work for your locale, you can translate this as "Last sync: +# {date}". + +# Tooltips for toolbar buttons +boldTitle=굵게 +italicTitle=기울임 + +# Settings page labels From dac61da2cba32ee681fbbe17d933f6b16227929d Mon Sep 17 00:00:00 2001 From: Hyeonseok Shin Date: Thu, 14 Sep 2017 03:50:56 +0000 Subject: [PATCH 004/125] Pontoon: Update Korean (ko) localization of Test Pilot: Notes Localization authors: - Hyeonseok Shin --- locales/ko/notes.properties | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/locales/ko/notes.properties b/locales/ko/notes.properties index cc2b890d3..54d180aa6 100644 --- a/locales/ko/notes.properties +++ b/locales/ko/notes.properties @@ -11,7 +11,15 @@ forgetEmail=이 이메일 없애기 # {date}". # Tooltips for toolbar buttons +fontSizeTitle=글자 크기 boldTitle=굵게 italicTitle=기울임 +strikethroughTitle=취소선 +numberedListTitle=번호 목록 +bulletedListTitle=번호없는 목록 +textDirectionTitle=텍스트 방향 # Settings page labels +themeLegend=테마 +defaultThemeTitle=기본 +darkThemeTitle=어두움 From a3c02be999341100abbb5cb0c78e10dc64c57bf5 Mon Sep 17 00:00:00 2001 From: Amanpreet Alam Date: Sun, 17 Sep 2017 13:31:20 +0000 Subject: [PATCH 005/125] Pontoon: Update Punjabi (pa-IN) localization of Test Pilot: Notes Localization authors: - Amanpreet Alam --- locales/pa-IN/notes.properties | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 locales/pa-IN/notes.properties diff --git a/locales/pa-IN/notes.properties b/locales/pa-IN/notes.properties new file mode 100644 index 000000000..a46d8ea22 --- /dev/null +++ b/locales/pa-IN/notes.properties @@ -0,0 +1,16 @@ +welcomeTitle2=ਹੈਲੋ! +welcomeText2=ਫਾਇਰਫਾਕਸ ਵਿੱਚ ਬਣੇ ਇਸ ਇੱਕ-ਸਫ਼ਾ ਨੋਟਪੈਡ ਵਿੱਚ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ। ਵੈੱਬ ਬਰਾਊਜ਼ ਕਰੋ। ਨੋਟਿਸ ਬਣਾਓ। ਇਹ ਬਹੁਤ ਆਸਾਨ ਹੈ। + +emptyPlaceHolder=…ਨੋਟ ਕਰੋ + + + +# LOCALIZATION NOTE (disableSync): Sync is intended as a generic +# synchronization, not Firefox Sync. +# LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this +# structure doesn't work for your locale, you can translate this as "Last sync: +# {date}". + +# Tooltips for toolbar buttons + +# Settings page labels From dca2e9c76e45def587261b6857af80574cd55862 Mon Sep 17 00:00:00 2001 From: Amanpreet Alam Date: Sun, 17 Sep 2017 13:51:08 +0000 Subject: [PATCH 006/125] Pontoon: Update Punjabi (pa-IN) localization of Test Pilot: Notes Localization authors: - mansimarkaur.mks - Amanpreet Alam --- locales/pa-IN/notes.properties | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/locales/pa-IN/notes.properties b/locales/pa-IN/notes.properties index a46d8ea22..1911813af 100644 --- a/locales/pa-IN/notes.properties +++ b/locales/pa-IN/notes.properties @@ -3,14 +3,32 @@ welcomeText2=ਫਾਇਰਫਾਕਸ ਵਿੱਚ ਬਣੇ ਇਸ ਇੱਕ- emptyPlaceHolder=…ਨੋਟ ਕਰੋ +giveFeedback=ਸਾਨੂੰ ਕੁਝ ਫੀਡਬੈਕ ਦੇਣ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ। +openingLogin=…ਲਾਗਇਨ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ +forgetEmail=ਇਹ ਈਮੇਲ ਨੂੰ ਭੁੱਲ ਜਾਓ +syncNotReady2=ਅਫ਼ਸੋਸ, ਨੋਟਿਸ ਸਿੰਕ ਕਰਨਾ ਹਾਲੇ ਤਿਆਰ ਨਹੀਂ ਹੈ। ਅਸੀਂ ਤੁਹਾਡੇ ਕਲਿੱਕ ਨੂੰ ਇਹ ਤਿਆਰ ਕਰਨ ਲਈ ਤੇਜ਼ੀ ਵਾਸਤੇ ਗਿਣਾਂਗੇ। +syncNotes=ਆਪਣੇ ਨੋਟਿਸਾਂ ਨੂੰ ਸਿੰਕ ਕਰੋ +syncProgress=…ਤਬਦੀਲੀਆਂ ਸਿੰਕ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ # LOCALIZATION NOTE (disableSync): Sync is intended as a generic # synchronization, not Firefox Sync. +disableSync=ਸਿੰਕ ਅਸਮਰੱਥ ਕਰੋ # LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this # structure doesn't work for your locale, you can translate this as "Last sync: # {date}". +syncComplete=ਸਿੰਕ ਕੀਤਾ {date} # Tooltips for toolbar buttons +fontSizeTitle=ਫੋਂਟ ਆਕਾਰ +boldTitle=ਗੂੜ੍ਹੇ +italicTitle=ਤਿਰਛੇ +strikethroughTitle=ਵਿੰਨ੍ਹੋ +numberedListTitle=ਨੰਬਰ ਸੂਚੀ +bulletedListTitle=ਬਿੰਦੀਆਂ ਵਾਲੀ ਸੂਚੀ +textDirectionTitle=ਲਿਖਤ ਦੀ ਦਿਸ਼ਾ # Settings page labels +themeLegend=ਥੀਮ +defaultThemeTitle=ਮੂਲ +darkThemeTitle=ਕਾਲਾਪਣ From 251dd65d4fe0cc45ec4569fe8913299e695c1df6 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Tue, 19 Sep 2017 15:13:02 -0400 Subject: [PATCH 007/125] Add kinto.js to build --- package.json | 1 + scripts/postinstall.js | 2 ++ src/manifest.json | 1 + 3 files changed, 4 insertions(+) diff --git a/package.json b/package.json index 87c01e3b9..f52ad0ddd 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "fxa-crypto-relier": "1.0.1", "jose-jwe-jws": "^0.1.5", "kinto-http": "^4.3.4", + "kinto": "^9.0.2", "quill": "1.2.6", "testpilot-ga": "^0.2.1" }, diff --git a/scripts/postinstall.js b/scripts/postinstall.js index 6f919d069..4f031261a 100755 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -9,6 +9,8 @@ const files = [ copySync('node_modules/quill/LICENSE', 'src/sidebar/vendor/quill.LICENSE'), copySync('node_modules/kinto-http/dist/kinto-http.min.js', 'src/vendor/kinto-http.js'), copySync('node_modules/kinto-http/LICENSE', 'src/vendor/kinto-http.LICENSE'), + copySync('node_modules/kinto/dist/kinto.noshim.js', 'src/vendor/kinto.js'), + copySync('node_modules/kinto/LICENSE', 'src/vendor/kinto.LICENSE'), copySync('node_modules/jose-jwe-jws/dist/jose.min.js', 'src/vendor/jose.js'), copySync('node_modules/jose-jwe-jws/LICENSE', 'src/vendor/jose.LICENCE'), copySync('node_modules/fxa-crypto-relier/dist/fxa-crypto-relier/fxa-crypto-relier.js', 'src/vendor/fxa-crypto-relier/fxa-crypto-relier.js') diff --git a/src/manifest.json b/src/manifest.json index 57886a3ac..491f57500 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -29,6 +29,7 @@ "scripts": [ "vendor/jose.js", "vendor/kinto-http.js", + "vendor/kinto.js", "vendor/fxa-crypto-relier/fxa-crypto-relier.js", "vendor/testpilot-ga.js", "sync.js", From fce284ba0977089b834f3571a864d90822a49dbf Mon Sep 17 00:00:00 2001 From: Cedric Amaya Date: Thu, 21 Sep 2017 08:01:08 -0700 Subject: [PATCH 008/125] Context Menu for Footer (#240) r=vladikoff Menu implementation for fixing #208. This commit adds the material-design-lite component library used for creating the menu and it's menu items. --- locales/en-US/notes.properties | 1 + package.json | 1 + scripts/postinstall.js | 5 +++- src/sidebar/dark-svg/three-dots-dark.svg | 14 +++++++++++ src/sidebar/panel.html | 9 ++++++- src/sidebar/panel.js | 12 ++++++--- src/sidebar/styles-dark.css | 27 +++++++++++++++++--- src/sidebar/styles.css | 32 ++++++++++++++++-------- 8 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 src/sidebar/dark-svg/three-dots-dark.svg diff --git a/locales/en-US/notes.properties b/locales/en-US/notes.properties index 3aba2538e..7c1c87cd0 100644 --- a/locales/en-US/notes.properties +++ b/locales/en-US/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Welcome to this one-page notepad built in to Firefox. Browse the we emptyPlaceHolder=Take a note… giveFeedback=Click here to give us some feedback +feedback=Feedback openingLogin=Opening Login… forgetEmail=Forget this Email diff --git a/package.json b/package.json index a96947c32..820556e0a 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "url": "https://github.com/mozilla/notes/issues" }, "dependencies": { + "material-design-lite": "1.3.0", "quill": "1.2.6", "testpilot-ga": "^0.2.1" }, diff --git a/scripts/postinstall.js b/scripts/postinstall.js index 31a080464..bde577758 100755 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -6,7 +6,10 @@ const files = [ copySync('node_modules/testpilot-ga/dist/index.js', 'src/vendor/testpilot-ga.js'), copySync('node_modules/quill/dist/quill.min.js', 'src/sidebar/vendor/quill.js'), copySync('node_modules/quill/dist/quill.snow.css', 'src/sidebar/vendor/quill.snow.css'), - copySync('node_modules/quill/LICENSE', 'src/sidebar/vendor/quill.LICENSE') + copySync('node_modules/quill/LICENSE', 'src/sidebar/vendor/quill.LICENSE'), + copySync('node_modules/material-design-lite/material.min.js', 'src/sidebar/vendor/material.js'), + copySync('node_modules/material-design-lite/material.min.css', 'src/sidebar/vendor/material.css'), + copySync('node_modules/material-design-lite/LICENSE', 'src/sidebar/vendor/material.LICENSE') ]; Promise.all(files).catch(err => { diff --git a/src/sidebar/dark-svg/three-dots-dark.svg b/src/sidebar/dark-svg/three-dots-dark.svg new file mode 100644 index 000000000..95702afd5 --- /dev/null +++ b/src/sidebar/dark-svg/three-dots-dark.svg @@ -0,0 +1,14 @@ + + + + Group + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/sidebar/panel.html b/src/sidebar/panel.html index f33364d9d..0de8aedaf 100644 --- a/src/sidebar/panel.html +++ b/src/sidebar/panel.html @@ -3,6 +3,7 @@ Firefox Notes + @@ -42,7 +43,12 @@ @@ -50,5 +56,6 @@ + diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index e4daa3eff..e34b08584 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -156,14 +156,20 @@ quill.on('text-change', () => { }); const enableSync = document.getElementById('enable-sync'); -const giveFeedback = document.getElementById('give-feedback'); const noteDiv = document.getElementById('sync-note'); const syncNoteBody = document.getElementById('sync-note-dialog'); const closeButton = document.getElementById('close-button'); enableSync.textContent = browser.i18n.getMessage('syncNotes'); syncNoteBody.textContent = browser.i18n.getMessage('syncNotReady2'); -giveFeedback.setAttribute('title', browser.i18n.getMessage('giveFeedback')); -giveFeedback.setAttribute('href', SURVEY_PATH); + +const giveFeedback = document.getElementById('give-feedback'); +giveFeedback.textContent = browser.i18n.getMessage('feedback'); +giveFeedback.addEventListener('click', () => { + browser.tabs.create({ + active: true, + url: SURVEY_PATH + }); +}); closeButton.addEventListener('click', () => { noteDiv.classList.toggle('visible'); diff --git a/src/sidebar/styles-dark.css b/src/sidebar/styles-dark.css index 76cd01de5..abbf440a7 100644 --- a/src/sidebar/styles-dark.css +++ b/src/sidebar/styles-dark.css @@ -10,10 +10,6 @@ div#toolbar { background-image: url('dark-svg/sync-16-dark.svg'); } -#give-feedback { - background-image: url('dark-svg/feedback-dark.svg'); -} - #footer-buttons button, #footer-buttons a { background-color: #272B35; @@ -36,6 +32,29 @@ div#toolbar { color: #fff; } +/* material-design-lite menu */ +.mdl-menu__outline { + background: #272B35; + transition: none; +} + +#context-menu-button { + background-image: url('dark-svg/three-dots-dark.svg'); +} + +.context-menu-item { + color: #e6e6e6; + background-color: #272B35; +} + +.context-menu-item:hover { + background-color: #323744; +} + +.context-menu-item:active { + background-color: #3d4352; +} + /* Overridden Quill classes */ .ql-snow .ql-stroke { stroke: #e6e6e6; diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index 2119d7af9..ff00636f0 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -100,16 +100,6 @@ footer { text-overflow: ellipsis; } -#give-feedback { - background-image: url('feedback.svg'); - background-position: center center; - background-repeat: no-repeat; - background-size: 20px 20px; - border-left: 1px solid #d7d7db; - display: flex; - flex: 0 0 40px; -} - #footer-buttons button, #footer-buttons a { background-color: #f9f9fa; @@ -177,3 +167,25 @@ footer { .forbid-cursor { cursor: no-drop; } + +#context-menu-button { + background-size: 3px; + background-image: url('three-dots.svg'); + background-position: 50%; + background-repeat: no-repeat; + height: 100%; + width: 26px; + text-align: left; +} + +.context-menu { + font-family: inherit; + padding: 0; +} + +.context-menu-item { + font-size: 12px; + padding: 0 0 0 15px; + height: 18px; + line-height: 30px; +} From c511d897588931ad8dd0919de26a1ae34dd66b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Chevalier?= Date: Thu, 21 Sep 2017 15:32:41 +0000 Subject: [PATCH 009/125] Pontoon: Update French (fr) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Théo Chevalier --- locales/fr/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/fr/notes.properties b/locales/fr/notes.properties index e3f01c59a..11bcda01f 100644 --- a/locales/fr/notes.properties +++ b/locales/fr/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Bienvenue sur cet outil de prise de notes simple et intégré à Fi emptyPlaceHolder=Saisissez une note… giveFeedback=Cliquez ici pour nous envoyer vos commentaires +feedback=Votre avis openingLogin=Ouverture de l’écran de connexion… forgetEmail=Oublier cette adresse électronique From c164456f0f9bcfa478a506aa08adbde107f54c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rok=20=C5=BDerdin?= Date: Thu, 21 Sep 2017 15:32:43 +0000 Subject: [PATCH 010/125] Pontoon: Update Slovenian (sl) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Rok Žerdin --- locales/sl/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/sl/notes.properties b/locales/sl/notes.properties index 8d1e6c2f0..8b5dbf69e 100644 --- a/locales/sl/notes.properties +++ b/locales/sl/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Dobrodošli v tej enostranski beležnici vgrajeni v Firefox. Brskaj emptyPlaceHolder=Ustvari zapisek ... giveFeedback=Kliknite tukaj, za povratne informacije +feedback=Povratne informacije openingLogin=Odpiranje prijave ... forgetEmail=Pozabi ta e-poštni naslov From ac8d7558e5883912e2f8a0b81b9362df70938ec6 Mon Sep 17 00:00:00 2001 From: Kohei Yoshino Date: Thu, 21 Sep 2017 15:50:40 +0000 Subject: [PATCH 011/125] Pontoon: Update Japanese (ja) localization of Test Pilot: Notes Localization authors: - Kohei Yoshino --- locales/ja/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/ja/notes.properties b/locales/ja/notes.properties index bdbbefa03..1946ff7f6 100644 --- a/locales/ja/notes.properties +++ b/locales/ja/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Firefox に組み込まれたこの 1 ページメモ帳へよう emptyPlaceHolder=メモを取る... giveFeedback=ここをクリックしてフィードバックをお寄せください +feedback=フィードバック openingLogin=ログイン画面を開いています... forgetEmail=このアドレスを消去 From f03543034b51a205aee6d34b5d1c495a527a5602 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Thu, 21 Sep 2017 17:31:44 +0000 Subject: [PATCH 012/125] Pontoon: Update Sorbian, Upper (hsb) localization of Test Pilot: Notes Localization authors: - Michael Wolf --- locales/hsb/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/hsb/notes.properties b/locales/hsb/notes.properties index f7c848875..e14eaefa5 100644 --- a/locales/hsb/notes.properties +++ b/locales/hsb/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Witajće k tutomu jednostronskemu zapisnikej zatwarjenemu w Firefox emptyPlaceHolder=Čińće noticu… giveFeedback=Klikńće tu, zo byšće nam swoje měnjenje zdźělił +feedback=Komentar openingLogin=Přizjewjenje so wočinja… forgetEmail=Tutu e-mejl zabyć From 581c5441736198778d9fc19a1ff48fb9ad659961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Esteban=20Ajsivinac=20Si=C3=A1n?= Date: Thu, 21 Sep 2017 17:51:10 +0000 Subject: [PATCH 013/125] Pontoon: Update Kaqchikel (cak) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Juan Esteban Ajsivinac Sián --- locales/cak/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/cak/notes.properties b/locales/cak/notes.properties index d6e4c1f72..683bdc523 100644 --- a/locales/cak/notes.properties +++ b/locales/cak/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Ütz apetik pa re tz'ib'awuj re' jun ruxaq tz'aqatisan pa Firefox. emptyPlaceHolder=Titz'ib'äx jun ch'utitzijol… giveFeedback=Tapitz'a' wawe' richin naya' taq ana'oj chi qe +feedback=Ya'oj na'oj openingLogin=Tajin Nijaq Molojri'ïl… forgetEmail=Timestäx re Taqoya'l re' From 245088f6cbc89146d6b4e37374ec08b4e5fbb3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Cig=C3=A1=C5=88?= Date: Thu, 21 Sep 2017 17:51:15 +0000 Subject: [PATCH 014/125] Pontoon: Update Slovak (sk) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Juraj Cigáň --- locales/sk/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/sk/notes.properties b/locales/sk/notes.properties index e9b6d9336..718badd64 100644 --- a/locales/sk/notes.properties +++ b/locales/sk/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Víta vás poznámkový blok zabudovaný priamo vo Firefoxe. Prehli emptyPlaceHolder=Zapíšte si poznámku… giveFeedback=Kliknutím sem nám poskytnete spätnú väzbu +feedback=Spätná väzba openingLogin=Otváranie prihlásenia… forgetEmail=Zabudnúť na túto e-mailovú adresu From 1d2b06039097cae528695135afad1141abebf6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=B6hler?= Date: Thu, 21 Sep 2017 18:11:15 +0000 Subject: [PATCH 015/125] Pontoon: Update German (de) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Michael Köhler --- locales/de/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/de/notes.properties b/locales/de/notes.properties index c31d9de1e..8e1a826a5 100644 --- a/locales/de/notes.properties +++ b/locales/de/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Willkommen bei diesem in Firefox integrierten, einseitigen Notizblo emptyPlaceHolder=Eine Notiz schreiben… giveFeedback=Klicken Sie hier, um uns Ihre Meinung zu sagen +feedback=Feedback openingLogin=Anmeldung wird geöffnet… forgetEmail=E-Mail-Adresse vergessen From 91cfbfc88a1bb05edac99030c73a7a8a2ad7bfed Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Thu, 21 Sep 2017 18:51:31 +0000 Subject: [PATCH 016/125] Pontoon: Update Sorbian, Lower (dsb) localization of Test Pilot: Notes Localization authors: - Michael Wolf --- locales/dsb/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/dsb/notes.properties b/locales/dsb/notes.properties index a4e4981f8..3951b38bd 100644 --- a/locales/dsb/notes.properties +++ b/locales/dsb/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Witajśo k toś tomu jadnobocnemu zapisnikoju zatwarjonemu w Firefo emptyPlaceHolder=Gótujśo noticu… giveFeedback=Klikniśo how, aby nam swójo měnjenje k wěsći dał +feedback=Komentar openingLogin=Pśizjawjenje se wócynja… forgetEmail=Toś tu e-mail zabyś From fe2c83b98b468d71842ff48644da0e4d363092f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Mesk=C3=B3?= Date: Thu, 21 Sep 2017 19:12:24 +0000 Subject: [PATCH 017/125] Pontoon: Update Hungarian (hu) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Balázs Meskó --- locales/hu/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/hu/notes.properties b/locales/hu/notes.properties index 2530e958e..c8bb7cb88 100644 --- a/locales/hu/notes.properties +++ b/locales/hu/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Üdvözöljük ebben a Firefoxba épített egylapos jegyzetfüzetbe emptyPlaceHolder=Készítsen jegyzetet… giveFeedback=Kattintson ide, hogy visszajelzést adjon +feedback=Visszajelzés openingLogin=Bejelentkezés megnyitása… forgetEmail=E-mail cím elfelejtése From c5d72a806785ae2c8fb2e611a36805209d6acbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Selim=20=C5=9Eumlu?= Date: Thu, 21 Sep 2017 20:51:17 +0000 Subject: [PATCH 018/125] Pontoon: Update Turkish (tr) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Selim Şumlu --- locales/tr/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/tr/notes.properties b/locales/tr/notes.properties index ac644bb09..b56a26eee 100644 --- a/locales/tr/notes.properties +++ b/locales/tr/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Firefox ile birlikte gelen tek sayfalık not defterinize hoş geldi emptyPlaceHolder=Not al… giveFeedback=Görüşlerinizi bildirmek için tıklayın +feedback=Geri bildirim openingLogin=Açılıyor… forgetEmail=Bu e-postayı unut From c725254bcc788723268074cff89e19e6f0d126c0 Mon Sep 17 00:00:00 2001 From: manxmensch Date: Thu, 21 Sep 2017 23:51:46 +0000 Subject: [PATCH 019/125] Pontoon: Update Malay (ms) localization of Test Pilot: Notes Localization authors: - manxmensch --- locales/ms/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/ms/notes.properties b/locales/ms/notes.properties index 9ac078b6e..7fd66c0a0 100644 --- a/locales/ms/notes.properties +++ b/locales/ms/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Selamat datang ke pad nota satu-halaman yang terbina dalam Firefox. emptyPlaceHolder=Ambil nota… giveFeedback=Klik di sini untuk berikan kami sebarang maklum balas +feedback=Maklum balas openingLogin=Membuka Log Masuk… forgetEmail=Lupakan E-mel ini From 0b21747e656203da64fbced724005e792d370d82 Mon Sep 17 00:00:00 2001 From: YFdyh000 Date: Fri, 22 Sep 2017 06:31:56 +0000 Subject: [PATCH 020/125] Pontoon: Update Chinese (China) (zh-CN) localization of Test Pilot: Notes Localization authors: - YFdyh000 --- locales/zh-CN/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/zh-CN/notes.properties b/locales/zh-CN/notes.properties index 1dde1430d..2c85fbb56 100644 --- a/locales/zh-CN/notes.properties +++ b/locales/zh-CN/notes.properties @@ -4,6 +4,7 @@ welcomeText2=欢迎使用 Firefox 内置的单页记事本。上网时快捷记 emptyPlaceHolder=写点笔记… giveFeedback=点击这里可以向我们提点意见 +feedback=反馈 openingLogin=正在打开登录页面… forgetEmail=忘记此邮件地址 From 299ee86fcf3992c7ab9e5eb6e49c79c53e3b3038 Mon Sep 17 00:00:00 2001 From: Ton Date: Fri, 22 Sep 2017 09:11:52 +0000 Subject: [PATCH 021/125] Pontoon: Update Dutch (nl) localization of Test Pilot: Notes Localization authors: - Ton --- locales/nl/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/nl/notes.properties b/locales/nl/notes.properties index 4fd204ae1..df43eac1a 100644 --- a/locales/nl/notes.properties +++ b/locales/nl/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Welkom bij dit in Firefox ingebouwde kladblok van 1 pagina. Surf op emptyPlaceHolder=Maak een notitie… giveFeedback=Klik hier om ons feedback te geven +feedback=Feedback openingLogin=Aanmelding openen… forgetEmail=Dit e-mailadres vergeten From 52454a43297731313aac565d86cb7ce58be9aba5 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Fri, 22 Sep 2017 09:31:38 +0000 Subject: [PATCH 022/125] Pontoon: Update Portuguese (Portugal) (pt-PT) localization of Test Pilot: Notes Localization authors: - Rodrigo --- locales/pt-PT/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/pt-PT/notes.properties b/locales/pt-PT/notes.properties index e72e445e2..7a6be4909 100644 --- a/locales/pt-PT/notes.properties +++ b/locales/pt-PT/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Bem-vindo(a) a esta página única de bloco de notas embutida no Fi emptyPlaceHolder=Tomar nota… giveFeedback=Clique aqui para nos dar algum feedback +feedback=Feedback openingLogin=A abrir início de sessão… forgetEmail=Esquecer este email From c4d8e08a68a938d4832c29edbc282abb8bd060b0 Mon Sep 17 00:00:00 2001 From: Pin-guang Chen Date: Fri, 22 Sep 2017 10:12:00 +0000 Subject: [PATCH 023/125] Pontoon: Update Chinese (Taiwan) (zh-TW) localization of Test Pilot: Notes Localization authors: - Pin-guang Chen --- locales/zh-TW/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/zh-TW/notes.properties b/locales/zh-TW/notes.properties index 675105dab..a75136599 100644 --- a/locales/zh-TW/notes.properties +++ b/locales/zh-TW/notes.properties @@ -4,6 +4,7 @@ welcomeText2=歡迎使用這套 Firefox 內建的一頁式記事本。上網時 emptyPlaceHolder=寫點筆記… giveFeedback=點擊此處,提供意見回饋給我們 +feedback=意見回饋 openingLogin=正在開啟登入畫面… forgetEmail=忘記此地址 From c3f0963a7ac7b96b2e17c52908de97957edb3d9f Mon Sep 17 00:00:00 2001 From: ravmn Date: Fri, 22 Sep 2017 20:32:03 +0000 Subject: [PATCH 024/125] Pontoon: Update Spanish (Chile) (es-CL) localization of Test Pilot: Notes Localization authors: - ravmn --- locales/es-CL/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/es-CL/notes.properties b/locales/es-CL/notes.properties index 5e1c85fe7..31ddc5001 100644 --- a/locales/es-CL/notes.properties +++ b/locales/es-CL/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Bienvenido a esta libreta de una sola página integrada a Firefox. emptyPlaceHolder=Tomar una nota… giveFeedback=Haz clic aquí para darnos tu opinión +feedback=Comentarios openingLogin=Abriendo conexión… forgetEmail=Olvidar este correo From 3ef6f5b92b9c5ea7c1fb5f7810c6bd621dd6cfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Andreji=C4=87?= Date: Fri, 22 Sep 2017 22:11:30 +0000 Subject: [PATCH 025/125] Pontoon: Update Serbian (sr) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Marko Andrejić --- locales/sr/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/sr/notes.properties b/locales/sr/notes.properties index 9e57e88a6..6fd1bf69c 100644 --- a/locales/sr/notes.properties +++ b/locales/sr/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Добродошли на једностранични нотес emptyPlaceHolder=Забележи ноту… giveFeedback=Кликните овде за повратну информацију +feedback=Повратна информација openingLogin=Отварам пријављивање… forgetEmail=Заборави ову адресу From 2b590c87348d292ec3bbcf68ce06a9fa1655fbe0 Mon Sep 17 00:00:00 2001 From: Arash Mousavi Date: Sat, 23 Sep 2017 06:31:10 +0000 Subject: [PATCH 026/125] Pontoon: Update Persian (fa) localization of Test Pilot: Notes Localization authors: - Arash Mousavi --- locales/fa/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/fa/notes.properties b/locales/fa/notes.properties index ea17c8726..434e91806 100644 --- a/locales/fa/notes.properties +++ b/locales/fa/notes.properties @@ -4,6 +4,7 @@ welcomeText2=به این دفترچهٔ کوچک تک‌صفحه‌ای در ف emptyPlaceHolder=یک یادداشت بنویسید… giveFeedback=برای ارسال بازخورد اینجا را کلیک کنید +feedback=بازخورد openingLogin=در حال باز کردن صفحه ورود… forgetEmail=این رایانامه را فراموش کن From 77547dfff1133a4c721bbc407341052bd39effe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Henriksen?= Date: Sat, 23 Sep 2017 12:31:14 +0000 Subject: [PATCH 027/125] =?UTF-8?q?Pontoon:=20Update=20Norwegian=20Bokm?= =?UTF-8?q?=C3=A5l=20(nb-NO)=20localization=20of=20Test=20Pilot:=20Notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Håvar Henriksen --- locales/nb-NO/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/nb-NO/notes.properties b/locales/nb-NO/notes.properties index 6364e3a28..2303cd222 100644 --- a/locales/nb-NO/notes.properties +++ b/locales/nb-NO/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Velkommen til denne ensides notisblokken innebygd i Firefox. Surf p emptyPlaceHolder=Skriv et notat… giveFeedback=Klikk her for å gi oss tilbakemelding +feedback=Tilbakemelding openingLogin=Åpner innlogging… forgetEmail=Glem denne e-posten From dd7d03f1d550cea3d846ba48d85d4f917ed29a0d Mon Sep 17 00:00:00 2001 From: Arpit Jaiswal Date: Sat, 23 Sep 2017 17:50:47 +0000 Subject: [PATCH 028/125] Pontoon: Update Hindi (hi-IN) localization of Test Pilot: Notes Localization authors: - Arpit Jaiswal --- locales/hi-IN/notes.properties | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/locales/hi-IN/notes.properties b/locales/hi-IN/notes.properties index 8a313083e..5e0e6b1b4 100644 --- a/locales/hi-IN/notes.properties +++ b/locales/hi-IN/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Firefox में बानेये गाय इस एक पृ emptyPlaceHolder=नोट लें… giveFeedback=हमें कुछ प्रतिक्रिया देने के लिए यहाँ क्लिक करें +feedback=प्रतिपुष्टि openingLogin=लॉगिन खोला जा रहा है… forgetEmail=यह ईमेल भूल जाए @@ -27,3 +28,8 @@ strikethroughTitle=काटना numberedListTitle=क्रमांकित सूची bulletedListTitle=बुलेट सूची textDirectionTitle=पाठ की दिशा + +# Settings page labels +themeLegend=विषयवस्तु +defaultThemeTitle=पूर्वःनिर्धारित +darkThemeTitle=गहरा From fb74808789ee17868d75169e165c1b5bfa08f647 Mon Sep 17 00:00:00 2001 From: Jordi Cuevas Date: Sat, 23 Sep 2017 18:31:18 +0000 Subject: [PATCH 029/125] Pontoon: Update Spanish (Spain) (es-ES) localization of Test Pilot: Notes Localization authors: - Jordi Cuevas --- locales/es-ES/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/es-ES/notes.properties b/locales/es-ES/notes.properties index c4c0c5062..900dbdaa5 100644 --- a/locales/es-ES/notes.properties +++ b/locales/es-ES/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Bienvenido a este bloc de notas integrado en Firefox. Navega por la emptyPlaceHolder=Tomar notas… giveFeedback=Haz clic aquí para darnos tu opinión +feedback=Comentarios openingLogin=Iniciando sesión… forgetEmail=Olvidar este correo electrónico From 7e0d5be7c19d7d7f6761f93a834d9211242ba2d6 Mon Sep 17 00:00:00 2001 From: Francesco Lodolo Date: Sat, 23 Sep 2017 18:51:08 +0000 Subject: [PATCH 030/125] Pontoon: Update Italian (it) localization of Test Pilot: Notes Localization authors: - Francesco Lodolo --- locales/it/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/it/notes.properties b/locales/it/notes.properties index e32cb2536..b5b8f9cb9 100644 --- a/locales/it/notes.properties +++ b/locales/it/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Benvenuto in questo semplice blocco note con una singola pagina, in emptyPlaceHolder=Aggiungi una nota… giveFeedback=Fai clic qui per farci conoscere la tua opinione +feedback=Feedback openingLogin=Apertura pagina di accesso… forgetEmail=Dimentica questa email From 77131461ca3d0fa347b00489ed1c55edde922446 Mon Sep 17 00:00:00 2001 From: "Schieck :)" Date: Sat, 23 Sep 2017 22:50:53 +0000 Subject: [PATCH 031/125] Pontoon: Update Portuguese (Brazil) (pt-BR) localization of Test Pilot: Notes Localization authors: - Schieck :) --- locales/pt-BR/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/pt-BR/notes.properties b/locales/pt-BR/notes.properties index adc1968d8..1139ea226 100644 --- a/locales/pt-BR/notes.properties +++ b/locales/pt-BR/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Bem-vindo a este bloco de notas de uma página integrado ao Firefox emptyPlaceHolder=Escrever uma nota… giveFeedback=Clique aqui para deixar a sua opinião +feedback=Feedback openingLogin=Abrindo conta de acesso… forgetEmail=Esquecer este e-mail From 2454296c3f2c8e8ac562953850238979d4163da7 Mon Sep 17 00:00:00 2001 From: Victor Bychek Date: Sun, 24 Sep 2017 12:11:02 +0000 Subject: [PATCH 032/125] Pontoon: Update Russian (ru) localization of Test Pilot: Notes Localization authors: - Victor Bychek --- locales/ru/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/ru/notes.properties b/locales/ru/notes.properties index fa19c2691..3c4092019 100644 --- a/locales/ru/notes.properties +++ b/locales/ru/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Добро пожаловать в одностраничный б emptyPlaceHolder=Создать заметку… giveFeedback=Щёлкните здесь, чтобы отправить нам отзыв +feedback=Оставить отзыв openingLogin=Открытие аккаунта… forgetEmail=Забыть об этой эл. почте From be2a5071df8a52291224b7a85ee95f2731644574 Mon Sep 17 00:00:00 2001 From: Andreas Pettersson Date: Sun, 24 Sep 2017 12:31:13 +0000 Subject: [PATCH 033/125] Pontoon: Update Swedish (sv-SE) localization of Test Pilot: Notes Localization authors: - Andreas Pettersson --- locales/sv-SE/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/sv-SE/notes.properties b/locales/sv-SE/notes.properties index f626d095c..9c14fff13 100644 --- a/locales/sv-SE/notes.properties +++ b/locales/sv-SE/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Välkommen till den här sidan med ett inbyggt anteckningsblock i F emptyPlaceHolder=Gör en anteckning… giveFeedback=Klicka här för att ge oss lite återkoppling +feedback=Återkoppling openingLogin=Öppnar inloggning… forgetEmail=Glöm den här e-postadressen From 388c618d111bcf7001cd9a2728c27f30618788fd Mon Sep 17 00:00:00 2001 From: Tymur Faradzhev Date: Sun, 24 Sep 2017 13:11:38 +0000 Subject: [PATCH 034/125] Pontoon: Update Ukrainian (uk) localization of Test Pilot: Notes Localization authors: - Tymur Faradzhev --- locales/uk/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/uk/notes.properties b/locales/uk/notes.properties index 7efdbb0b1..0c2fdd1bc 100644 --- a/locales/uk/notes.properties +++ b/locales/uk/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Ласкаво просимо в односторінковий б emptyPlaceHolder=Створіть нотатку… giveFeedback=Натисніть тут, щоб надіслати нам відгук +feedback=Зворотній зв'язок openingLogin=Відкриття входу… forgetEmail=Забути цю адресу електронної пошти From 2e282205d2c676543f7a1248fae208f757952787 Mon Sep 17 00:00:00 2001 From: Marcelo Poli Date: Sun, 24 Sep 2017 19:50:51 +0000 Subject: [PATCH 035/125] Pontoon: Update Spanish (Argentina) (es-AR) localization of Test Pilot: Notes Localization authors: - Marcelo Poli --- locales/es-AR/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/es-AR/notes.properties b/locales/es-AR/notes.properties index 901ed8e04..85a938fab 100644 --- a/locales/es-AR/notes.properties +++ b/locales/es-AR/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Bienvenido a este bloc de notas de una página integrado en Firefox emptyPlaceHolder=Tomar nota… giveFeedback=Clic aquí para darnos tu opinión +feedback=Opinión openingLogin=Abrir ingreso… forgetEmail=Olvidar este correo From 38aaa999c6f3f7d03f4d8acbcad74ae511154a85 Mon Sep 17 00:00:00 2001 From: Cedricium Date: Mon, 25 Sep 2017 06:50:36 -0700 Subject: [PATCH 036/125] Add support for links This is the initial implementation for supporting links (#233). With these changes, links will automatically be created from anything that begins with `http://` or `https://`. That includes any typed or pasted text. The changes in the CSS make it so that the Quill link editing UI tooltip is no longer shown. In order to open a link, the user must mouse over the link and right-click for the context menu or `Ctrl/Cmd + Click` to open in a new tab. --- src/sidebar/panel.js | 37 +++++++++++++++++++++++++++++++++++++ src/sidebar/styles.css | 4 ++++ 2 files changed, 41 insertions(+) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index e34b08584..75f847ec5 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -1,4 +1,5 @@ const formats = [ + 'link', 'bold', 'font', 'italic', @@ -76,6 +77,42 @@ const quill = new Quill('#editor', { formats: formats // enabled formats, see https://github.com/quilljs/quill/issues/1108 }); +function isWhitespace(ch) { + let whiteSpace = false; + if ((ch === ' ') || (ch === '\t') || (ch === '\n')) { + whiteSpace = true; + } + return whiteSpace; +} + +// function used for recognizing typed urls and creating links +quill.on('text-change', function(delta) { + const regex = /https?:\/\/[^\s]+$/; + if (delta.ops.length === 2 && delta.ops[0].retain && isWhitespace(delta.ops[1].insert)) { + const endRetain = delta.ops[0].retain; + const text = quill.getText().substr(0, endRetain); + const match = text.match(regex); + + if (match !== null) { + const url = match[0]; + + let ops = []; + if (endRetain > url.length) { + ops.push({ retain: endRetain - url.length }); + } + + ops = ops.concat([ + { delete: url.length }, + { insert: url, attributes: { link: url } } + ]); + + quill.updateContents({ + ops: ops + }); + } + } +}); + let userOSKey; if (navigator.appVersion.indexOf('Mac') !== -1) diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index ff00636f0..23437c4f9 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -189,3 +189,7 @@ footer { height: 18px; line-height: 30px; } + +.ql-tooltip { + display: none; +} From c495ac4d8014f1b619ea967d19befbfc0fd25a42 Mon Sep 17 00:00:00 2001 From: Fjoerfoks Date: Tue, 26 Sep 2017 09:11:20 +0000 Subject: [PATCH 037/125] Pontoon: Update Frisian (fy-NL) localization of Test Pilot: Notes Localization authors: - Fjoerfoks --- locales/fy-NL/notes.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/fy-NL/notes.properties b/locales/fy-NL/notes.properties index 3091428b4..729752b3c 100644 --- a/locales/fy-NL/notes.properties +++ b/locales/fy-NL/notes.properties @@ -4,6 +4,7 @@ welcomeText2=Wolkom by dit yn Firefox ynboude skrasblok fan 1 side. Surf op it w emptyPlaceHolder=Meitsje in notysje… giveFeedback=Klik hjir om ús kommentaar te jaan +feedback=Kommentaar openingLogin=Oanmelding iepenje… forgetEmail=Ferjit dizze e-mail From 9cda59b70260b0af9e251b5719bf0ae9099d5833 Mon Sep 17 00:00:00 2001 From: Enol Date: Tue, 26 Sep 2017 09:31:07 +0000 Subject: [PATCH 038/125] Pontoon: Update Asturian (ast) localization of Test Pilot: Notes Localization authors: - Enol --- locales/ast/notes.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/locales/ast/notes.properties b/locales/ast/notes.properties index 819ea3aa4..9ac02701e 100644 --- a/locales/ast/notes.properties +++ b/locales/ast/notes.properties @@ -4,8 +4,9 @@ welcomeText2=Afáyate nesti bloc de notes d'una fueya integráu en Firefox. Rest emptyPlaceHolder=Anotar… giveFeedback=Primi equí pa damos daqué de feedback +feedback=Unviar comentarios -openingLogin=Abiendo aniciu de sesión… +openingLogin=Abriendo aniciu de sesión… forgetEmail=Escaecer esti corréu syncNotReady2=Perdón, la sincronización de notes entá nun ta preparada. ¡Cuntaremos el to clic como un votu pa entainar! From 877af94e4abbca9fc05361f3dfc2dc53d03327a8 Mon Sep 17 00:00:00 2001 From: Cedricium Date: Tue, 26 Sep 2017 07:17:25 -0700 Subject: [PATCH 039/125] Fixed errors with initial implementation for links This fixes the two main issues that were happening with the initial implementation of supportng links. The issues fixed are as follows: - links not being clickable: made it so every link within the `
` text field has an event listener for a click event which will open it's `href` in a new tab. Also, those `` elements are given a `cursor: pointer` when being hovered over. - difficult to escape link styling: if the user were to hit [Backspace] to delete a character immediately following a link, then the cursor would be placed at the end of the link. Whatever the user types next will have picked up the `link` format. This is corrected by checking for common characters in sentences such as whitespace and removing the link formatting. Also added in this commit is the link-clicked analytics. --- src/background.js | 3 +++ src/sidebar/panel.js | 23 +++++++++++++++++++++++ src/sidebar/styles.css | 6 ++++++ 3 files changed, 32 insertions(+) diff --git a/src/background.js b/src/background.js index a43a8cc94..eb38e1da5 100644 --- a/src/background.js +++ b/src/background.js @@ -56,6 +56,9 @@ browser.runtime.onMessage.addListener(function(eventData) { action: 'theme-changed' }); break; + case 'link-clicked': + sendMetrics('link-clicked', eventData.content); + break; } }); diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 75f847ec5..da0a48282 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -113,6 +113,29 @@ quill.on('text-change', function(delta) { } }); +document.querySelector('#editor').addEventListener('click', function(e) { + const anchor = e.target; + if (anchor !== null && anchor.tagName === 'A') { + browser.runtime.sendMessage({ + action: 'link-clicked', + context: getPadStats() + }); + browser.tabs.create({ + active: true, + url: anchor.href + }); + } +}); + +quill.on('text-change', function(delta) { + if ('insert' in delta.ops[1] && isWhitespace(delta.ops[1].insert)) { + const format = quill.getFormat(delta.ops[0].retain, 1); + + if ('link' in format) + quill.formatText(delta.ops[0].retain, 1, 'link', false); + } +}); + let userOSKey; if (navigator.appVersion.indexOf('Mac') !== -1) diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index 23437c4f9..92aa6e8f5 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -35,6 +35,10 @@ div#editor { overflow: hidden; } +div#editor a { + cursor: pointer; +} + .ql-snow .ql-picker.ql-size { width: 45px; } @@ -193,3 +197,5 @@ footer { .ql-tooltip { display: none; } + + From ed4f94c73b46806b4c69cd61053fe20382454848 Mon Sep 17 00:00:00 2001 From: Cedricium Date: Tue, 26 Sep 2017 07:17:25 -0700 Subject: [PATCH 040/125] Fixed errors with initial implementation for links This fixes the two main issues that were happening with the initial implementation of supportng links. The issues fixed are as follows: - links not being clickable: made it so every link within the `
` text field has an event listener for a click event which will open it's `href` in a new tab. Also, those `` elements are given a `cursor: pointer` when being hovered over. - difficult to escape link styling: if the user were to hit [Backspace] to delete a character immediately following a link, then the cursor would be placed at the end of the link. Whatever the user types next will have picked up the `link` format. This is corrected by checking for common characters in sentences such as whitespace and removing the link formatting. Also added in this commit is the link-clicked analytics. --- src/background.js | 3 +++ src/sidebar/panel.js | 23 +++++++++++++++++++++++ src/sidebar/styles.css | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/src/background.js b/src/background.js index a43a8cc94..eb38e1da5 100644 --- a/src/background.js +++ b/src/background.js @@ -56,6 +56,9 @@ browser.runtime.onMessage.addListener(function(eventData) { action: 'theme-changed' }); break; + case 'link-clicked': + sendMetrics('link-clicked', eventData.content); + break; } }); diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 75f847ec5..da0a48282 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -113,6 +113,29 @@ quill.on('text-change', function(delta) { } }); +document.querySelector('#editor').addEventListener('click', function(e) { + const anchor = e.target; + if (anchor !== null && anchor.tagName === 'A') { + browser.runtime.sendMessage({ + action: 'link-clicked', + context: getPadStats() + }); + browser.tabs.create({ + active: true, + url: anchor.href + }); + } +}); + +quill.on('text-change', function(delta) { + if ('insert' in delta.ops[1] && isWhitespace(delta.ops[1].insert)) { + const format = quill.getFormat(delta.ops[0].retain, 1); + + if ('link' in format) + quill.formatText(delta.ops[0].retain, 1, 'link', false); + } +}); + let userOSKey; if (navigator.appVersion.indexOf('Mac') !== -1) diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index 23437c4f9..97bac808d 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -35,6 +35,10 @@ div#editor { overflow: hidden; } +div#editor a { + cursor: pointer; +} + .ql-snow .ql-picker.ql-size { width: 45px; } From a3c83e34d9ff81ef26822b6e01331347b267b45e Mon Sep 17 00:00:00 2001 From: Cedricium Date: Tue, 26 Sep 2017 07:40:07 -0700 Subject: [PATCH 041/125] Removed extra newlines from `styles.css` --- src/sidebar/styles.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index 97bac808d..507e82ddc 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -120,7 +120,6 @@ footer { background-color: #d7d7db; } - #menu { position: absolute; bottom: 10px; From 195f40946e8c44ab0c44295bd3622c8c05e80071 Mon Sep 17 00:00:00 2001 From: Cedric Amaya Date: Tue, 26 Sep 2017 07:42:36 -0700 Subject: [PATCH 042/125] Removed extra newlines in `styles.css` --- src/sidebar/styles.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index 92aa6e8f5..97bac808d 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -197,5 +197,3 @@ footer { .ql-tooltip { display: none; } - - From e7ac2571e56869ead5df4024941485a9f5d77a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 26 Sep 2017 16:48:35 +0200 Subject: [PATCH 043/125] Add a saving status indicator (#245) r=vladikoff Fixes #208 #234 --- locales/en-US/notes.properties | 4 +- package.json | 1 - scripts/postinstall.js | 5 +-- src/sidebar/dark-svg/three-dots-dark.svg | 14 ------- src/sidebar/panel.html | 12 ++---- src/sidebar/panel.js | 29 +++++++++----- src/sidebar/styles-dark.css | 27 ++----------- src/sidebar/styles.css | 50 +++++++++++------------- 8 files changed, 54 insertions(+), 88 deletions(-) delete mode 100644 src/sidebar/dark-svg/three-dots-dark.svg diff --git a/locales/en-US/notes.properties b/locales/en-US/notes.properties index 7c1c87cd0..97cccf3ad 100644 --- a/locales/en-US/notes.properties +++ b/locales/en-US/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Welcome to this one-page notepad built in to Firefox. Browse the we emptyPlaceHolder=Take a note… giveFeedback=Click here to give us some feedback -feedback=Feedback openingLogin=Opening Login… forgetEmail=Forget this Email +savingChanges=Saving changes… +changesSaved=All changes saved + syncNotReady2=Sorry, syncing notes isn’t quite ready. We will count your click as a vote to hurry it up! syncNotes=Sync Your Notes syncProgress=Syncing Changes… diff --git a/package.json b/package.json index 820556e0a..a96947c32 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "url": "https://github.com/mozilla/notes/issues" }, "dependencies": { - "material-design-lite": "1.3.0", "quill": "1.2.6", "testpilot-ga": "^0.2.1" }, diff --git a/scripts/postinstall.js b/scripts/postinstall.js index bde577758..31a080464 100755 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -6,10 +6,7 @@ const files = [ copySync('node_modules/testpilot-ga/dist/index.js', 'src/vendor/testpilot-ga.js'), copySync('node_modules/quill/dist/quill.min.js', 'src/sidebar/vendor/quill.js'), copySync('node_modules/quill/dist/quill.snow.css', 'src/sidebar/vendor/quill.snow.css'), - copySync('node_modules/quill/LICENSE', 'src/sidebar/vendor/quill.LICENSE'), - copySync('node_modules/material-design-lite/material.min.js', 'src/sidebar/vendor/material.js'), - copySync('node_modules/material-design-lite/material.min.css', 'src/sidebar/vendor/material.css'), - copySync('node_modules/material-design-lite/LICENSE', 'src/sidebar/vendor/material.LICENSE') + copySync('node_modules/quill/LICENSE', 'src/sidebar/vendor/quill.LICENSE') ]; Promise.all(files).catch(err => { diff --git a/src/sidebar/dark-svg/three-dots-dark.svg b/src/sidebar/dark-svg/three-dots-dark.svg deleted file mode 100644 index 95702afd5..000000000 --- a/src/sidebar/dark-svg/three-dots-dark.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - Group - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/sidebar/panel.html b/src/sidebar/panel.html index 0de8aedaf..9e6c48420 100644 --- a/src/sidebar/panel.html +++ b/src/sidebar/panel.html @@ -3,7 +3,6 @@ Firefox Notes - @@ -42,13 +41,9 @@
@@ -56,6 +51,5 @@ - diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index e34b08584..31edecb78 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -144,6 +144,8 @@ quill.on('text-change', () => { chrome.runtime.sendMessage('notes@mozilla.com', { action: 'text-change' }); + + updateSavingIndicator(); // Debounce this second event chrome.runtime.sendMessage({ action: 'metrics-changed', @@ -155,21 +157,30 @@ quill.on('text-change', () => { }); }); +const savingIndicator = document.getElementById('saving-indicator'); const enableSync = document.getElementById('enable-sync'); +const giveFeedback = document.getElementById('give-feedback'); const noteDiv = document.getElementById('sync-note'); const syncNoteBody = document.getElementById('sync-note-dialog'); const closeButton = document.getElementById('close-button'); -enableSync.textContent = browser.i18n.getMessage('syncNotes'); +savingIndicator.textContent = browser.i18n.getMessage('changesSaved'); +enableSync.setAttribute('title', browser.i18n.getMessage('syncNotes')); syncNoteBody.textContent = browser.i18n.getMessage('syncNotReady2'); +giveFeedback.setAttribute('title', browser.i18n.getMessage('giveFeedback')); +giveFeedback.setAttribute('href', SURVEY_PATH); + + +let savingIndicatorTimeout; +function updateSavingIndicator() { + savingIndicator.textContent = browser.i18n.getMessage('savingChanges'); + const later = function() { + savingIndicatorTimeout = null; + savingIndicator.textContent = browser.i18n.getMessage('changesSaved'); + }; + clearTimeout(savingIndicatorTimeout); + savingIndicatorTimeout = setTimeout(later, 300); +} -const giveFeedback = document.getElementById('give-feedback'); -giveFeedback.textContent = browser.i18n.getMessage('feedback'); -giveFeedback.addEventListener('click', () => { - browser.tabs.create({ - active: true, - url: SURVEY_PATH - }); -}); closeButton.addEventListener('click', () => { noteDiv.classList.toggle('visible'); diff --git a/src/sidebar/styles-dark.css b/src/sidebar/styles-dark.css index abbf440a7..76cd01de5 100644 --- a/src/sidebar/styles-dark.css +++ b/src/sidebar/styles-dark.css @@ -10,6 +10,10 @@ div#toolbar { background-image: url('dark-svg/sync-16-dark.svg'); } +#give-feedback { + background-image: url('dark-svg/feedback-dark.svg'); +} + #footer-buttons button, #footer-buttons a { background-color: #272B35; @@ -32,29 +36,6 @@ div#toolbar { color: #fff; } -/* material-design-lite menu */ -.mdl-menu__outline { - background: #272B35; - transition: none; -} - -#context-menu-button { - background-image: url('dark-svg/three-dots-dark.svg'); -} - -.context-menu-item { - color: #e6e6e6; - background-color: #272B35; -} - -.context-menu-item:hover { - background-color: #323744; -} - -.context-menu-item:active { - background-color: #3d4352; -} - /* Overridden Quill classes */ .ql-snow .ql-stroke { stroke: #e6e6e6; diff --git a/src/sidebar/styles.css b/src/sidebar/styles.css index ff00636f0..97fd7538d 100644 --- a/src/sidebar/styles.css +++ b/src/sidebar/styles.css @@ -86,13 +86,11 @@ footer { height: 40px; } -#enable-sync { - background-image: url('sync-16-inactive.svg'); - background-position: 10px 12px; - background-repeat: no-repeat; +#saving-indicator { display: flex; flex: 1 0; - padding: 0 10px 0 32px; + padding: 10px; + color: #969696; text-align: left; display: block; overflow: hidden; @@ -100,6 +98,26 @@ footer { text-overflow: ellipsis; } +#enable-sync { + background-image: url('sync-16-inactive.svg'); + background-position: center center; + background-repeat: no-repeat; + background-size: 20px 20px; + border-left: 1px solid #d7d7db; + display: flex; + flex: 0 0 40px; +} + +#give-feedback { + background-image: url('feedback.svg'); + background-position: center center; + background-repeat: no-repeat; + background-size: 20px 20px; + border-left: 1px solid #d7d7db; + display: flex; + flex: 0 0 40px; +} + #footer-buttons button, #footer-buttons a { background-color: #f9f9fa; @@ -167,25 +185,3 @@ footer { .forbid-cursor { cursor: no-drop; } - -#context-menu-button { - background-size: 3px; - background-image: url('three-dots.svg'); - background-position: 50%; - background-repeat: no-repeat; - height: 100%; - width: 26px; - text-align: left; -} - -.context-menu { - font-family: inherit; - padding: 0; -} - -.context-menu-item { - font-size: 12px; - padding: 0 0 0 15px; - height: 18px; - line-height: 30px; -} From 6d527b8872443861834bb6a2d6a68c4ed932cff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 26 Sep 2017 16:57:50 +0200 Subject: [PATCH 044/125] Add @ryanfeeley SVG icon. (#224) r=ryanfeeley,vladikoff Fixes #217 --- src/icons/notes-48.png | Bin 611 -> 0 bytes src/icons/notes-96.png | Bin 988 -> 0 bytes src/icons/notes.svg | 17 +++++++++++++++++ src/manifest.json | 6 +----- 4 files changed, 18 insertions(+), 5 deletions(-) delete mode 100644 src/icons/notes-48.png delete mode 100644 src/icons/notes-96.png create mode 100644 src/icons/notes.svg diff --git a/src/icons/notes-48.png b/src/icons/notes-48.png deleted file mode 100644 index 1192bdbfe9304558bc2d9aebab3a6536ff0aa8e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 611 zcmV-p0-XJcP)Ax11zH7(MzT5yg}*^a zBosoku?mrkV3+I_SK&xxa_8Qe**UXw<2=bJW-@u-=Q;D9=X_BdTW|%h@CgsG-^OqN zkMKFfy&UpH!432??E~g3#@mDU17co}L4E>j1CsS|wPMU`Iq_CQzQV+^n8j%v#8h}U zhv}RcXR)t>fTKC@XK)wa!t)P2$5IeC6bpEh(=(ghUSsbl0ry)<{%>2#67FQ4yV#|@ z=wkOU0e$U9C+qEFjU*rm_}>Lgl=yZHPtc3VXDg0`*|-w&CXilOS~P(}AzvPsN&=P} zu8ifn1^mMChRB}?`3earI}@*9JtFySVL@4VCQeIWIaFG>MK)X<3l000McNliru;R6;A8wK$mXgmM_18GS_ zK~#9!?VU?&Q$ZMppQLK5h}BIkRs-S{yl%vewqO_HLR?w@fC?g|y6_jc5X9=*f8eFK zQ4mA~t6LW$MMZ^L>BS1tZW5!UagoWcO-^RcB{O{=m{n8q&HJA7eP_Ni=LC}H3@`@F z0A*krcnqATeefa1me~kA0jdqgnE9MyjF~mS%O(@6j~C|iiZMp6N1RxF3@gU?$N@iE zoZOW8KgAdWhgzIieH>VgG1}y{wLlNhxx(L%S;lf4D5YdT5;2y6dEj4CLH7gCOaN7l zWk(5k3Y>^j_&hKwaa$g@jdsr5l9<-xrmOgefr^B*9u?qdv-Hx4;kZttRZ1SX;$py{ zG<0UL*@C1IWni5&bfOG&*&0xlezC2*tx}Lkp-2cBAOnO9kO4vl$N(V&WPp$XGC-t6 zlADb_Q@cO<6@Qz0IbaWP7TB9b0Je969?+l#>mgmhLkB%lHDCeg4lrAE1B-DRkVFl5 zX95k4MKiayFT$Gwu9>Ny**2%!U((%Xm=*`k+}gedRDqAwwzP!85#Uo2ML5ZO!b>LT z8PCPv2JClC*SRbV5D|3NN?5H386aeU3=kQSR5!E=+^6=i^Q7k*?F5E^OJwknp6$Y8 zB*2698lH4RrvgoFd0Kz8HIr`WgjofL#*&#^+ZW+o0oTmb=VqJph5{7-f-g0o3KW4G zKp_C(3uZ1wJnM#v2s&#arj@V^5Hdgph>S@3J!nN>&U1}=fel%Gx$SlDEVccV9RVDq z9l$wrAbGJ6s{khh%ohFFzd0sV1KtOmvOnNKH*_vw17>}w0rRZ) zykj#WIp7|iHRE0ZkAQEUi@zH<51eu|Fm(e&1f8`KRx3gV2pJ#)L`Edp4gC#_n}wOr z^Z*0EmMp&9cH!~b1Re@o&78dGh8BUo0JFt*?6;<*YQUR-Q}$at=!WJ3Ho%MR=}JLu z& + + + +universal-notepad-large +Created with Sketch. + + + + diff --git a/src/manifest.json b/src/manifest.json index 871f16821..a5e13400d 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -11,12 +11,8 @@ "update_url": "https://testpilot.firefox.com/files/notes@mozilla.com/updates.json" } }, - "icons": { - "48": "icons/notes-48.png", - "96": "icons/notes-96.png" - }, "sidebar_action": { - "default_icon": "icons/notes-48.png", + "default_icon": "icons/notes.svg", "default_title" : "Notes", "default_panel": "sidebar/panel.html" }, From c288c2aa1e60b0b421badcc06082f2b1cb5e489c Mon Sep 17 00:00:00 2001 From: Lan Glad Date: Tue, 26 Sep 2017 15:11:43 +0000 Subject: [PATCH 045/125] Pontoon: Update Slovenian (sl) localization of Test Pilot: Notes Localization authors: - Lan Glad --- locales/sl/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/sl/notes.properties b/locales/sl/notes.properties index 8b5dbf69e..96bcaefa1 100644 --- a/locales/sl/notes.properties +++ b/locales/sl/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Dobrodošli v tej enostranski beležnici vgrajeni v Firefox. Brskaj emptyPlaceHolder=Ustvari zapisek ... giveFeedback=Kliknite tukaj, za povratne informacije -feedback=Povratne informacije openingLogin=Odpiranje prijave ... forgetEmail=Pozabi ta e-poštni naslov +savingChanges=Shranjevanje sprememb … +changesSaved=Spremembe so bile shranjene + syncNotReady2=Oprostite, sinhronizacija zapiskov še ni pripravljena. Vaš klik bomo šteli kot glas, naj pohitimo! syncNotes=Sinhronizirajte svoje zapiske syncProgress=Sinhroniziranje sprememb ... From 89d6880636b8291cc4ca438a6983a4f0f392fd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Chevalier?= Date: Tue, 26 Sep 2017 15:31:57 +0000 Subject: [PATCH 046/125] Pontoon: Update French (fr) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Théo Chevalier --- locales/fr/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/fr/notes.properties b/locales/fr/notes.properties index 11bcda01f..8c44b4402 100644 --- a/locales/fr/notes.properties +++ b/locales/fr/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Bienvenue sur cet outil de prise de notes simple et intégré à Fi emptyPlaceHolder=Saisissez une note… giveFeedback=Cliquez ici pour nous envoyer vos commentaires -feedback=Votre avis openingLogin=Ouverture de l’écran de connexion… forgetEmail=Oublier cette adresse électronique +savingChanges=Enregistrement des changements… +changesSaved=Tous les changements ont été enregistrés + syncNotReady2=Désolé, la synchronisation n’est pas encore disponible. Nous comptabilisons votre clic comme un vote pour l’implémenter d’autant plus vite ! syncNotes=Synchroniser vos notes syncProgress=Synchronisation… From 9fb0341bc64f2756755154373b13fa3b7ac5baa2 Mon Sep 17 00:00:00 2001 From: albertdcastro Date: Tue, 26 Sep 2017 15:32:01 +0000 Subject: [PATCH 047/125] Pontoon: Update Portuguese (Portugal) (pt-PT) localization of Test Pilot: Notes Localization authors: - albertdcastro --- locales/pt-PT/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/pt-PT/notes.properties b/locales/pt-PT/notes.properties index 7a6be4909..e7d2b206a 100644 --- a/locales/pt-PT/notes.properties +++ b/locales/pt-PT/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Bem-vindo(a) a esta página única de bloco de notas embutida no Fi emptyPlaceHolder=Tomar nota… giveFeedback=Clique aqui para nos dar algum feedback -feedback=Feedback openingLogin=A abrir início de sessão… forgetEmail=Esquecer este email +savingChanges=A guardar as alterações… +changesSaved=Todas as alterações foram guardadas + syncNotReady2=Desculpe, sincronizar notas ainda não está pronto. Iremos contar o seu clique como um vote para despachar! syncNotes=Sincronizar as suas notas syncProgress=A sincronizar alterações… From 90303a6c160da6b26f405b8d471c3b66901a7c86 Mon Sep 17 00:00:00 2001 From: Ton Date: Tue, 26 Sep 2017 15:51:17 +0000 Subject: [PATCH 048/125] Pontoon: Update Dutch (nl) localization of Test Pilot: Notes Localization authors: - Ton --- locales/nl/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/nl/notes.properties b/locales/nl/notes.properties index df43eac1a..e4f3e6818 100644 --- a/locales/nl/notes.properties +++ b/locales/nl/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Welkom bij dit in Firefox ingebouwde kladblok van 1 pagina. Surf op emptyPlaceHolder=Maak een notitie… giveFeedback=Klik hier om ons feedback te geven -feedback=Feedback openingLogin=Aanmelding openen… forgetEmail=Dit e-mailadres vergeten +savingChanges=Wijzigingen opslaan… +changesSaved=Alle wijzigingen zijn opgeslagen + syncNotReady2=Sorry, synchronisatie van notities is nog niet helemaal gereed. We rekenen uw klik mee als een stem om dit te versnellen! syncNotes=Uw notities synchroniseren syncProgress=Wijzigingen synchroniseren… From 68a62be149c2299c9ebbbe56f80f9c8370621199 Mon Sep 17 00:00:00 2001 From: avelper Date: Tue, 26 Sep 2017 15:51:20 +0000 Subject: [PATCH 049/125] Pontoon: Update Spanish (Spain) (es-ES) localization of Test Pilot: Notes Localization authors: - avelper --- locales/es-ES/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/es-ES/notes.properties b/locales/es-ES/notes.properties index 900dbdaa5..15c4dad9e 100644 --- a/locales/es-ES/notes.properties +++ b/locales/es-ES/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Bienvenido a este bloc de notas integrado en Firefox. Navega por la emptyPlaceHolder=Tomar notas… giveFeedback=Haz clic aquí para darnos tu opinión -feedback=Comentarios openingLogin=Iniciando sesión… forgetEmail=Olvidar este correo electrónico +savingChanges=Guardando cambios… +changesSaved=Todos los cambios guardados + syncNotReady2=Lo sentimos, la sincronización de notas aún no está lista. ¡Nos damos por aludidos para darnos prisa! syncNotes=Sincronizar tus notas syncProgress=Sincronizando los cambios… From a191b6e328543e525ec07a3561aed5c33c31f977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=B6hler?= Date: Tue, 26 Sep 2017 16:12:25 +0000 Subject: [PATCH 050/125] Pontoon: Update German (de) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Michael Köhler --- locales/de/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/de/notes.properties b/locales/de/notes.properties index 8e1a826a5..4ae3c6fa3 100644 --- a/locales/de/notes.properties +++ b/locales/de/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Willkommen bei diesem in Firefox integrierten, einseitigen Notizblo emptyPlaceHolder=Eine Notiz schreiben… giveFeedback=Klicken Sie hier, um uns Ihre Meinung zu sagen -feedback=Feedback openingLogin=Anmeldung wird geöffnet… forgetEmail=E-Mail-Adresse vergessen +savingChanges=Änderungen werden gespeichert… +changesSaved=Alle Änderungen gespeichert + syncNotReady2=Die Synchronisation von Notizen ist leider noch nicht bereit, aber Ihr Klick ermutigt uns, uns zu beeilen! syncNotes=Synchronisieren Sie Ihre Notizen syncProgress=Änderungen werden synchronisiert… From fefc9e1ccc8da7a510cdaca36289163d9c3b1bf0 Mon Sep 17 00:00:00 2001 From: Victor Bychek Date: Tue, 26 Sep 2017 16:12:29 +0000 Subject: [PATCH 051/125] Pontoon: Update Russian (ru) localization of Test Pilot: Notes Localization authors: - Victor Bychek --- locales/ru/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/ru/notes.properties b/locales/ru/notes.properties index 3c4092019..3c081bd4b 100644 --- a/locales/ru/notes.properties +++ b/locales/ru/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Добро пожаловать в одностраничный б emptyPlaceHolder=Создать заметку… giveFeedback=Щёлкните здесь, чтобы отправить нам отзыв -feedback=Оставить отзыв openingLogin=Открытие аккаунта… forgetEmail=Забыть об этой эл. почте +savingChanges=Сохранение изменений… +changesSaved=Все изменения сохранены + syncNotReady2=Извините, синхронизация заметок пока недоступна. Мы будем считать ваши нажатия как голоса за то, чтобы поторопить нас! syncNotes=Синхронизировать ваши заметки syncProgress=Синхронизация изменений… From 8e540b998e9e7b7e828dc3fd98e0125894ab679e Mon Sep 17 00:00:00 2001 From: Andreas Pettersson Date: Tue, 26 Sep 2017 16:31:17 +0000 Subject: [PATCH 052/125] Pontoon: Update Swedish (sv-SE) localization of Test Pilot: Notes Localization authors: - Andreas Pettersson --- locales/sv-SE/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/sv-SE/notes.properties b/locales/sv-SE/notes.properties index 9c14fff13..fc2401b77 100644 --- a/locales/sv-SE/notes.properties +++ b/locales/sv-SE/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Välkommen till den här sidan med ett inbyggt anteckningsblock i F emptyPlaceHolder=Gör en anteckning… giveFeedback=Klicka här för att ge oss lite återkoppling -feedback=Återkoppling openingLogin=Öppnar inloggning… forgetEmail=Glöm den här e-postadressen +savingChanges=Sparar ändringar… +changesSaved=Alla ändringar sparade + syncNotReady2=Tyvärr, synkroniserade anteckningar är inte helt redo. Vi räknar ditt klick som en röst för att snabba på utvecklingen! syncNotes=Synkronisera dina anteckningar syncProgress=Synkroniserar ändringar… From 2c57cfd31f43855df9f296c10d1c45e3dc4a0123 Mon Sep 17 00:00:00 2001 From: Luiz Carlos de Morais Date: Tue, 26 Sep 2017 16:51:48 +0000 Subject: [PATCH 053/125] Pontoon: Update Portuguese (Brazil) (pt-BR) localization of Test Pilot: Notes Localization authors: - Luiz Carlos de Morais --- locales/pt-BR/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/pt-BR/notes.properties b/locales/pt-BR/notes.properties index 1139ea226..f9f102d4b 100644 --- a/locales/pt-BR/notes.properties +++ b/locales/pt-BR/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Bem-vindo a este bloco de notas de uma página integrado ao Firefox emptyPlaceHolder=Escrever uma nota… giveFeedback=Clique aqui para deixar a sua opinião -feedback=Feedback openingLogin=Abrindo conta de acesso… forgetEmail=Esquecer este e-mail +savingChanges=Salvando alterações… +changesSaved=Todas as alterações salvas + syncNotReady2=Desculpe, a sincronização de notas ainda não está pronta. Nós contaremos seu clique como um voto para que nos apressemos! syncNotes=Sincronize suas notas syncProgress=Sincronizando alterações… From bf41369bfc63181ccee5874fffc308fdc64e90f0 Mon Sep 17 00:00:00 2001 From: Pin-guang Chen Date: Tue, 26 Sep 2017 17:10:59 +0000 Subject: [PATCH 054/125] Pontoon: Update Chinese (Taiwan) (zh-TW) localization of Test Pilot: Notes Localization authors: - Pin-guang Chen --- locales/zh-TW/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/zh-TW/notes.properties b/locales/zh-TW/notes.properties index a75136599..5629be623 100644 --- a/locales/zh-TW/notes.properties +++ b/locales/zh-TW/notes.properties @@ -4,11 +4,13 @@ welcomeText2=歡迎使用這套 Firefox 內建的一頁式記事本。上網時 emptyPlaceHolder=寫點筆記… giveFeedback=點擊此處,提供意見回饋給我們 -feedback=意見回饋 openingLogin=正在開啟登入畫面… forgetEmail=忘記此地址 +savingChanges=正在儲存修改… +changesSaved=已儲存所有修改 + syncNotReady2=很抱歉,筆記同步功能還沒開發完成。我們將把您的點擊次數記錄下來,當作投票來加速我們的開發! syncNotes=同步您的筆記 syncProgress=正在同步變更… From e39b44577980f3ec936ae7a5902e2622fbad9590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Mesk=C3=B3?= Date: Tue, 26 Sep 2017 17:32:16 +0000 Subject: [PATCH 055/125] Pontoon: Update Hungarian (hu) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Balázs Meskó --- locales/hu/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/hu/notes.properties b/locales/hu/notes.properties index c8bb7cb88..6be8e879c 100644 --- a/locales/hu/notes.properties +++ b/locales/hu/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Üdvözöljük ebben a Firefoxba épített egylapos jegyzetfüzetbe emptyPlaceHolder=Készítsen jegyzetet… giveFeedback=Kattintson ide, hogy visszajelzést adjon -feedback=Visszajelzés openingLogin=Bejelentkezés megnyitása… forgetEmail=E-mail cím elfelejtése +savingChanges=Változások mentése… +changesSaved=Minden változás mentve + syncNotReady2=Sajnáljuk, a jegyzetek szinkronizálása még nem áll készen. De ha kattintgat, akkor gyorsabban kész lesz! syncNotes=Jegyzetek szinkronizálása syncProgress=Módosítások szinkronizálása… From 4e7c99d5ff7ff5f81bb3ae8dff63e62efa5e6943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Cig=C3=A1=C5=88?= Date: Tue, 26 Sep 2017 17:51:50 +0000 Subject: [PATCH 056/125] Pontoon: Update Slovak (sk) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Juraj Cigáň --- locales/sk/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/sk/notes.properties b/locales/sk/notes.properties index 718badd64..2ae871409 100644 --- a/locales/sk/notes.properties +++ b/locales/sk/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Víta vás poznámkový blok zabudovaný priamo vo Firefoxe. Prehli emptyPlaceHolder=Zapíšte si poznámku… giveFeedback=Kliknutím sem nám poskytnete spätnú väzbu -feedback=Spätná väzba openingLogin=Otváranie prihlásenia… forgetEmail=Zabudnúť na túto e-mailovú adresu +savingChanges=Ukladanie zmien… +changesSaved=Všetky zmeny boli uložené + syncNotReady2=Ospravedlňujeme sa, no synchronizácia ešte nie je pripravená. Vaše kliknutie však berieme ako prejav toho, že o funkciu je záujem. syncNotes=Synchronizovať poznámky syncProgress=Synchronizácia zmien… From 0c121192f5c3d9c1c9878a04458b61d27977da2e Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Tue, 26 Sep 2017 18:31:29 +0000 Subject: [PATCH 057/125] Pontoon: Update Sorbian, Lower (dsb) localization of Test Pilot: Notes Localization authors: - Michael Wolf --- locales/dsb/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/dsb/notes.properties b/locales/dsb/notes.properties index 3951b38bd..92c4b8364 100644 --- a/locales/dsb/notes.properties +++ b/locales/dsb/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Witajśo k toś tomu jadnobocnemu zapisnikoju zatwarjonemu w Firefo emptyPlaceHolder=Gótujśo noticu… giveFeedback=Klikniśo how, aby nam swójo měnjenje k wěsći dał -feedback=Komentar openingLogin=Pśizjawjenje se wócynja… forgetEmail=Toś tu e-mail zabyś +savingChanges=Změny se składuju… +changesSaved=Wšykne změny skłaźone + syncNotReady2=Synchronizacija noticow bóžko hyšći njejo gótowa. Ale wašo kliknjenje nas pózbuźujo chwataś! syncNotes=Waše notice synchronizěrowaś syncProgress=Změny se synchronizěruju… From 44d06434e1a163a382d92670034e1c17f7df6648 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Tue, 26 Sep 2017 18:31:33 +0000 Subject: [PATCH 058/125] Pontoon: Update Sorbian, Upper (hsb) localization of Test Pilot: Notes Localization authors: - Michael Wolf --- locales/hsb/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/hsb/notes.properties b/locales/hsb/notes.properties index e14eaefa5..9f1bd300b 100644 --- a/locales/hsb/notes.properties +++ b/locales/hsb/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Witajće k tutomu jednostronskemu zapisnikej zatwarjenemu w Firefox emptyPlaceHolder=Čińće noticu… giveFeedback=Klikńće tu, zo byšće nam swoje měnjenje zdźělił -feedback=Komentar openingLogin=Přizjewjenje so wočinja… forgetEmail=Tutu e-mejl zabyć +savingChanges=Změny so składuja… +changesSaved=Wšě změny składowane + syncNotReady2=Synchronizacija noticow bohužel hišće hotowa njeje. Ale waše kliknjenje nas pozbudźuje chwatać! syncNotes=Waše noticy synchronizować syncProgress=Změny so synchronizuja… From 6380591f19fcd6fb3a787007e257efff53d62a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Va=C5=A1=C3=AD=C4=8Dek?= Date: Tue, 26 Sep 2017 19:11:20 +0000 Subject: [PATCH 059/125] Pontoon: Update Czech (cs) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Michal Vašíček --- locales/cs/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/cs/notes.properties b/locales/cs/notes.properties index 6f90ffc10..0dd0d6366 100644 --- a/locales/cs/notes.properties +++ b/locales/cs/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Kliknutím sem nám poskytnete zpětnou vazbu openingLogin=Otevírání přihlášení… forgetEmail=Zapomenout tento e-mail +savingChanges=Ukládání změn… +changesSaved=Všechny změny uloženy + syncNotReady2=Omlouváme se, ale funkce synchronizace poznámek zatím není připravena. Vaše kliknutí však bereme jako hlas pro zrychlení! syncNotes=Synchronizovat poznámky syncProgress=Synchronizace změn… From 0b880455bc30c5e586494727f08215740e6731b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Esteban=20Ajsivinac=20Si=C3=A1n?= Date: Tue, 26 Sep 2017 20:12:18 +0000 Subject: [PATCH 060/125] Pontoon: Update Kaqchikel (cak) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Juan Esteban Ajsivinac Sián --- locales/cak/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/cak/notes.properties b/locales/cak/notes.properties index 683bdc523..dfeed660f 100644 --- a/locales/cak/notes.properties +++ b/locales/cak/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Ütz apetik pa re tz'ib'awuj re' jun ruxaq tz'aqatisan pa Firefox. emptyPlaceHolder=Titz'ib'äx jun ch'utitzijol… giveFeedback=Tapitz'a' wawe' richin naya' taq ana'oj chi qe -feedback=Ya'oj na'oj openingLogin=Tajin Nijaq Molojri'ïl… forgetEmail=Timestäx re Taqoya'l re' +savingChanges=Tajin yexim ri taq jaloj… +changesSaved=Ronojel ri taq jaloj xeyak + syncNotReady2=Takuyu', k'a man tikirel ta yexim taq ch'utitzijol. ¡Xkeqajilaj ri taq pitzoj richin niqaxïk' qi'! syncNotes=Ke'axima' ri taq Ach'utitzijol syncProgress=Tajin Yexim ri Taq Jaloj… From 39a07bb9acad582db71e6d920cbe70f371984b15 Mon Sep 17 00:00:00 2001 From: Kohei Yoshino Date: Tue, 26 Sep 2017 20:31:50 +0000 Subject: [PATCH 061/125] Pontoon: Update Japanese (ja) localization of Test Pilot: Notes Localization authors: - Kohei Yoshino --- locales/ja/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/ja/notes.properties b/locales/ja/notes.properties index 1946ff7f6..12d8aa147 100644 --- a/locales/ja/notes.properties +++ b/locales/ja/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Firefox に組み込まれたこの 1 ページメモ帳へよう emptyPlaceHolder=メモを取る... giveFeedback=ここをクリックしてフィードバックをお寄せください -feedback=フィードバック openingLogin=ログイン画面を開いています... forgetEmail=このアドレスを消去 +savingChanges=変更を保存しています... +changesSaved=すべての変更が保存されました。 + syncNotReady2=申し訳ありませんが、メモの同期はまだ開発中です。あなたのクリックを投票として数え、完成を急ぎます! syncNotes=メモを同期 syncProgress=変更内容を同期しています... From c444502c5bdeaa4d1c310f5284910d46b2e05119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Andreji=C4=87?= Date: Tue, 26 Sep 2017 21:30:50 +0000 Subject: [PATCH 062/125] Pontoon: Update Serbian (sr) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Marko Andrejić --- locales/sr/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/sr/notes.properties b/locales/sr/notes.properties index 6fd1bf69c..8e678bee2 100644 --- a/locales/sr/notes.properties +++ b/locales/sr/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Добродошли на једностранични нотес emptyPlaceHolder=Забележи ноту… giveFeedback=Кликните овде за повратну информацију -feedback=Повратна информација openingLogin=Отварам пријављивање… forgetEmail=Заборави ову адресу +savingChanges=Памтим измене… +changesSaved=Све измене запамћене + syncNotReady2=Жао нам је, синронизација белешки није још увек спремна. Бројаћемо ваше кликове као гласове да је убрзамо! syncNotes=Синхронизујте ваше ноте syncProgress=Синхронизујем измене… From 48dd52321bb663c46d376f80031aee281cf77338 Mon Sep 17 00:00:00 2001 From: ravmn Date: Tue, 26 Sep 2017 22:31:09 +0000 Subject: [PATCH 063/125] Pontoon: Update Spanish (Chile) (es-CL) localization of Test Pilot: Notes Localization authors: - ravmn --- locales/es-CL/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/es-CL/notes.properties b/locales/es-CL/notes.properties index 31ddc5001..bcc26d9c2 100644 --- a/locales/es-CL/notes.properties +++ b/locales/es-CL/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Bienvenido a esta libreta de una sola página integrada a Firefox. emptyPlaceHolder=Tomar una nota… giveFeedback=Haz clic aquí para darnos tu opinión -feedback=Comentarios openingLogin=Abriendo conexión… forgetEmail=Olvidar este correo +savingChanges=Guardando cambios… +changesSaved=Todos los cambios guardados + syncNotReady2=Lo sentimos, la sincronización de notas aún no está lista. ¡Consideraremos tu clic como motivación para darnos prisa! syncNotes=Sincroniza tus notas syncProgress=Sincronizando cambios… From d3057d48681947747f91f018753f2fbdc171c919 Mon Sep 17 00:00:00 2001 From: manxmensch Date: Wed, 27 Sep 2017 00:12:12 +0000 Subject: [PATCH 064/125] Pontoon: Update Malay (ms) localization of Test Pilot: Notes Localization authors: - manxmensch --- locales/ms/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/ms/notes.properties b/locales/ms/notes.properties index 7fd66c0a0..cc6e3067e 100644 --- a/locales/ms/notes.properties +++ b/locales/ms/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Selamat datang ke pad nota satu-halaman yang terbina dalam Firefox. emptyPlaceHolder=Ambil nota… giveFeedback=Klik di sini untuk berikan kami sebarang maklum balas -feedback=Maklum balas openingLogin=Membuka Log Masuk… forgetEmail=Lupakan E-mel ini +savingChanges=Menyimpan perubahan… +changesSaved=Semua perubahan sudah disimpan + syncNotReady2=Maaf, sync nota masih belum tersedia. Kami akan mengira bilangan klik anda sebagai undian untuk menyediakannya secepat yang mungkin! syncNotes=Sync Notes Anda syncProgress=Sedang Sync Perubahan… From 5dbf7b5f59caa19c463963d8514e7693ea9b0e02 Mon Sep 17 00:00:00 2001 From: YFdyh000 Date: Wed, 27 Sep 2017 00:50:45 +0000 Subject: [PATCH 065/125] Pontoon: Update Chinese (China) (zh-CN) localization of Test Pilot: Notes Localization authors: - YFdyh000 --- locales/zh-CN/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/zh-CN/notes.properties b/locales/zh-CN/notes.properties index 2c85fbb56..6e793a4c0 100644 --- a/locales/zh-CN/notes.properties +++ b/locales/zh-CN/notes.properties @@ -4,11 +4,13 @@ welcomeText2=欢迎使用 Firefox 内置的单页记事本。上网时快捷记 emptyPlaceHolder=写点笔记… giveFeedback=点击这里可以向我们提点意见 -feedback=反馈 openingLogin=正在打开登录页面… forgetEmail=忘记此邮件地址 +savingChanges=保存更改… +changesSaved=已保存所有更改 + syncNotReady2=很抱歉,笔记同步功能还没开发完成。我们将把您的点击次数记录下来,当作投票来加速我们的开发! syncNotes=同步您的便签 syncProgress=正在同步更改… From 9626db7751e739029f24a077889ed5b8e59e67b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Wed, 27 Sep 2017 10:38:47 +0200 Subject: [PATCH 066/125] Handle links modifications. --- src/sidebar/panel.js | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 6eb99ddb4..75bcf2f32 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -85,31 +85,47 @@ function isWhitespace(ch) { return whiteSpace; } +let ignoreNextTextChange = false; +let debounceLinksTimeout; // function used for recognizing typed urls and creating links quill.on('text-change', function(delta) { - const regex = /https?:\/\/[^\s]+$/; - if (delta.ops.length === 2 && delta.ops[0].retain && isWhitespace(delta.ops[1].insert)) { - const endRetain = delta.ops[0].retain; - const text = quill.getText().substr(0, endRetain); - const match = text.match(regex); - - if (match !== null) { - const url = match[0]; - - let ops = []; - if (endRetain > url.length) { - ops.push({ retain: endRetain - url.length }); + const later = function() { + debounceLinksTimeout = null; + const regex = /https?:\/\/[^\s]+$/; + if (delta.ops.length === 2 && delta.ops[0].retain ) { + let endRetain = delta.ops[0].retain; + if (delta.ops[1].hasOwnProperty('insert')) { + endRetain += 1; } + const text = quill.getText().substr(0, endRetain); + const match = text.match(regex); - ops = ops.concat([ - { delete: url.length }, - { insert: url, attributes: { link: url } } - ]); + if (match !== null) { + const url = match[0]; - quill.updateContents({ - ops: ops - }); + let ops = []; + if (endRetain > url.length) { + ops.push({ retain: endRetain - url.length }); + } + + ops = ops.concat([ + { delete: url.length }, + { insert: url, attributes: { link: url } } + ]); + + ignoreNextTextChange = true; + quill.updateContents({ + ops: ops + }); + } } + }; + + if(!ignoreNextTextChange) { + clearTimeout(debounceLinksTimeout); + debounceLinksTimeout = setTimeout(later, 500); + } else { + ignoreNextTextChange = false; } }); From 23c310a81fc219313cb3b7cee5bb17cc3bb249e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Selim=20=C5=9Eumlu?= Date: Wed, 27 Sep 2017 10:11:14 +0000 Subject: [PATCH 067/125] Pontoon: Update Turkish (tr) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Selim Şumlu --- locales/tr/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/tr/notes.properties b/locales/tr/notes.properties index b56a26eee..5c7598ff5 100644 --- a/locales/tr/notes.properties +++ b/locales/tr/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Firefox ile birlikte gelen tek sayfalık not defterinize hoş geldi emptyPlaceHolder=Not al… giveFeedback=Görüşlerinizi bildirmek için tıklayın -feedback=Geri bildirim openingLogin=Açılıyor… forgetEmail=Bu e-postayı unut +savingChanges=Değişiklikler kaydediliyor… +changesSaved=Tüm değişiklikler kaydedildi + syncNotReady2=Maalesef notları eşitleme özelliği henüz hazır değil. Bu tıklamanızı istek parça olarak kabul ettik. syncNotes=Notlarımı eşitle syncProgress=Değişiklikler eşitleniyor… From 50947f902f51f304874513752d82478318d1517b Mon Sep 17 00:00:00 2001 From: Francesco Lodolo Date: Wed, 27 Sep 2017 12:11:16 +0000 Subject: [PATCH 068/125] Pontoon: Update Italian (it) localization of Test Pilot: Notes Localization authors: - Francesco Lodolo --- locales/it/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/it/notes.properties b/locales/it/notes.properties index b5b8f9cb9..b60b8387d 100644 --- a/locales/it/notes.properties +++ b/locales/it/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Benvenuto in questo semplice blocco note con una singola pagina, in emptyPlaceHolder=Aggiungi una nota… giveFeedback=Fai clic qui per farci conoscere la tua opinione -feedback=Feedback openingLogin=Apertura pagina di accesso… forgetEmail=Dimentica questa email +savingChanges=Salvataggio modifiche… +changesSaved=Modifiche salvate + syncNotReady2=Siamo spiacenti, Sync non è ancora supportato, ma consideriamo il tuo clic un incentivo a renderlo disponibile quanto prima. syncNotes=Sincronizza le tue note syncProgress=Sincronizzazione modifiche… From b0b51402b4474d22858580e0ec65d5d12306bac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Wed, 27 Sep 2017 16:40:09 +0200 Subject: [PATCH 069/125] Cleaning space on empty lines. (#248) --- LICENSE | 2 +- src/settings/settings.html | 8 ++++---- src/settings/settings.js | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/LICENSE b/LICENSE index 14e2f777f..a612ad981 100644 --- a/LICENSE +++ b/LICENSE @@ -35,7 +35,7 @@ Mozilla Public License Version 2.0 means any form of the work other than Source Code Form. 1.7. "Larger Work" - means a work that combines Covered Software with other material, in + means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" diff --git a/src/settings/settings.html b/src/settings/settings.html index e51d34865..c379a096e 100644 --- a/src/settings/settings.html +++ b/src/settings/settings.html @@ -5,9 +5,9 @@ - + - +
@@ -19,8 +19,8 @@
- + - + diff --git a/src/settings/settings.js b/src/settings/settings.js index 301252e69..676d4595a 100644 --- a/src/settings/settings.js +++ b/src/settings/settings.js @@ -11,7 +11,7 @@ const themeRadioBtn = document.getElementsByName('theme'); function loadSavedData(data) { const theme = data.theme; - + if (theme === 'default') themeRadioBtn[0].checked = true; else if (theme === 'dark') @@ -25,25 +25,25 @@ document.addEventListener('DOMContentLoaded', function() { function getTheme() { let theme = ''; - + for (let i = 0; i < themeRadioBtn.length; i++) { if (themeRadioBtn[i].checked) theme = themeRadioBtn[i].value; else continue; } - + const selectedTheme = { theme: theme }; - + return selectedTheme; } for (let i = 0; i < themeRadioBtn.length; i++) { themeRadioBtn[i].onclick = function() { const theme = getTheme(); - + browser.storage.local.set(theme); // notify background.js that theme settings have changed From 17395b70cd9b4db77d28b7ab72cae7397b7e0bb8 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Wed, 27 Sep 2017 18:12:07 +0000 Subject: [PATCH 070/125] Pontoon: Update Hebrew (he) localization of Test Pilot: Notes Localization authors: - ItielMaN - Yaron Shahrabani --- locales/he/notes.properties | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 locales/he/notes.properties diff --git a/locales/he/notes.properties b/locales/he/notes.properties new file mode 100644 index 000000000..5dc3289d3 --- /dev/null +++ b/locales/he/notes.properties @@ -0,0 +1,37 @@ +welcomeTitle2=שלום! +welcomeText2=ברוכים הבאים לפנקס בעל העמוד הבודד שנבנה לתוך Firefox. מהיום אפשר לגלוש באינטרנט. לכתוב הערות בצד. בפשטות וביעילות. + +emptyPlaceHolder=כתיבת פתקית… + +giveFeedback=יש ללחוץ כאן כדי לשלוח לנו משוב + +openingLogin=מסך הכניסה נפתח… +forgetEmail=לשכוח מכתובת דוא״ל זו + +savingChanges=השינויים נשמרים… +changesSaved=כל השינויים נשמרו + +syncNotReady2=סנכרון פתקיות אינו אפשרי עדיין, עמך הסליחה. עם זאת, אנו נספור את הלחיצה שלך כהצבעה לאפשרות שכזאת כדי להאיץ את הפיתוח! +syncNotes=סנכרון הפתקיות שלך +syncProgress=השינויים מסונכרנים… +# LOCALIZATION NOTE (disableSync): Sync is intended as a generic +# synchronization, not Firefox Sync. +disableSync=נטרול הסנכרון +# LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this +# structure doesn't work for your locale, you can translate this as "Last sync: +# {date}". +syncComplete=הסנכרון האחרון: {date} + +# Tooltips for toolbar buttons +fontSizeTitle=גודל הגופן +boldTitle=מודגש +italicTitle=נטוי +strikethroughTitle=קו חוצה +numberedListTitle=רשימה ממוספרת +bulletedListTitle=רשימת תבליטים +textDirectionTitle=כיוון הטקסט + +# Settings page labels +themeLegend=ערכת נושא +defaultThemeTitle=ברירת מחדל +darkThemeTitle=כהה From b26320714848c21f2ffe1c15f3ddbbec85fdc1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5var=20Henriksen?= Date: Thu, 28 Sep 2017 11:50:49 +0000 Subject: [PATCH 071/125] =?UTF-8?q?Pontoon:=20Update=20Norwegian=20Bokm?= =?UTF-8?q?=C3=A5l=20(nb-NO)=20localization=20of=20Test=20Pilot:=20Notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Håvar Henriksen --- locales/nb-NO/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/nb-NO/notes.properties b/locales/nb-NO/notes.properties index 2303cd222..b40d15741 100644 --- a/locales/nb-NO/notes.properties +++ b/locales/nb-NO/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Velkommen til denne ensides notisblokken innebygd i Firefox. Surf p emptyPlaceHolder=Skriv et notat… giveFeedback=Klikk her for å gi oss tilbakemelding -feedback=Tilbakemelding openingLogin=Åpner innlogging… forgetEmail=Glem denne e-posten +savingChanges=Lagre endringer… +changesSaved=Alle endringer lagret + syncNotReady2=Dessverre, synkroniserte notater er ikke helt klare. Vi regner ditt klikk som en avstemming for å henge i! syncNotes=Synkroniser notatene dine syncProgress=Synkroniserer endringer… From 5de977b329ee50a24ea5fb9e2a5f4e34e1ede28d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Thu, 28 Sep 2017 17:24:32 +0200 Subject: [PATCH 072/125] Add back the icons in the about:addons page. (#251) r=vladikoff * Add back the icons in the about:addons page. * Having a SVG doesn't seems to fix the issue. --- src/icons/notes-48.png | Bin 0 -> 469 bytes src/icons/notes-96.png | Bin 0 -> 845 bytes src/manifest.json | 4 ++++ 3 files changed, 4 insertions(+) create mode 100644 src/icons/notes-48.png create mode 100644 src/icons/notes-96.png diff --git a/src/icons/notes-48.png b/src/icons/notes-48.png new file mode 100644 index 0000000000000000000000000000000000000000..b66ee11f014bd0bbbc941f7ac5c6f1e294006381 GIT binary patch literal 469 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmSQK*5Dp-y;YjHK@;M7UB8wRq zbi6^BajEUJl|Vts64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<_&gFIav zLoyoQ&b0MAVj$2OFEH)S1y;RB)=PTC-fhqkV&$#oaq(nMkC){cs9E}W{&$nd>fVej4^=kZU`>sTvv@v_VGV;o!`y3C(VMMcnXx+c1Rj+nD2YkLVh8?Guyp-#}g_Y8Y@(P zOt}zcZ}ptxfa$*aZG|5^U98{#o%XWk;s4L9^NaS`IjEj@21Wscr>mdKI;Vst0IuD$ AZ2$lO literal 0 HcmV?d00001 diff --git a/src/icons/notes-96.png b/src/icons/notes-96.png new file mode 100644 index 0000000000000000000000000000000000000000..61e836b4d295d34ed7fa97d5f3ac423f5bdbfc67 GIT binary patch literal 845 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEX7WqAsj$Z!;#Vf4nJ zL`(%?#+$k3mw|$kC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)lo$_>X z45^s&_O4-`u%iguga2>!c!h*mCy2E?>EaHEj@x-qN&Nwb!c&Qb9I_l-ehh&cYhr&g z$TTno&S*QO*JzSqD`Lo`B5Wgk{?G24|Fze~p8x!B%$! z!gIc7-hBJ@@H~SbgUr>^y&j?7vtM}%9jLI`_kNCb;kmm%jw_zNnq@lkY})(ZVg6qj z+73UA3lxz*SGjS&4&$BfztgX8tJ*ZfpO4}7_MiXbbQtcKY(8GQTD^*aK`y6yL2=&e zWc>x9Uzcz^=sUi#d~xW<=+&<{_p#@^P+IqH&8j?$qkOxTEnwL8Lg|;8suvozv0hcGenOvlQq) zi@L~cu(^5Fs<>lu>C>;-ui7Kg>t?X|x#9J$e}Yp|Zx+5WP15Xoxz~3uqxqGp#|QTnzcct2bx)o@HFB3k zYm8WFY;|mKEkE2zKzE*PGP|JD;j?+cG%%$A6!0+Ner0gB$;u7k5fkoP4x2%8QBGj$ zgbBCOMV%Fgfhr{sKE14y!F;v}D3`?vrj#!0bhvC@z;{_^MKVfIpo9-M=Yx{xp)qpz zYy3Gl6XXi~;(=i~f#DwOoXg_(uB)juD9`zO+34qOrSqTD_o-L12VDP}v^C0ifxy2l z3 Date: Thu, 28 Sep 2017 16:11:08 +0000 Subject: [PATCH 073/125] Pontoon: Update Spanish (Mexico) (es-MX) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Lucio Chávez --- locales/es-MX/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/es-MX/notes.properties b/locales/es-MX/notes.properties index 8533590a0..41f1eda8e 100644 --- a/locales/es-MX/notes.properties +++ b/locales/es-MX/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Haz clic aquí para hacernos algunos comentarios openingLogin=Iniciando sesión… forgetEmail=Dejar de recordar este correo electrónico +savingChanges=Guardando cambios… +changesSaved=Todos los cambios guardados + syncNotReady2=Lo sentimos, la sincronización de notas aún no está lista. ¡Contamos tus clics para darnos prisa! syncNotes=Sincronizar tus notas syncProgress=Sincronizando cambios… From d529740ee5f3c896d5f831794858ca1c4c0a7f51 Mon Sep 17 00:00:00 2001 From: deimidis Date: Fri, 29 Sep 2017 02:31:30 +0000 Subject: [PATCH 074/125] Pontoon: Update Spanish (Argentina) (es-AR) localization of Test Pilot: Notes Localization authors: - deimidis --- locales/es-AR/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/es-AR/notes.properties b/locales/es-AR/notes.properties index 85a938fab..3992bd2e6 100644 --- a/locales/es-AR/notes.properties +++ b/locales/es-AR/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Bienvenido a este bloc de notas de una página integrado en Firefox emptyPlaceHolder=Tomar nota… giveFeedback=Clic aquí para darnos tu opinión -feedback=Opinión openingLogin=Abrir ingreso… forgetEmail=Olvidar este correo +savingChanges=Guardando cambios… +changesSaved=Se guardaron todos los cambios + syncNotReady2=Lo sentimos, sincronizar notas todavía no está listo. ¡Contaremos el clic como un voto para que nos apuremos! syncNotes=Sincronizar notas syncProgress=Sincronizando cambios… From de7075621a05c31063a99f66f21acafc22e41aa6 Mon Sep 17 00:00:00 2001 From: Cedricium Date: Fri, 29 Sep 2017 06:14:06 -0700 Subject: [PATCH 075/125] Bug fixes for #252, #254, and #255 The issue #252 is resolved by adding a function that adds a matcher to the clipboard which looks for urls. When pasted, the urls are immediately resolved as links. Issues #254 and #255 have been resolved by adding a simple `else` statement to the function that looks out for the `insert` in the quill Delta. In addition to the `else` statement, the original `if` statement has been made more specific to match only when the `Delta.ops` length is equal to two (2). --- src/sidebar/panel.js | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index da0a48282..0d89c5d40 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -85,7 +85,7 @@ function isWhitespace(ch) { return whiteSpace; } -// function used for recognizing typed urls and creating links +// recognizes typed urls and create links from those urls quill.on('text-change', function(delta) { const regex = /https?:\/\/[^\s]+$/; if (delta.ops.length === 2 && delta.ops[0].retain && isWhitespace(delta.ops[1].insert)) { @@ -113,6 +113,34 @@ quill.on('text-change', function(delta) { } }); +// recognizes pasted urls and create links from those urls +quill.clipboard.addMatcher(Node.TEXT_NODE, function(node, delta) { + const regex = /https?:\/\/[^\s]+/; + if (typeof(node.data) !== 'string') + return; + const matches = node.data.match(regex); + + if (matches && matches.length > 0) { + const ops = []; + let str = node.data; + + matches.forEach(function(match) { + const split = str.split(match); + const beforeLink = split.shift(); + ops.push({ insert: beforeLink }); + ops.push({ insert: match, attributes: { link: match } }); + str = split.join(match); + }); + + ops.push({ insert: str }); + delta.ops = ops; + } + + return delta; +}); + +// adds an eventListener to every element which opens their respective +// href link in a new tab when clicked document.querySelector('#editor').addEventListener('click', function(e) { const anchor = e.target; if (anchor !== null && anchor.tagName === 'A') { @@ -127,13 +155,15 @@ document.querySelector('#editor').addEventListener('click', function(e) { } }); +// makes getting out of link-editing format easier by escaping whitespace characters quill.on('text-change', function(delta) { - if ('insert' in delta.ops[1] && isWhitespace(delta.ops[1].insert)) { + if (delta.ops.length === 2 && 'insert' in delta.ops[1] && + isWhitespace(delta.ops[1].insert)) { const format = quill.getFormat(delta.ops[0].retain, 1); - if ('link' in format) quill.formatText(delta.ops[0].retain, 1, 'link', false); - } + } else + return; }); let userOSKey; From 663c6a60df137f88caea1f682c5a20f83253d9b0 Mon Sep 17 00:00:00 2001 From: Fjoerfoks Date: Fri, 29 Sep 2017 14:51:16 +0000 Subject: [PATCH 076/125] Pontoon: Update Frisian (fy-NL) localization of Test Pilot: Notes Localization authors: - Fjoerfoks --- locales/fy-NL/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/fy-NL/notes.properties b/locales/fy-NL/notes.properties index 729752b3c..394bc4597 100644 --- a/locales/fy-NL/notes.properties +++ b/locales/fy-NL/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Wolkom by dit yn Firefox ynboude skrasblok fan 1 side. Surf op it w emptyPlaceHolder=Meitsje in notysje… giveFeedback=Klik hjir om ús kommentaar te jaan -feedback=Kommentaar openingLogin=Oanmelding iepenje… forgetEmail=Ferjit dizze e-mail +savingChanges=Wizigingen bewarje… +changesSaved=Alle wizigingen binne bewarre + syncNotReady2=Sorry, syngronisaasje fan notysjes is noch net hielendal ree. Wy rekkenje jo klik mei as in stim om dit te flugger op te pakken! syncNotes=Jo notysjes syngronisearje syncProgress=Wizigingen syngronisearje… From 0b48948c42f255a55e891b565c1eb67558c310e9 Mon Sep 17 00:00:00 2001 From: tmm88 Date: Fri, 8 Sep 2017 15:11:55 +0100 Subject: [PATCH 077/125] improving rethorics in README.md **this PR does basically aim at:** - *improving rethorics in README.md file* --- **the basic goal behind that is to basically:** - **make file reading ux better** --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5b5087d8b..3cebc9bd8 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,14 @@ [![CircleCI](https://circleci.com/gh/mozilla/notes/tree/master.svg?style=svg)](https://circleci.com/gh/mozilla/notes/tree/master) [![Available on Test Pilot](https://img.shields.io/badge/available_on-Test_Pilot-0996F8.svg)](https://testpilot.firefox.com/experiments/notes) -## What it does +## What does it aim for -Open a notepad in the Firefox toolbar to store notes about your browsing. +This project does basically aim at opening a notepad in the Firefox toolbar to store notes about your browsing. -## How to use it +## How can you use it Step 0: If you plan on sending pull-request, you should fork the repository. - Step 1: Clone the [notes](https://github.com/mozilla/notes) repository or your fork. ``` git clone https://github.com/mozilla/notes.git From 7075284d902059e3af9920748fee4a080351ea03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 29 Sep 2017 17:39:15 +0200 Subject: [PATCH 078/125] @vladikoff review. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3cebc9bd8..2616d15e3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## What does it aim for -This project does basically aim at opening a notepad in the Firefox toolbar to store notes about your browsing. +This project let you open a notepad in the Firefox toolbar to store notes about your browsing. ## How can you use it From 26539adfdedf6651ff9491da67b325dcdfd8c562 Mon Sep 17 00:00:00 2001 From: Jim Spentzos Date: Sat, 30 Sep 2017 15:51:12 +0000 Subject: [PATCH 079/125] Pontoon: Update Greek (el) localization of Test Pilot: Notes Localization authors: - Jim Spentzos --- locales/el/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/el/notes.properties b/locales/el/notes.properties index 84a6dfd8c..f8ae2b25c 100644 --- a/locales/el/notes.properties +++ b/locales/el/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Κάντε κλικ εδώ για να μάς στείλετε λί openingLogin=Άνοιγμα σύνδεσης… forgetEmail=Διαγραφή αυτού του e-mail +savingChanges=Αποθήκευση αλλαγών… +changesSaved=Αποθηκεύτηκαν όλες οι αλλαγές + syncNotReady2=Λυπούμαστε, ο συγχρονισμός σημειώσεων δεν είναι έτοιμος ακόμα. Θα μετρήσουμε το κλικ σας ως ψήφο για να βιαστούμε! syncNotes=Συγχρονισμός σημειώσεων syncProgress=Αλλαγές συγχρονισμού… From 388e3221392b497f2ed46ffc11c7a942b69d145c Mon Sep 17 00:00:00 2001 From: Benny Chandra Date: Sat, 30 Sep 2017 16:51:46 +0000 Subject: [PATCH 080/125] Pontoon: Update Indonesian (id) localization of Test Pilot: Notes Localization authors: - Benny Chandra - eljuno --- locales/id/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/id/notes.properties b/locales/id/notes.properties index 8c7bdefbd..1f93f6274 100644 --- a/locales/id/notes.properties +++ b/locales/id/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Klik di sini untuk memberikan saran kepada kami openingLogin=Membuka Log-masuk… forgetEmail=Lupakan Surel ini +savingChanges=Menyimpan perubahan… +changesSaved=Semua perubahan tersimpan + syncNotReady2=Maaf, sinkronisasi catatan belum siap. Kami akan menghitung klik Anda sebagai satu suara untuk mempercepat! syncNotes=Sinkronkan Catatan Anda syncProgress=Mensinkronisasi Pengubahan… From e2d9adf5cf53ae14b5e9a9ba3508107f1192c426 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Tue, 19 Sep 2017 15:42:53 -0400 Subject: [PATCH 081/125] Rewrite sync logic to use Kinto This commit shifts the source of truth to be the Kinto collection, which at present only has a single record (the singleNote record). Locally, this record should have a content field which stores the quill content, as well as an id and a last_modified. This record is transformed by the remote transformer, which encrypts the whole record, which is stored under the "content" field of the remote record. A vague attempt at backwards compatibility is made, where we recognize old-style encrypted records, which are just the "content" field encrypted, and not a whole Kinto record, and when we recognize them, we "decode" them as complete Kinto records. Although the source of truth is now the Kinto collection, no effort whatsoever was made to update the rest of this project, which still relies on storing last_modified and notes in browser.local. The contentWasSynced field wasn't rethought in any way, and neither was the syncing strategy (sync on startup and every time the user changes the text). The syncing logic was adapted from ExtensionStorageSync.jsm in the mozilla-central tree. There are lots of edge cases that remain to be covered, especially centering around merge conflicts. No effort was made to test the cases where we get 401s or key conflicts, although the code seems sane. --- src/background.js | 4 +- src/sync.js | 279 ++++++++++++++++++++++++++++------------------ 2 files changed, 174 insertions(+), 109 deletions(-) diff --git a/src/background.js b/src/background.js index 415ba70b3..8d5c9c2b0 100644 --- a/src/background.js +++ b/src/background.js @@ -12,7 +12,7 @@ const timeouts = {}; // Kinto sync and encryption -const client = new KintoClient(KINTO_SERVER); +const client = new Kinto({remote: KINTO_SERVER, bucket: "default"}); // Analytics @@ -94,7 +94,7 @@ browser.runtime.onMessage.addListener(function(eventData) { loadFromKinto(client); break; case 'kinto-save': - saveToKinto(client); + saveToKinto(client, eventData.content); break; case 'metrics-changed': sendMetrics('changed', eventData.context); diff --git a/src/sync.js b/src/sync.js index b6da66ae1..8101fdc61 100644 --- a/src/sync.js +++ b/src/sync.js @@ -30,72 +30,165 @@ function decrypt(key, encrypted) { }); } +// An "id schema" used to validate Kinto IDs and generate new ones. +const notesIdSchema = { + // FIXME: Maybe this should generate IDs? + generate() { + throw new Error("cannot generate IDs"); + }, -function loadFromKinto(client) { + validate(id) { + // FIXME: verify that at least this matches Kinto server ID format + return true; + }, +}; + +class ServerKeyNewerError extends Error { + constructor() { + super("key used to encrypt the record appears to be newer than our key"); + } +} + +class ServerKeyOlderError extends Error { + constructor() { + super("key used to encrypt the record appears to be older than our key"); + } +} + +class JWETransformer { + constructor(key) { + this.key = key; + } + + async encode(record) { + // FIXME: should we try to obfuscate the record ID? + const ciphertext = await encrypt(this.key, record); + // Copy over the _status field, so that we handle concurrency + // headers (If-Match, If-None-Match) correctly. + // DON'T copy over "deleted" status, because then we'd leak + // plaintext deletes. + const status = record._status && (record._status == "deleted" ? "updated" : record._status); + const encryptedResult = { + content: ciphertext, + id: record.id, + _status: status, + kid: this.key.kid, + }; + if (record.hasOwnProperty("last_modified")) { + encryptedResult.last_modified = record.last_modified; + } + + return encryptedResult; + } + + async decode(record) { + if (!record.content) { + // This can happen for tombstones if a record is deleted. + if (record.deleted) { + return record; + } + throw new Error("No ciphertext: nothing to decrypt?"); + } + + if (record.kid !== this.key.kid) { + if (this.key.kid < record.kid) { + throw new ServerKeyNewerError(); + } else { + throw new ServerKeyOlderError(); + } + } + + // FIXME: Make sure this is backwards compatible?? + let decoded = await decrypt(this.key, record.content); + if (!decoded.hasOwnProperty('id')) { + // Old-style encrypted notes aren't true Kinto records -- + // they're just the content field. + decoded = { + content: decoded, + id: 'singleNote', + } + } + if (record.hasOwnProperty("last_modified")) { + decoded.last_modified = record.last_modified; + } + + // _status: deleted records were deleted on a client, but + // uploaded as an encrypted blob so we don't leak deletions. + // If we get such a record, flag it as deleted. + if (decoded._status == "deleted") { + decoded.deleted = true; + } + + return decoded; + } +} + +function syncKinto(client) { // Get credentials and lastmodified - browser.storage.local.get(['credentials', 'contentWasSynced', 'last_modified']) + return browser.storage.local.get(['credentials', 'contentWasSynced', 'last_modified']) .then((data) => { // XXX: Ask for an refresh token // Query Kinto with the Bearer Token if (!data.hasOwnProperty('credentials')) return; - - client - .bucket('default') - .collection('notes') - .getRecord('singleNote', { - headers: { Authorization: `Bearer ${data.credentials.access_token}` } - }) - .then(result => { - if (!data.hasOwnProperty('last_modified') || - result.data.last_modified > data.last_modified) { - // If there is something in Kinto send unencrypted content to the sidebar - return decrypt(data.credentials.key, result['data']['content']) - .then(content => { - browser.runtime.sendMessage({ - action: 'kinto-loaded', - data: content, - contentWasSynced: data.contentWasSynced, - last_modified: result.data.last_modified - }); - }) - .catch(() => { - // In case we cannot decrypt the message - if (data.credentials.key.kid < result.data.kid) { - // If the key date is greater than current one, log the user out. - return browser.storage.local.remove('credentials'); - } else { - // If the key date is older than the current one, we can't help - // because there is no way we get the previous key. - // Flush the server ALA sync - return client - .bucket('default') - .collection('notes') - .deleteRecord('singleNote', { - headers: { Authorization: `Bearer ${data.credentials.access_token}` } - }); - } - }); - } + return client + .collection('notes', { + idSchema: notesIdSchema, + remoteTransformers: [new JWETransformer(data.credentials.key)], }) - .catch(error => { - if (/HTTP 404/.test(error.message)) { - // If there is nothing in Kinto send null to the sidebar - console.log('Kinto is emtpy'); - browser.runtime.sendMessage({ - action: 'kinto-loaded', - data: null - }); - } else if (/HTTP 401/.test(error.message)) { - // In case of 401 log the user out. - return browser.storage.local.remove('credentials'); - } else { - console.error(error); - } + .sync({ + headers: { Authorization: `Bearer ${data.credentials.access_token}` }, + // FIXME: Handle conflicts + strategy: "server_wins", }); + }) + .then(syncResult => { + // FIXME: conflicts would happen here. + // Do we need to do anything with errors, published, updated, etc.? + return syncResult; + }) + .catch(error => { + if (error.response && error.response.status == 401) { + // In case of 401 log the user out. + // FIXME: Fetch a new token and retry? + return browser.storage.local.remove('credentials'); + } else if (error instanceof ServerKeyNewerError) { + // If the key date is greater than current one, log the user out. + return browser.storage.local.remove('credentials'); + } else if (error instanceof ServerKeyOlderError) { + // If the key date is older than the current one, we can't help + // because there is no way we get the previous key. + // Flush the server because whatever was there is wrong. + // FIXME: need to reset sync status. + const kintoHttp = client.api.remote; + return kintoHttp.bucket('default').deleteCollection('notes', { + headers: { Authorization: `Bearer ${data.credentials.access_token}` } + }); + } else { + console.error(error); + } + }); +} + +function loadFromKinto(client) { + return syncKinto(client) + .then(syncResult => { + // FIXME: Should we only do this if we got new data as part of a sync? + return client.collection('notes', { + idSchema: notesIdSchema, + }).getAny('singleNote'); + }) + .then(result => { + console.log("Collection had record", result); + browser.runtime.sendMessage({ + action: 'kinto-loaded', + data: result.data.content, + contentWasSynced: true, + last_modified: result.data && result.data.last_modified + }); }); } -function saveToKinto(client) { +function saveToKinto(client, content) { // XXX: Debounce the call and set the status to Editing browser.runtime.sendMessage('notes@mozilla.com', { action: 'text-editing' @@ -103,63 +196,35 @@ function saveToKinto(client) { const later = function() { syncDebounce = null; + const notes = client.collection('notes', { + idSchema: notesIdSchema, + }); + let credentials; - browser.storage.local.get(['credentials', 'notes', 'contentWasSynced', 'last_modified']) + browser.storage.local.get(['credentials']) .then(data => { - if (!data.contentWasSynced && data.hasOwnProperty('credentials')) { - return encrypt(data.credentials.key, data.notes) - .then(encrypted => { - const headers = { Authorization: `Bearer ${data.credentials.access_token}`}; - if (data.hasOwnProperty('last_modified') && typeof data.last_modified !== "object") { - headers['If-Match'] = '"' + data.last_modified + '"'; - } - console.log(headers); - return client - .bucket('default') - .collection('notes') - .updateRecord( - { id: 'singleNote', content: encrypted, kid: data.credentials.key.kid }, - { headers } - ); - }) - .then((body) => { - console.log('Content was synced at ' + body.data.last_modified); - return browser.storage.local.set({ contentWasSynced: true, - last_modified: body.data.last_modified }) - .then(() => { - // Set the status to syncing - browser.runtime.sendMessage('notes@mozilla.com', { - action: 'text-synced', - last_modified: body.data.last_modified, - }); - }); - }) - .catch(error => { - if (/HTTP 401/.test(error.message)) { - // In case of 401 log the user out. - return browser.storage.local.remove(['credentials']).then(() => { - return browser.storage.local.set({ contentWasSynced: false }); - }); - } else if (/HTTP 412/.test(error.message)) { - // In case of 412 handle merge conflict - console.log(error); - browser.storage.local.set({ contentWasSynced: false }).then(() => { - loadFromKinto(client); - }); - } else { - console.error(error); - } - }); - } else { - browser.runtime.sendMessage('notes@mozilla.com', { - action: 'text-saved' - }); - } + credentials = data.credentials; + return notes.upsert({ id: 'singleNote', content }); + }) + .then(_ => { + browser.runtime.sendMessage('notes@mozilla.com', { + action: 'text-saved' + }); + return syncKinto(client); + }) + .then(syncResult => { + // FIXME: Do anything with sync result? + return notes.getAny('singleNote'); + }) + .then(result => { + // Set the status to synced + browser.runtime.sendMessage('notes@mozilla.com', { + action: 'text-synced', + last_modified: result.data.last_modified, + }); }); }; clearTimeout(syncDebounce); syncDebounce = setTimeout(later, 1000); - // Try to save the new content with the previous last_modified value - // If it failed loadFromKinto and handle merge } From 3039fd166adc65a278385f95d8d7277d5824ecb1 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 2 Oct 2017 11:47:06 -0400 Subject: [PATCH 082/125] These properties aren't necessary --- src/sync.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sync.js b/src/sync.js index 8101fdc61..bc7bb5608 100644 --- a/src/sync.js +++ b/src/sync.js @@ -125,7 +125,7 @@ class JWETransformer { function syncKinto(client) { // Get credentials and lastmodified - return browser.storage.local.get(['credentials', 'contentWasSynced', 'last_modified']) + return browser.storage.local.get(['credentials']) .then((data) => { // XXX: Ask for an refresh token // Query Kinto with the Bearer Token From df80126a290e4de78ca40009b529f3ca0fd397cb Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 2 Oct 2017 12:04:17 -0400 Subject: [PATCH 083/125] Introduce credentials API This will make things a little easier to test. --- src/background.js | 5 ++-- src/sync.js | 68 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/background.js b/src/background.js index 8d5c9c2b0..0b2773684 100644 --- a/src/background.js +++ b/src/background.js @@ -81,6 +81,7 @@ function authenticate() { }); } browser.runtime.onMessage.addListener(function(eventData) { + const credentials = new BrowserStorageCredentials(browser.storage.local); switch (eventData.action) { case 'authenticate': sendMetrics('webext-button-authenticate', eventData.context); @@ -91,10 +92,10 @@ browser.runtime.onMessage.addListener(function(eventData) { browser.storage.local.remove(['credentials']); break; case 'kinto-load': - loadFromKinto(client); + loadFromKinto(client, credentials); break; case 'kinto-save': - saveToKinto(client, eventData.content); + saveToKinto(client, credentials, eventData.content); break; case 'metrics-changed': sendMetrics('changed', eventData.context); diff --git a/src/sync.js b/src/sync.js index bc7bb5608..dcb08d361 100644 --- a/src/sync.js +++ b/src/sync.js @@ -1,5 +1,6 @@ /* exported loadFromKinto */ /* exported saveToKinto */ +/* exported BrowserStorageCredentials */ let syncDebounce = null; @@ -123,20 +124,53 @@ class JWETransformer { } } -function syncKinto(client) { +/** + * Interface describing a mechanism to fetch credentials. + */ +class Credentials { + async get() { + return Promise.reject("Implement me"); + } + + /** + * Call this if, for example, credentials were invalid. + */ + async clear() { + return Promise.reject("Implement me"); + } +} + +class BrowserStorageCredentials { + constructor(storage) { + this.storage = storage; + } + + async get() { + const data = await this.storage.get(['credentials']); + return data.credentials; + } + + async clear() { + return this.storage.remove('credentials'); + } +} + +function syncKinto(client, credentials) { // Get credentials and lastmodified - return browser.storage.local.get(['credentials']) - .then((data) => { + let credential; + return credentials.get() + .then(received => { + credential = received; // XXX: Ask for an refresh token // Query Kinto with the Bearer Token - if (!data.hasOwnProperty('credentials')) return; + if (!received) return; return client .collection('notes', { idSchema: notesIdSchema, - remoteTransformers: [new JWETransformer(data.credentials.key)], + remoteTransformers: [new JWETransformer(credential.key)], }) .sync({ - headers: { Authorization: `Bearer ${data.credentials.access_token}` }, + headers: { Authorization: `Bearer ${credential.access_token}` }, // FIXME: Handle conflicts strategy: "server_wins", }); @@ -150,10 +184,10 @@ function syncKinto(client) { if (error.response && error.response.status == 401) { // In case of 401 log the user out. // FIXME: Fetch a new token and retry? - return browser.storage.local.remove('credentials'); + return credentials.clear(); } else if (error instanceof ServerKeyNewerError) { // If the key date is greater than current one, log the user out. - return browser.storage.local.remove('credentials'); + return credentials.clear(); } else if (error instanceof ServerKeyOlderError) { // If the key date is older than the current one, we can't help // because there is no way we get the previous key. @@ -161,7 +195,7 @@ function syncKinto(client) { // FIXME: need to reset sync status. const kintoHttp = client.api.remote; return kintoHttp.bucket('default').deleteCollection('notes', { - headers: { Authorization: `Bearer ${data.credentials.access_token}` } + headers: { Authorization: `Bearer ${credential.access_token}` } }); } else { console.error(error); @@ -169,8 +203,8 @@ function syncKinto(client) { }); } -function loadFromKinto(client) { - return syncKinto(client) +function loadFromKinto(client, credentials) { + return syncKinto(client, credentials) .then(syncResult => { // FIXME: Should we only do this if we got new data as part of a sync? return client.collection('notes', { @@ -188,7 +222,7 @@ function loadFromKinto(client) { }); } -function saveToKinto(client, content) { +function saveToKinto(client, credentials, content) { // XXX: Debounce the call and set the status to Editing browser.runtime.sendMessage('notes@mozilla.com', { action: 'text-editing' @@ -199,18 +233,12 @@ function saveToKinto(client, content) { const notes = client.collection('notes', { idSchema: notesIdSchema, }); - let credentials; - - browser.storage.local.get(['credentials']) - .then(data => { - credentials = data.credentials; - return notes.upsert({ id: 'singleNote', content }); - }) + return notes.upsert({ id: 'singleNote', content }) .then(_ => { browser.runtime.sendMessage('notes@mozilla.com', { action: 'text-saved' }); - return syncKinto(client); + return syncKinto(client, credentials); }) .then(syncResult => { // FIXME: Do anything with sync result? From e441d40295d629a2314986cb2f32feb8c238dacc Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 2 Oct 2017 12:11:42 -0400 Subject: [PATCH 084/125] Tell eslint to support modern JS --- .eslintrc.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.yml b/.eslintrc.yml index 09812ffea..de024b5b6 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -3,6 +3,9 @@ env: es6: true webextensions: true +parserOptions: + ecmaVersion: 2017 + extends: - eslint:recommended From 1243fcf31004ec9fd844a7d1be3ad47cfc5d9aa9 Mon Sep 17 00:00:00 2001 From: Arash Mousavi Date: Mon, 2 Oct 2017 16:31:46 +0000 Subject: [PATCH 085/125] Pontoon: Update Persian (fa) localization of Test Pilot: Notes Localization authors: - Arash Mousavi --- locales/fa/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/fa/notes.properties b/locales/fa/notes.properties index 434e91806..c3efa1498 100644 --- a/locales/fa/notes.properties +++ b/locales/fa/notes.properties @@ -4,11 +4,13 @@ welcomeText2=به این دفترچهٔ کوچک تک‌صفحه‌ای در ف emptyPlaceHolder=یک یادداشت بنویسید… giveFeedback=برای ارسال بازخورد اینجا را کلیک کنید -feedback=بازخورد openingLogin=در حال باز کردن صفحه ورود… forgetEmail=این رایانامه را فراموش کن +savingChanges=در حال ذخیره تغییرات… +changesSaved=تمام تغییرات ذخیره شد + syncNotReady2=متاسفیم، همگام‌سازی یادداشت‌ها یک جورایی هنوز آماده نیست. ما کلیک‌های شما رو به عنوان رای به راه‌اندازی سریعش حساب می‌کنیم! syncNotes=همگام‌سازی یادداشت‌ها syncProgress=در حال همگام‌سازی تغییرات… From f454c8f959c977dd6e9735754406429ebf1e3d94 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 2 Oct 2017 12:15:18 -0400 Subject: [PATCH 086/125] Clean up ESLint errors It's important to make sure not a single double quote enters the codebase. --- .eslintrc.yml | 2 ++ src/background.js | 2 +- src/sidebar/panel.js | 2 +- src/sync.js | 39 ++++++++++++++++++++------------------- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index de024b5b6..abde95e70 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -11,11 +11,13 @@ extends: globals: KintoClient: false + Kinto: false Quill: false Jose: false JoseJWE: false TestPilotGA: false fxaCryptoRelier: false + BrowserStorageCredentials: false loadFromKinto: false saveToKinto: false diff --git a/src/background.js b/src/background.js index 0b2773684..0c7159c5c 100644 --- a/src/background.js +++ b/src/background.js @@ -12,7 +12,7 @@ const timeouts = {}; // Kinto sync and encryption -const client = new Kinto({remote: KINTO_SERVER, bucket: "default"}); +const client = new Kinto({remote: KINTO_SERVER, bucket: 'default'}); // Analytics diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 482413e25..a436418ac 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -257,7 +257,7 @@ chrome.runtime.onMessage.addListener(eventData => { }); break; case 'kinto-loaded': - console.log("kinto-loaded content", eventData); + console.log('kinto-loaded content', eventData); if (eventData.data !== null) { const local = quill.getContents(); const remote = eventData.data; diff --git a/src/sync.js b/src/sync.js index dcb08d361..91951c2b5 100644 --- a/src/sync.js +++ b/src/sync.js @@ -35,10 +35,10 @@ function decrypt(key, encrypted) { const notesIdSchema = { // FIXME: Maybe this should generate IDs? generate() { - throw new Error("cannot generate IDs"); + throw new Error('cannot generate IDs'); }, - validate(id) { + validate() { // FIXME: verify that at least this matches Kinto server ID format return true; }, @@ -46,13 +46,13 @@ const notesIdSchema = { class ServerKeyNewerError extends Error { constructor() { - super("key used to encrypt the record appears to be newer than our key"); + super('key used to encrypt the record appears to be newer than our key'); } } class ServerKeyOlderError extends Error { constructor() { - super("key used to encrypt the record appears to be older than our key"); + super('key used to encrypt the record appears to be older than our key'); } } @@ -68,14 +68,14 @@ class JWETransformer { // headers (If-Match, If-None-Match) correctly. // DON'T copy over "deleted" status, because then we'd leak // plaintext deletes. - const status = record._status && (record._status == "deleted" ? "updated" : record._status); + const status = record._status && (record._status === 'deleted' ? 'updated' : record._status); const encryptedResult = { content: ciphertext, id: record.id, _status: status, kid: this.key.kid, }; - if (record.hasOwnProperty("last_modified")) { + if (record.hasOwnProperty('last_modified')) { encryptedResult.last_modified = record.last_modified; } @@ -88,7 +88,7 @@ class JWETransformer { if (record.deleted) { return record; } - throw new Error("No ciphertext: nothing to decrypt?"); + throw new Error('No ciphertext: nothing to decrypt?'); } if (record.kid !== this.key.kid) { @@ -107,16 +107,16 @@ class JWETransformer { decoded = { content: decoded, id: 'singleNote', - } + }; } - if (record.hasOwnProperty("last_modified")) { + if (record.hasOwnProperty('last_modified')) { decoded.last_modified = record.last_modified; } // _status: deleted records were deleted on a client, but // uploaded as an encrypted blob so we don't leak deletions. // If we get such a record, flag it as deleted. - if (decoded._status == "deleted") { + if (decoded._status === 'deleted') { decoded.deleted = true; } @@ -129,19 +129,20 @@ class JWETransformer { */ class Credentials { async get() { - return Promise.reject("Implement me"); + return Promise.reject('Implement me'); } /** * Call this if, for example, credentials were invalid. */ async clear() { - return Promise.reject("Implement me"); + return Promise.reject('Implement me'); } } -class BrowserStorageCredentials { +class BrowserStorageCredentials extends Credentials { constructor(storage) { + super(); this.storage = storage; } @@ -172,7 +173,7 @@ function syncKinto(client, credentials) { .sync({ headers: { Authorization: `Bearer ${credential.access_token}` }, // FIXME: Handle conflicts - strategy: "server_wins", + strategy: 'server_wins', }); }) .then(syncResult => { @@ -181,7 +182,7 @@ function syncKinto(client, credentials) { return syncResult; }) .catch(error => { - if (error.response && error.response.status == 401) { + if (error.response && error.response.status === 401) { // In case of 401 log the user out. // FIXME: Fetch a new token and retry? return credentials.clear(); @@ -205,14 +206,14 @@ function syncKinto(client, credentials) { function loadFromKinto(client, credentials) { return syncKinto(client, credentials) - .then(syncResult => { + .then(() => { // FIXME: Should we only do this if we got new data as part of a sync? return client.collection('notes', { idSchema: notesIdSchema, }).getAny('singleNote'); }) .then(result => { - console.log("Collection had record", result); + console.log('Collection had record', result); browser.runtime.sendMessage({ action: 'kinto-loaded', data: result.data.content, @@ -234,13 +235,13 @@ function saveToKinto(client, credentials, content) { idSchema: notesIdSchema, }); return notes.upsert({ id: 'singleNote', content }) - .then(_ => { + .then(() => { browser.runtime.sendMessage('notes@mozilla.com', { action: 'text-saved' }); return syncKinto(client, credentials); }) - .then(syncResult => { + .then(() => { // FIXME: Do anything with sync result? return notes.getAny('singleNote'); }) From ed06540d865aa4deb932d0477d05343fdf77a6b8 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 2 Oct 2017 15:34:51 -0400 Subject: [PATCH 087/125] Introduce a test harness --- README.md | 1 + package.json | 2 ++ test/index.html | 27 +++++++++++++++++++++++++++ test/test.auth.js | 5 +++++ 4 files changed, 35 insertions(+) create mode 100644 test/index.html create mode 100644 test/test.auth.js diff --git a/README.md b/README.md index 5b5087d8b..aaadcdb9d 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Step 2:Navigate to the root of the directory you cloned and run: | `npm run build` | Builds the application as a Web Extension.| | `npm start` | Launches Firefox with the Web Extension. | +You can also open the `test/index.html` file in your browser to run the automated tests. ## Localization diff --git a/package.json b/package.json index f52ad0ddd..9cefb2fc2 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,11 @@ "testpilot-ga": "^0.2.1" }, "devDependencies": { + "chai": "^4.1.0", "cross-spawn": "^5.1.0", "eslint": "^4.0.0", "fs-extra": "^4.0.1", + "mocha": "^3.2.0", "npm-run-all": "^4.0.2", "pontoon-to-webext": "^1.0.2", "prettier": "^1.4.4", diff --git a/test/index.html b/test/index.html new file mode 100644 index 000000000..6fe772016 --- /dev/null +++ b/test/index.html @@ -0,0 +1,27 @@ + + + + Mocha Tests + + + +
+ + + + + + + + + + + + + + + diff --git a/test/test.auth.js b/test/test.auth.js new file mode 100644 index 000000000..3d8ef1402 --- /dev/null +++ b/test/test.auth.js @@ -0,0 +1,5 @@ +describe('Authorization', function() { + it('should define syncKinto', function() { + chai.expect(syncKinto).not.eql(undefined); + }); +}); From bd3e18034b9887942ddb34525324399458bc9d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mu=E1=B8=A5end=20Belqasem?= Date: Mon, 2 Oct 2017 21:10:55 +0000 Subject: [PATCH 088/125] Pontoon: Update Kabyle (kab) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Muḥend Belqasem --- locales/kab/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/kab/notes.properties b/locales/kab/notes.properties index e099afec0..dfe21c005 100644 --- a/locales/kab/notes.properties +++ b/locales/kab/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Senned dagi akken ad γ-d-azneḍ tikti inek openingLogin=Ldi anekcum… forgetEmail=Ttu tansa-yagi imayl +savingChanges=Asekle n usnifel… +changesSaved=Isnifal ttwaskelsen meṛṛa. + syncNotReady2=Suref-aɣ, amtawi n tezmilin ur iheggi ara. Ad nettkel ɣef utekki-ik d tafrant akken ad tzerbeḍ! syncNotes=Mtawi Tizmilin-inek syncProgress=Amtawi… From b34f53990af56058a02b6579017fa2dfed39f8bd Mon Sep 17 00:00:00 2001 From: Emin Mastizada Date: Tue, 3 Oct 2017 04:31:34 +0000 Subject: [PATCH 089/125] Pontoon: Update Azerbaijani (az) localization of Test Pilot: Notes Localization authors: - Emin Mastizada --- locales/az/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/az/notes.properties b/locales/az/notes.properties index b1979abdb..9d062891c 100644 --- a/locales/az/notes.properties +++ b/locales/az/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Buraya klikləyərək bizə geri dönüşünüzü bildirin openingLogin=Daxil olma açılır… forgetEmail=Bu E-poçt-u unut +savingChanges=Dəyişikliklər saxlanılır… +changesSaved=Bütün dəyişikliklər saxlandı + syncNotReady2=Üzr istəyirik, qeydlərin sinxronlaşdırılması tam hazır deyil. Klikinizi funksionallığı tələsdirmək üçün səs kimi sayacıq! syncNotes=Qeydləri sinxronlaşdır syncProgress=Dəyişikliklər sinxronlaşdırılır… From 56205be17d47b42d2f0601126e371500aed6f6e0 Mon Sep 17 00:00:00 2001 From: "rafael.raybcastro" Date: Thu, 5 Oct 2017 14:11:18 +0000 Subject: [PATCH 090/125] Pontoon: Update Tagalog (tl) localization of Test Pilot: Notes Localization authors: - rafael.raybcastro - Frederick Villaluna --- locales/tl/notes.properties | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 locales/tl/notes.properties diff --git a/locales/tl/notes.properties b/locales/tl/notes.properties new file mode 100644 index 000000000..72d377991 --- /dev/null +++ b/locales/tl/notes.properties @@ -0,0 +1,21 @@ +welcomeTitle2=Kamusta! +welcomeText2=Maligayang padating sa isang-pahingang notepad ginawa sa Firefox. Mag Browse sa web. Mag sulat ng mga tala, Ganun Kadali. + +emptyPlaceHolder=Kumuha ng tala... + +giveFeedback=I-click ito para magbigay ng feedback samin + +openingLogin=Nag Login... +forgetEmail=Kalimutan ang Email na ito + + +# LOCALIZATION NOTE (disableSync): Sync is intended as a generic +# synchronization, not Firefox Sync. +# LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this +# structure doesn't work for your locale, you can translate this as "Last sync: +# {date}". + +# Tooltips for toolbar buttons +numberedListTitle=Bilang na Listahan + +# Settings page labels From 227f84d6feac1593ef94babe47c1059a9f6f3eac Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Thu, 5 Oct 2017 14:17:13 -0400 Subject: [PATCH 091/125] Some simplistic tests These don't use chai-as-promised, even though it would be cleaner, because there's no super easy way to use it in the browser. There might be better ways to get these tests running, but this is probably close enough for now. --- package.json | 3 +++ src/sync.js | 1 + test/index.html | 2 ++ test/test.auth.js | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/package.json b/package.json index 9cefb2fc2..e043a9ddf 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,17 @@ }, "devDependencies": { "chai": "^4.1.0", + "chai-as-promised": "^7.1.1", "cross-spawn": "^5.1.0", "eslint": "^4.0.0", + "fetch-mock": "^5.12.2", "fs-extra": "^4.0.1", "mocha": "^3.2.0", "npm-run-all": "^4.0.2", "pontoon-to-webext": "^1.0.2", "prettier": "^1.4.4", "rimraf": "^2.6.1", + "sinon": "^4.0.1", "web-ext": "^1.9.1" }, "homepage": "https://github.com/mozilla/notes#readme", diff --git a/src/sync.js b/src/sync.js index 91951c2b5..0ebc2c9a0 100644 --- a/src/sync.js +++ b/src/sync.js @@ -200,6 +200,7 @@ function syncKinto(client, credentials) { }); } else { console.error(error); + return Promise.reject(error); } }); } diff --git a/test/index.html b/test/index.html index 6fe772016..99acf6b7d 100644 --- a/test/index.html +++ b/test/index.html @@ -15,6 +15,8 @@ + + diff --git a/test/test.auth.js b/test/test.auth.js index 3d8ef1402..5a83f7e51 100644 --- a/test/test.auth.js +++ b/test/test.auth.js @@ -2,4 +2,45 @@ describe('Authorization', function() { it('should define syncKinto', function() { chai.expect(syncKinto).not.eql(undefined); }); + + describe('401s', function() { + const promiseCredential = Promise.resolve({ + key: { + kid: 20171005, + kty: "kty", + }, + access_token: "access_token" + }); + const client = new Kinto(); + + let credentials; + beforeEach(function() { + fetchMock.mock('*', { + status: 401, + body: "outh", + headers: {"Content-Type": "application/json"}, + }); + credentials = { + get: sinon.mock().returns(promiseCredential), + clear: sinon.mock() + }; + }); + + afterEach(function() { + fetchMock.reset(); + }); + + it('should respond to 401s by deleting the token', function() { + return syncKinto(client, credentials).then(() => { + chai.assert(credentials.clear.calledOnce); + }); + }); + + it('should not reject the promise', function() { + return syncKinto(client, credentials).then( + () => {}, + msg => chai.assert(false, msg.toString()) + ); + }); + }); }); From ce3bd079f30699d383f2ba72b43f7ce605c488bb Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Thu, 5 Oct 2017 16:07:54 -0400 Subject: [PATCH 092/125] Convert to karma tests This seems to be the standard for web extensions. These can be run using npm. Karma relies on sinon-chrome, which (by default) exposes its stuff as a "chrome" variable instead of the "browser" variable we expect. The background script also uses the storage API immediately, so we need to make sure the mock is populated with data before we even load it. --- karma.conf.js | 49 ++++++++++++++++++++++++ package.json | 11 +++++- test/index.html | 29 -------------- test/{test.auth.js => unit/main.test.js} | 3 ++ test/unit/setup_globals.js | 4 ++ 5 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 karma.conf.js delete mode 100644 test/index.html rename test/{test.auth.js => unit/main.test.js} (86%) create mode 100644 test/unit/setup_globals.js diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 000000000..9be2f9309 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,49 @@ +const reporters = ["mocha", "coverage"]; +if (process.env.COVERALLS_REPO_TOKEN) { + reporters.push("coveralls"); +} + +module.exports = function(config) { + config.set({ + singleRun: true, + browsers: ["Firefox"], + frameworks: ["mocha"], + reporters, + coverageReporter: { + dir: "build/coverage", + reporters: [ + { + type: "lcov", + subdir: "lcov" + }, + { + type: "html", + subdir(browser) { + // normalization process to keep a consistent browser name + // across different OS + return browser.toLowerCase().split(/[ /-]/)[0]; + } + }, {type: "text-summary"} + ] + }, + files: [ + "node_modules/chai/chai.js", + "node_modules/sinon/pkg/sinon.js", + "node_modules/sinon-chrome/bundle/sinon-chrome-webextensions.min.js", + "node_modules/fetch-mock/es5/client-browserified.js", + "test/unit/setup_globals.js", + "src/vendor/*.js", + "src/*.js", + "test/unit/*.test.js" + ], + // coverage preprocessor doesn't cope with ES2017 + //preprocessors: {"src/*.js": ["coverage"]}, + plugins: [ + "karma-coveralls", + "karma-coverage", + "karma-firefox-launcher", + "karma-mocha", + "karma-mocha-reporter" + ] + }); +}; diff --git a/package.json b/package.json index e043a9ddf..700224922 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,19 @@ "eslint": "^4.0.0", "fetch-mock": "^5.12.2", "fs-extra": "^4.0.1", + "karma": "^1.7.1", + "karma-coverage": "^1.1.1", + "karma-coveralls": "^1.1.2", + "karma-firefox-launcher": "^1.0.1", + "karma-mocha": "^1.3.0", + "karma-mocha-reporter": "^2.2.4", "mocha": "^3.2.0", "npm-run-all": "^4.0.2", "pontoon-to-webext": "^1.0.2", "prettier": "^1.4.4", "rimraf": "^2.6.1", "sinon": "^4.0.1", + "sinon-chrome": "^2.2.1", "web-ext": "^1.9.1" }, "homepage": "https://github.com/mozilla/notes#readme", @@ -46,6 +53,8 @@ "prebuild": "npm run clean", "start": "web-ext run -s src", "start-rtl": "WEB_EXT_PREF=general.useragent.locale=ar npm start", - "start-nightly": "npm start -- --firefox=nightly" + "start-nightly": "npm start -- --firefox=nightly", + "test": "npm-run-all test:*", + "test:karma": "NODE_ENV=test karma start" } } diff --git a/test/index.html b/test/index.html deleted file mode 100644 index 99acf6b7d..000000000 --- a/test/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - Mocha Tests - - - -
- - - - - - - - - - - - - - - - - diff --git a/test/test.auth.js b/test/unit/main.test.js similarity index 86% rename from test/test.auth.js rename to test/unit/main.test.js index 5a83f7e51..cd0137b03 100644 --- a/test/test.auth.js +++ b/test/unit/main.test.js @@ -1,3 +1,6 @@ +'use strict'; +// Many of these are "functional" tests that are run using Karma, and +// so "unit" tests from the browser perspective (not including browser interaction). describe('Authorization', function() { it('should define syncKinto', function() { chai.expect(syncKinto).not.eql(undefined); diff --git a/test/unit/setup_globals.js b/test/unit/setup_globals.js new file mode 100644 index 000000000..0d43b85b4 --- /dev/null +++ b/test/unit/setup_globals.js @@ -0,0 +1,4 @@ +browser = chrome; +// Provide something static that the background script can load +// without choking. +browser.storage.local.get.resolves({}); From dc24a0583cd52da64f4df96775939068223b02e7 Mon Sep 17 00:00:00 2001 From: Cedricium Date: Thu, 5 Oct 2017 15:07:59 -0700 Subject: [PATCH 093/125] Bug fixes for #253, #271, and #273 This commit fixes issues #253, #271, and #273. How these issues are fixed is described below: - #253: When a space (or any character) is entered at index 0 of the editor with a link immediately following that character (as shown in the screen-grab for the issue), any formatting that is applied to the link will be applied to that character. The issue here was that the `link` format was being applied to space characters, but this is fixed by removing the `link` format from the first character of the editor. - #271 & #273: These issues involve the links getting any format they had applied to them removed as soon as the link-editing format was escaped. The fix for this was to capture and save the format of the link (formats like bold, italics, font size, etc.) then applying those same formats in addition to the `link` format when the url is turned into a link. --- src/sidebar/panel.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 0d66b4a60..d029991cf 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -94,6 +94,7 @@ quill.on('text-change', function(delta) { endRetain += 1; } const text = quill.getText().substr(0, endRetain); + const format = quill.getFormat(text); const match = text.match(regex); if (match !== null) { @@ -104,9 +105,16 @@ quill.on('text-change', function(delta) { ops.push({ retain: endRetain - url.length }); } + const attributes = {}; + // apply any previous formatting options to the attributes object + Object.keys(format).forEach(function(key) { + attributes[key] = format[key]; + }); + attributes['link'] = url; + ops = ops.concat([ { delete: url.length }, - { insert: url, attributes: { link: url } } + { insert: url, attributes } ]); quill.updateContents({ @@ -165,6 +173,8 @@ quill.on('text-change', function(delta) { const format = quill.getFormat(delta.ops[0].retain, 1); if ('link' in format) quill.formatText(delta.ops[0].retain, 1, 'link', false); + } else if (delta.ops.length === 1 && delta.ops[0].hasOwnProperty('insert')) { + quill.formatText(0, 1, 'link', false); } else return; }); From f173649497be157011a96472affec447a097d122 Mon Sep 17 00:00:00 2001 From: Enol Date: Fri, 6 Oct 2017 11:51:48 +0000 Subject: [PATCH 094/125] Pontoon: Update Asturian (ast) localization of Test Pilot: Notes Localization authors: - Enol --- locales/ast/notes.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/ast/notes.properties b/locales/ast/notes.properties index 9ac02701e..7ad8fbe72 100644 --- a/locales/ast/notes.properties +++ b/locales/ast/notes.properties @@ -4,11 +4,13 @@ welcomeText2=Afáyate nesti bloc de notes d'una fueya integráu en Firefox. Rest emptyPlaceHolder=Anotar… giveFeedback=Primi equí pa damos daqué de feedback -feedback=Unviar comentarios openingLogin=Abriendo aniciu de sesión… forgetEmail=Escaecer esti corréu +savingChanges=Guardando camudancies… +changesSaved=Guardáronse toles camudancies + syncNotReady2=Perdón, la sincronización de notes entá nun ta preparada. ¡Cuntaremos el to clic como un votu pa entainar! syncNotes=Sincroniza les tos notes syncProgress=Sincronizando camudancies… From 81acb3b0a25b6cfd911416a31277047e79d67a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 6 Oct 2017 15:30:32 +0200 Subject: [PATCH 095/125] All changes saved should not act as a button. --- src/sidebar/panel.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sidebar/panel.html b/src/sidebar/panel.html index 9e6c48420..d15a691fb 100644 --- a/src/sidebar/panel.html +++ b/src/sidebar/panel.html @@ -41,7 +41,7 @@
From b65428c8c4608f8f1adac366d1c5d015d97e8fae Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Fri, 6 Oct 2017 13:39:42 -0400 Subject: [PATCH 096/125] Use webpack to build unit tests This lets us require() stuff like normal rather than hoping that a version exists that is prebuilt for browsers. In particular, this lets us use chai-as-promised. --- .gitignore | 1 + karma.conf.js | 7 +------ package.json | 5 +++-- test/unit/{setup_globals.js => index.js} | 4 +++- test/unit/main.test.js | 12 ++++++++---- webpack.test-unit.js | 9 +++++++++ 6 files changed, 25 insertions(+), 13 deletions(-) rename test/unit/{setup_globals.js => index.js} (60%) create mode 100644 webpack.test-unit.js diff --git a/.gitignore b/.gitignore index 6ea03278c..0d1d8ff64 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ src/vendor/* src/sidebar/vendor/* src/_locales web-ext-artifacts/ +test/dist/* diff --git a/karma.conf.js b/karma.conf.js index 9be2f9309..815e850e1 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -27,14 +27,9 @@ module.exports = function(config) { ] }, files: [ - "node_modules/chai/chai.js", - "node_modules/sinon/pkg/sinon.js", - "node_modules/sinon-chrome/bundle/sinon-chrome-webextensions.min.js", - "node_modules/fetch-mock/es5/client-browserified.js", - "test/unit/setup_globals.js", "src/vendor/*.js", + "test/dist/unit-bundle.js", "src/*.js", - "test/unit/*.test.js" ], // coverage preprocessor doesn't cope with ES2017 //preprocessors: {"src/*.js": ["coverage"]}, diff --git a/package.json b/package.json index 700224922..dabc1ca4e 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,8 @@ "rimraf": "^2.6.1", "sinon": "^4.0.1", "sinon-chrome": "^2.2.1", - "web-ext": "^1.9.1" + "web-ext": "^1.9.1", + "webpack": "^3.6.0" }, "homepage": "https://github.com/mozilla/notes#readme", "license": "MPL-2.0", @@ -55,6 +56,6 @@ "start-rtl": "WEB_EXT_PREF=general.useragent.locale=ar npm start", "start-nightly": "npm start -- --firefox=nightly", "test": "npm-run-all test:*", - "test:karma": "NODE_ENV=test karma start" + "test:karma": "webpack --config webpack.test-unit.js && NODE_ENV=test karma start" } } diff --git a/test/unit/setup_globals.js b/test/unit/index.js similarity index 60% rename from test/unit/setup_globals.js rename to test/unit/index.js index 0d43b85b4..f1555a32d 100644 --- a/test/unit/setup_globals.js +++ b/test/unit/index.js @@ -1,4 +1,6 @@ -browser = chrome; +browser = require('sinon-chrome/webextensions/index'); // Provide something static that the background script can load // without choking. browser.storage.local.get.resolves({}); + +require('./main.test'); diff --git a/test/unit/main.test.js b/test/unit/main.test.js index cd0137b03..2aa988c3c 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -1,4 +1,11 @@ 'use strict'; +var chai = require('chai'); +var sinon = require('sinon'); +var chaiAsPromised = require('chai-as-promised'); +var fetchMock = require('fetch-mock'); + +chai.use(chaiAsPromised); + // Many of these are "functional" tests that are run using Karma, and // so "unit" tests from the browser perspective (not including browser interaction). describe('Authorization', function() { @@ -40,10 +47,7 @@ describe('Authorization', function() { }); it('should not reject the promise', function() { - return syncKinto(client, credentials).then( - () => {}, - msg => chai.assert(false, msg.toString()) - ); + return chai.expect(syncKinto(client, credentials)).fulfilled; }); }); }); diff --git a/webpack.test-unit.js b/webpack.test-unit.js new file mode 100644 index 000000000..123933d9f --- /dev/null +++ b/webpack.test-unit.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + entry: './test/unit/index.js', + output: { + filename: 'unit-bundle.js', + path: path.resolve(__dirname, 'test/dist/') + } +}; From e9bf5b1b373738eca80318b7f4ff9151bd3e5650 Mon Sep 17 00:00:00 2001 From: Abdalrahman Hwoij Date: Fri, 6 Oct 2017 20:52:00 +0000 Subject: [PATCH 097/125] Pontoon: Update Arabic (ar) localization of Test Pilot: Notes Localization authors: - Abdalrahman Hwoij - Khaled Hosny --- locales/ar/notes.properties | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/locales/ar/notes.properties b/locales/ar/notes.properties index 6290b1abe..4dbd2d967 100644 --- a/locales/ar/notes.properties +++ b/locales/ar/notes.properties @@ -8,6 +8,9 @@ giveFeedback=انقر هنا لإطلاعنا على مقترحاتك openingLogin=يفتح الولوج… forgetEmail=انسَ هذا البريد +savingChanges=يحفظ التغييرات… +changesSaved=حُفظت كل التغييرات + syncNotReady2=للأسف مزامنة الملاحظات ليست جاهزة بعد، لكن ستعتبر نقرتك تصويتًا ليُسرع. syncNotes=زامن ملاحظاتك syncProgress=يُزامن التغييرات… @@ -27,3 +30,8 @@ strikethroughTitle=مشطوب numberedListTitle=قائمة مرقومة bulletedListTitle=قائمة منقوطة textDirectionTitle=اتجاه النص + +# Settings page labels +themeLegend=سمة +defaultThemeTitle=المبدئي +darkThemeTitle=داكن From 063ea5215e04c7b7a9fc74d53a83fc03efcfd96a Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Fri, 6 Oct 2017 17:31:06 -0400 Subject: [PATCH 098/125] Add more tests to try to verify the handling of decryption --- test/unit/main.test.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/unit/main.test.js b/test/unit/main.test.js index 2aa988c3c..8f63fbfcc 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -9,6 +9,15 @@ chai.use(chaiAsPromised); // Many of these are "functional" tests that are run using Karma, and // so "unit" tests from the browser perspective (not including browser interaction). describe('Authorization', function() { + let sandbox; + beforeEach(function() { + sandbox = sinon.sandbox.create(); + }); + + afterEach(function() { + sandbox.restore(); + }); + it('should define syncKinto', function() { chai.expect(syncKinto).not.eql(undefined); }); @@ -50,4 +59,32 @@ describe('Authorization', function() { return chai.expect(syncKinto(client, credentials)).fulfilled; }); }); + + describe("remote transformer", function() { + const kid = 20171005; + const key = {kid: kid, kty: "kty"}; + it("should return whatever decrypt returns", function() { + const decryptedResult = { content: [{ insert: "Test message" }] }; + const decryptMock = sandbox.stub(global, 'decrypt'); + decryptMock.returns(decryptedResult); + chai.expect(new JWETransformer(key).decode({content: "encrypted content", kid: kid})).eventually.eql({ + content: [{insert: "Test message"}], + }); + }); + + it("should throw if kid is different", function() { + chai.expect(new JWETransformer(key).decode({content: "encrypted content", kid: 20171001})).rejectedWith(ServerKeyOlderError); + }); + + it("should be backwards compatible with the old style of Kinto record", function() { + const oldRecordStyle = [ + { insert: "Test message" }, + ]; + const decryptMock = sandbox.stub(global, 'decrypt'); + decryptMock.returns(oldRecordStyle); + chai.expect(new JWETransformer(key).decode({content: "encrypted content", kid: kid})).eventually.eql({ + content: [{insert: "Test message"}], + }); + }); + }); }); From fc33d1626716fb9fdacef3e7c8572acc402cc774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20I?= Date: Sat, 7 Oct 2017 11:11:15 +0000 Subject: [PATCH 099/125] Pontoon: Update Norwegian Nynorsk (nn-NO) localization of Test Pilot: Notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Localization authors: - Bjørn I. --- locales/nn-NO/notes.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/nn-NO/notes.properties b/locales/nn-NO/notes.properties index a36bf37a7..1365d7a10 100644 --- a/locales/nn-NO/notes.properties +++ b/locales/nn-NO/notes.properties @@ -8,6 +8,9 @@ giveFeedback=Klikk her for å gje oss tilbakemelding openingLogin=Opnar innlogging… forgetEmail=Gløym denne e-posten +savingChanges=Lagrar endringar… +changesSaved=Alle endringar lagra + syncNotReady2=Diverre, synkroniserte notat er ikkje heilt klare. Vi reknar ditt klikk som ei røyst for å henge litt i! syncNotes=Sync notata dine syncProgress=Synkroniserer endringar… From 6981a935b2c681551239fa7dc39d4c9ab1737597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Oct 2017 15:49:33 +0200 Subject: [PATCH 100/125] Run tests with Travis. --- .travis.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 657d55ce7..2fbad8b67 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,16 @@ language: node_js - +addons: + firefox: latest node_js: - "6" - +before_install: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - sleep 3 script: - npm run build - npm run lint + - npm run test +env: + global: + - FIREFOX_BINARY: firefox From 52c14ac616f624bd76977e2f57334310762cd3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Oct 2017 16:29:38 +0200 Subject: [PATCH 101/125] Back to development: 1.9.0 --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 842d0ead4..f612b543b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,15 @@ # Changelog -## 1.8.0 (unreleased) +## 1.9.0 (unreleased) -* No changes yet +* Add links support + + +## 1.8.0 (2017-10-09) + +* Add a saving status indicator +* Update Notes icon to a SVG one +* Fix 14px default size ## 1.7.1 (2017-08-29) From 4e687c76438c077a46450b9d819e000b635e2341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Oct 2017 17:12:49 +0200 Subject: [PATCH 102/125] Fixing @natim bugs. Paired with @glasserc --- src/sidebar/panel.js | 22 +++++----------------- src/sync.js | 5 +++-- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index a436418ac..731886ecb 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -258,23 +258,11 @@ chrome.runtime.onMessage.addListener(eventData => { break; case 'kinto-loaded': console.log('kinto-loaded content', eventData); - if (eventData.data !== null) { - const local = quill.getContents(); - const remote = eventData.data; - if (!eventData.contentWasSynced) { - const newContent = JSON.parse(JSON.stringify(remote)); - newContent.ops.push({ insert: '\n====== Previously was ======\n\n' }); - content = newContent.ops.concat(local.ops); - } else { - content = remote; - } - ignoreNextTextChange = true; - } else { - browser.storage.local.remove('initialContent'); - content = eventData.data; - } - browser.storage.local.set({ notes: content, last_modified: eventData.last_modified }); - + content = eventData.data; + browser.storage.local.set({ notes: content, + last_modified: eventData.last_modified}); + time = new Date(eventData.last_modified).toLocaleTimeString(); + enableSync.textContent = 'Synced at ' + time; setTimeout(() => { console.log('Content is', content); quill.setContents(content); diff --git a/src/sync.js b/src/sync.js index 0ebc2c9a0..14cfc7df4 100644 --- a/src/sync.js +++ b/src/sync.js @@ -91,7 +91,7 @@ class JWETransformer { throw new Error('No ciphertext: nothing to decrypt?'); } - if (record.kid !== this.key.kid) { + if (record.kid.substr(15) !== this.key.kid.substr(15)) { if (this.key.kid < record.kid) { throw new ServerKeyNewerError(); } else { @@ -119,7 +119,6 @@ class JWETransformer { if (decoded._status === 'deleted') { decoded.deleted = true; } - return decoded; } } @@ -188,12 +187,14 @@ function syncKinto(client, credentials) { return credentials.clear(); } else if (error instanceof ServerKeyNewerError) { // If the key date is greater than current one, log the user out. + console.error(error); return credentials.clear(); } else if (error instanceof ServerKeyOlderError) { // If the key date is older than the current one, we can't help // because there is no way we get the previous key. // Flush the server because whatever was there is wrong. // FIXME: need to reset sync status. + console.error(error); const kintoHttp = client.api.remote; return kintoHttp.bucket('default').deleteCollection('notes', { headers: { Authorization: `Bearer ${credential.access_token}` } From 9fc10c5fd0bff324c6b82d019e8d192d417edafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Oct 2017 17:24:41 +0200 Subject: [PATCH 103/125] Fixing whitespaces. --- src/settings/settings.html | 8 ++++---- src/settings/settings.js | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/settings/settings.html b/src/settings/settings.html index e51d34865..c379a096e 100644 --- a/src/settings/settings.html +++ b/src/settings/settings.html @@ -5,9 +5,9 @@ - + - +
@@ -19,8 +19,8 @@
- + - + diff --git a/src/settings/settings.js b/src/settings/settings.js index 301252e69..676d4595a 100644 --- a/src/settings/settings.js +++ b/src/settings/settings.js @@ -11,7 +11,7 @@ const themeRadioBtn = document.getElementsByName('theme'); function loadSavedData(data) { const theme = data.theme; - + if (theme === 'default') themeRadioBtn[0].checked = true; else if (theme === 'dark') @@ -25,25 +25,25 @@ document.addEventListener('DOMContentLoaded', function() { function getTheme() { let theme = ''; - + for (let i = 0; i < themeRadioBtn.length; i++) { if (themeRadioBtn[i].checked) theme = themeRadioBtn[i].value; else continue; } - + const selectedTheme = { theme: theme }; - + return selectedTheme; } for (let i = 0; i < themeRadioBtn.length; i++) { themeRadioBtn[i].onclick = function() { const theme = getTheme(); - + browser.storage.local.set(theme); // notify background.js that theme settings have changed From 52958dc573e5a0967a6f4e1d2532776dd43dca1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Oct 2017 17:25:01 +0200 Subject: [PATCH 104/125] Clicking on the sync button once connected force a new sync. --- src/background.js | 14 ++++++++++++-- src/sidebar/panel.js | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/background.js b/src/background.js index 0c7159c5c..b1f899cb6 100644 --- a/src/background.js +++ b/src/background.js @@ -84,8 +84,18 @@ browser.runtime.onMessage.addListener(function(eventData) { const credentials = new BrowserStorageCredentials(browser.storage.local); switch (eventData.action) { case 'authenticate': - sendMetrics('webext-button-authenticate', eventData.context); - authenticate(); + credentials.get() + .then(result => { + if (!result) { + sendMetrics('webext-button-authenticate', eventData.context); + authenticate(); + } else { + chrome.runtime.sendMessage({ + action: 'text-syncing' + }); + loadFromKinto(client, credentials); + } + }); break; case 'disconnected': sendMetrics('webext-button-disconnect', eventData.context); diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 731886ecb..c607add5b 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -272,6 +272,9 @@ chrome.runtime.onMessage.addListener(eventData => { ignoreNextLoadEvent = true; loadContent(); break; + case 'text-syncing': + enableSync.textContent = 'Syncing'; + break; case 'text-editing': enableSync.textContent = 'Editing'; break; From 58c97a2227e7ad1d8d6ebbd349408cd3885d3a26 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 9 Oct 2017 12:04:04 -0400 Subject: [PATCH 105/125] Add verifyAndRestore We don't actually use any expectations yet, but maybe we will one day. --- test/unit/main.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/main.test.js b/test/unit/main.test.js index 8f63fbfcc..e8a0548a7 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -15,7 +15,7 @@ describe('Authorization', function() { }); afterEach(function() { - sandbox.restore(); + sandbox.verifyAndRestore(); }); it('should define syncKinto', function() { From a761c7981c179e9fe3062e36c5f553836fbd30de Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 9 Oct 2017 12:04:26 -0400 Subject: [PATCH 106/125] Add failing unit test that reproduces error @vladikoff got --- test/unit/main.test.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/unit/main.test.js b/test/unit/main.test.js index e8a0548a7..02296c42f 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -87,4 +87,26 @@ describe('Authorization', function() { }); }); }); + + describe('loadKinto', function() { + it('should fire a kinto-loaded message even if nothing in kinto', () => { + const syncKinto = sandbox.stub(global, 'syncKinto').resolves(undefined); + const collection = { + getAny: sandbox.stub().resolves(undefined) + }; + const client = { + collection: sandbox.stub().returns(collection) + }; + return loadFromKinto(client, undefined) + .then(() => { + chai.assert(browser.runtime.sendMessage.calledOnce); + chai.expect(browser.runtime.sendMessage.getCall(0).args(0)).eql({ + action: 'kinto-loaded', + data: null, + contentWasSynced: false, + last_modified: undefined, + }); + }); + }); + }); }); From c24a98a18ae0df418d5f74fb3aff59507baec213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 9 Oct 2017 18:07:13 +0200 Subject: [PATCH 107/125] Fix linter. --- src/sidebar/panel.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 72aec3f80..4844fb08c 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -196,10 +196,10 @@ giveFeedback.addEventListener('click', () => { }); }); const disconnectSync = document.getElementById('disconnect-from-sync'); -disconnectSync.style.display = "none"; +disconnectSync.style.display = 'none'; disconnectSync.textContent = browser.i18n.getMessage('disableSync'); disconnectSync.addEventListener('click', () => { - disconnectSync.style.display = "none"; + disconnectSync.style.display = 'none'; enableSync.textContent = 'Disconnected'; setTimeout(() => { enableSync.textContent = browser.i18n.getMessage('syncNotes'); @@ -274,7 +274,7 @@ chrome.runtime.onMessage.addListener(eventData => { last_modified: eventData.last_modified}); time = new Date(eventData.last_modified).toLocaleTimeString(); enableSync.textContent = 'Synced at ' + time; - disconnectSync.style.display = "block"; + disconnectSync.style.display = 'block'; setTimeout(() => { console.log('Content is', content); quill.setContents(content); From ca027066bdd03bb1e29cb95682a573408a65153b Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 9 Oct 2017 15:15:23 -0400 Subject: [PATCH 108/125] Fix test --- src/sync.js | 21 +++++++++++++++++---- test/unit/main.test.js | 5 ++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/sync.js b/src/sync.js index 14cfc7df4..14b959142 100644 --- a/src/sync.js +++ b/src/sync.js @@ -206,10 +206,24 @@ function syncKinto(client, credentials) { }); } +/** + * Try to sync against the Kinto server, and retrieve the current note + * contents. + * + * On completion, a 'kinto-loaded' event will be fired with the + * following structure: + * + * { + * action: 'kinto-loaded', + * data: the "content" that was previously saved to Kinto, or null + * if nothing was previously saved to Kinto (for example, a new + * FxA account, or if syncing failed on a fresh profile) + * last_modified: the timestamp of the sync, or null + * } + */ function loadFromKinto(client, credentials) { return syncKinto(client, credentials) .then(() => { - // FIXME: Should we only do this if we got new data as part of a sync? return client.collection('notes', { idSchema: notesIdSchema, }).getAny('singleNote'); @@ -218,9 +232,8 @@ function loadFromKinto(client, credentials) { console.log('Collection had record', result); browser.runtime.sendMessage({ action: 'kinto-loaded', - data: result.data.content, - contentWasSynced: true, - last_modified: result.data && result.data.last_modified + data: result ? result.data.content : null, + last_modified: result ? result.data.last_modified : null, }); }); } diff --git a/test/unit/main.test.js b/test/unit/main.test.js index 02296c42f..c654bdfd7 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -100,11 +100,10 @@ describe('Authorization', function() { return loadFromKinto(client, undefined) .then(() => { chai.assert(browser.runtime.sendMessage.calledOnce); - chai.expect(browser.runtime.sendMessage.getCall(0).args(0)).eql({ + chai.expect(browser.runtime.sendMessage.getCall(0).args[0]).eql({ action: 'kinto-loaded', data: null, - contentWasSynced: false, - last_modified: undefined, + last_modified: null, }); }); }); From d594695da6aabb046568c53cd05f76c85254fd48 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 9 Oct 2017 16:02:45 -0400 Subject: [PATCH 109/125] Define correct failure behavior for syncKinto --- src/sync.js | 21 ++++++++++++++++----- test/unit/main.test.js | 30 +++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/sync.js b/src/sync.js index 14b959142..73b039eaf 100644 --- a/src/sync.js +++ b/src/sync.js @@ -155,6 +155,14 @@ class BrowserStorageCredentials extends Credentials { } } +/** + * Try to sync our data against the Kinto server. + * + * Returns a promise. The promise can reject in case of sync failure + * or any other reason. This is so that programming errors can be + * caught more easily in testing. Since this application is + * offline-first, sync failure should not be a failure for callers. + */ function syncKinto(client, credentials) { // Get credentials and lastmodified let credential; @@ -222,12 +230,15 @@ function syncKinto(client, credentials) { * } */ function loadFromKinto(client, credentials) { + function retrieveNote() { + return client.collection('notes', { + idSchema: notesIdSchema, + }).getAny('singleNote'); + } + return syncKinto(client, credentials) - .then(() => { - return client.collection('notes', { - idSchema: notesIdSchema, - }).getAny('singleNote'); - }) + // Ignore failure of syncKinto by retrieving note even when promise rejected + .then(retrieveNote, retrieveNote) .then(result => { console.log('Collection had record', result); browser.runtime.sendMessage({ diff --git a/test/unit/main.test.js b/test/unit/main.test.js index c654bdfd7..d5a72e631 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -16,6 +16,7 @@ describe('Authorization', function() { afterEach(function() { sandbox.verifyAndRestore(); + browser.flush(); }); it('should define syncKinto', function() { @@ -89,14 +90,19 @@ describe('Authorization', function() { }); describe('loadKinto', function() { - it('should fire a kinto-loaded message even if nothing in kinto', () => { - const syncKinto = sandbox.stub(global, 'syncKinto').resolves(undefined); - const collection = { - getAny: sandbox.stub().resolves(undefined) + let collection, client; + beforeEach(() => { + collection = { + getAny: sandbox.stub(), }; - const client = { + client = { collection: sandbox.stub().returns(collection) }; + }); + + it('should fire a kinto-loaded message even if nothing in kinto', () => { + const syncKinto = sandbox.stub(global, 'syncKinto').resolves(undefined); + collection.getAny.resolves(undefined); return loadFromKinto(client, undefined) .then(() => { chai.assert(browser.runtime.sendMessage.calledOnce); @@ -107,5 +113,19 @@ describe('Authorization', function() { }); }); }); + + it('should not fail if syncKinto rejects', () => { + const syncKinto = sandbox.stub(global, 'syncKinto').rejects('server busy playing Minesweeper'); + collection.getAny.resolves({data: {last_modified: 'abc', content: 'def'}}); + return loadFromKinto(client, undefined) + .then(() => { + chai.assert(browser.runtime.sendMessage.calledOnce); + chai.expect(browser.runtime.sendMessage.getCall(0).args[0]).eql({ + action: 'kinto-loaded', + data: 'def', + last_modified: 'abc', + }); + }); + }); }); }); From 3f214beb74356f1c3c264b63d99120f1e8a8b526 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 9 Oct 2017 16:13:44 -0400 Subject: [PATCH 110/125] Add a test to verify that saveToKinto doesn't fail when syncing fails This requires promisifying saveToKinto a little bit. Earlier calls to the debounced function will never resolve, but hopefully that should be fine. --- src/sync.js | 31 +++++++++++++++++++------------ test/unit/main.test.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/sync.js b/src/sync.js index 73b039eaf..7b299b5b7 100644 --- a/src/sync.js +++ b/src/sync.js @@ -214,6 +214,12 @@ function syncKinto(client, credentials) { }); } +function retrieveNote(client) { + return client.collection('notes', { + idSchema: notesIdSchema, + }).getAny('singleNote'); +} + /** * Try to sync against the Kinto server, and retrieve the current note * contents. @@ -230,15 +236,9 @@ function syncKinto(client, credentials) { * } */ function loadFromKinto(client, credentials) { - function retrieveNote() { - return client.collection('notes', { - idSchema: notesIdSchema, - }).getAny('singleNote'); - } - return syncKinto(client, credentials) // Ignore failure of syncKinto by retrieving note even when promise rejected - .then(retrieveNote, retrieveNote) + .then(() => retrieveNote(client), () => retrieveNote(client)) .then(result => { console.log('Collection had record', result); browser.runtime.sendMessage({ @@ -250,6 +250,12 @@ function loadFromKinto(client, credentials) { } function saveToKinto(client, credentials, content) { + let resolve, reject; + const promise = new Promise((thisResolve, thisReject) => { + resolve = thisResolve; + reject = thisReject; + }); + // XXX: Debounce the call and set the status to Editing browser.runtime.sendMessage('notes@mozilla.com', { action: 'text-editing' @@ -267,19 +273,20 @@ function saveToKinto(client, credentials, content) { }); return syncKinto(client, credentials); }) - .then(() => { - // FIXME: Do anything with sync result? - return notes.getAny('singleNote'); - }) + .then(() => retrieveNote(client), () => retrieveNote(client)) .then(result => { // Set the status to synced - browser.runtime.sendMessage('notes@mozilla.com', { + return browser.runtime.sendMessage('notes@mozilla.com', { action: 'text-synced', last_modified: result.data.last_modified, }); + }) + .then(() => { + resolve(); }); }; clearTimeout(syncDebounce); syncDebounce = setTimeout(later, 1000); + return promise; } diff --git a/test/unit/main.test.js b/test/unit/main.test.js index d5a72e631..a9813dde0 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -128,4 +128,39 @@ describe('Authorization', function() { }); }); }); + + describe('saveToKinto', function() { + let collection, client; + beforeEach(() => { + collection = { + upsert: sandbox.stub().resolves(undefined), + getAny: sandbox.stub(), + }; + client = { + collection: sandbox.stub().returns(collection) + }; + }); + + it('should not fail if syncKinto rejects', () => { + const syncKinto = sandbox.stub(global, 'syncKinto').rejects('server busy playing Minesweeper'); + collection.getAny.resolves({data: {last_modified: 'abc', content: 'def'}}); + return saveToKinto(client, undefined, 'imaginary content') + .then(() => { + chai.assert(browser.runtime.sendMessage.calledThrice); + chai.expect(browser.runtime.sendMessage.getCall(0).args[0]).eql('notes@mozilla.com'); + chai.expect(browser.runtime.sendMessage.getCall(0).args[1]).eql({ + action: 'text-editing', + }); + chai.expect(browser.runtime.sendMessage.getCall(1).args[0]).eql('notes@mozilla.com'); + chai.expect(browser.runtime.sendMessage.getCall(1).args[1]).eql({ + action: 'text-saved', + }); + chai.expect(browser.runtime.sendMessage.getCall(2).args[0]).eql('notes@mozilla.com'); + chai.expect(browser.runtime.sendMessage.getCall(2).args[1]).eql({ + action: 'text-synced', + last_modified: 'abc', + }); + }); + }); + }); }); From f287edcd1b4b3204e295e8904f9dab2010eacd77 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Mon, 9 Oct 2017 17:01:08 -0400 Subject: [PATCH 111/125] Fix linter --- src/sync.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sync.js b/src/sync.js index 7b299b5b7..f1ed07496 100644 --- a/src/sync.js +++ b/src/sync.js @@ -250,10 +250,9 @@ function loadFromKinto(client, credentials) { } function saveToKinto(client, credentials, content) { - let resolve, reject; - const promise = new Promise((thisResolve, thisReject) => { + let resolve; + const promise = new Promise(thisResolve => { resolve = thisResolve; - reject = thisReject; }); // XXX: Debounce the call and set the status to Editing From 58cd81ab56f1dbbd99110a0397a0ea3a58ed2f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 13:35:01 +0200 Subject: [PATCH 112/125] Internationalize strings. --- locales/en-US/notes.properties | 8 ++++- src/sidebar/panel.js | 61 +++++++++++++++++----------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/locales/en-US/notes.properties b/locales/en-US/notes.properties index 7c1c87cd0..755028509 100644 --- a/locales/en-US/notes.properties +++ b/locales/en-US/notes.properties @@ -8,6 +8,7 @@ feedback=Feedback openingLogin=Opening Login… forgetEmail=Forget this Email +disconnected=Disconnected syncNotReady2=Sorry, syncing notes isn’t quite ready. We will count your click as a vote to hurry it up! syncNotes=Sync Your Notes @@ -18,7 +19,12 @@ disableSync=Disable Sync # LOCALIZATION NOTE (syncComplete): {date} is the date of last sync. If this # structure doesn't work for your locale, you can translate this as "Last sync: # {date}". -syncComplete=Synced {date} +syncComplete=Synced at {date} +# LOCALIZATION NOTE (savedComplete): {date} is the time of saving. If this +# structure doesn't work for your locale, you can translate this as "Saved ( +# {date})". +savedComplete=Saved at {date} +editing = Editing # Tooltips for toolbar buttons fontSizeTitle=Font Size diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 4844fb08c..93905f366 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -200,7 +200,7 @@ disconnectSync.style.display = 'none'; disconnectSync.textContent = browser.i18n.getMessage('disableSync'); disconnectSync.addEventListener('click', () => { disconnectSync.style.display = 'none'; - enableSync.textContent = 'Disconnected'; + enableSync.textContent = browser.i18n.getMessage('disconnected'); setTimeout(() => { enableSync.textContent = browser.i18n.getMessage('syncNotes'); }, 2000); @@ -213,7 +213,14 @@ closeButton.addEventListener('click', () => { noteDiv.classList.toggle('visible'); }); +let loginTimeout; enableSync.onclick = () => { + enableSync.textContent = browser.i18n.getMessage('openingLogin'); + + loginTimeout = setTimeout(() => { + enableSync.textContent = browser.i18n.getMessage('syncNotes'); + }, 60000); + browser.runtime.sendMessage({ action: 'authenticate', context: getPadStats() @@ -250,7 +257,10 @@ function getLastSyncedTime() { getting.then(data => { if (data.hasOwnProperty('credentials')) { const time = new Date(data.last_modified).toLocaleTimeString(); - enableSync.textContent = 'Synced at ' + time; + enableSync.textContent = browser.i18n.getMessage('syncComplete', time); + } else { + const time = new Date().toLocaleTimeString(); + enableSync.textContent = browser.i18n.getMessage('savedComplete', time); } }); } @@ -267,36 +277,40 @@ chrome.runtime.onMessage.addListener(eventData => { action: 'kinto-load' }); break; - case 'kinto-loaded': + case 'kinto-loaded': + clearTimeout(loginTimeout); console.log('kinto-loaded content', eventData); content = eventData.data; browser.storage.local.set({ notes: content, - last_modified: eventData.last_modified}); - time = new Date(eventData.last_modified).toLocaleTimeString(); - enableSync.textContent = 'Synced at ' + time; - disconnectSync.style.display = 'block'; - setTimeout(() => { - console.log('Content is', content); - quill.setContents(content); - }, 10); + last_modified: eventData.last_modified}) + .then(() => { + getLastSyncedTime(); + disconnectSync.style.display = 'block'; + setTimeout(() => { + console.log('Content is', content); + quill.setContents(content); + }, 10); + }); break; case 'text-change': ignoreNextLoadEvent = true; loadContent(); break; case 'text-syncing': - enableSync.textContent = 'Syncing'; + enableSync.textContent = browser.i18n.getMessage('syncProgress'); break; case 'text-editing': - enableSync.textContent = 'Editing'; + enableSync.textContent = browser.i18n.getMessage('editing'); break; case 'text-synced': - time = new Date(eventData.last_modified).toLocaleTimeString(); - enableSync.textContent = 'Synced at ' + time; + browser.storage.local.set({ last_modified: eventData.last_modified}) + .then(() => { + getLastSyncedTime(); + }); break; case 'text-saved': time = new Date().toLocaleTimeString(); - enableSync.textContent = 'Saved at ' + time; + enableSync.textContent = browser.i18n.getMessage('savedComplete', time); break; case 'theme-changed': getThemeFromStorage(); @@ -363,18 +377,3 @@ function getPadStats() { // Create a connection with the background script to handle open and // close events. browser.runtime.connect(); - -chrome.runtime.onMessage.addListener(eventData => { - switch (eventData.action) { - case 'authenticated': - if (eventData.err) { - // TODO: Localize this - enableSync.textContent = 'Login Failed…'; - } else if (eventData.bearer) { - enableSync.textContent = 'Synced'; - enableSync.disabled = true; - } - - break; - } -}); From 3be2933c29f3af94817833a39e8c06c4ea802599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 14:04:12 +0200 Subject: [PATCH 113/125] Fix linter. --- src/sidebar/panel.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sidebar/panel.js b/src/sidebar/panel.js index 02075ae5b..82ca67d37 100644 --- a/src/sidebar/panel.js +++ b/src/sidebar/panel.js @@ -215,14 +215,10 @@ const INITIAL_CONTENT = { ] }; -// What I have is already in localStorage. -let ignoreNextTextChange = true; - function handleLocalContent(data) { if (!data.hasOwnProperty('notes')) { quill.setContents(INITIAL_CONTENT); browser.storage.local.set({contentWasSynced: true }); - ignoreNextTextChange = true; } else { if (JSON.stringify(quill.getContents()) !== JSON.stringify(data.notes)) { quill.setContents(data.notes); From b8d0951262fc612bbdefee62f14221a58558fb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 14:05:18 +0200 Subject: [PATCH 114/125] Upgrade version to 2.0.0dev --- package.json | 2 +- src/background.js | 2 +- src/manifest.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 663b4af3f..7f1ec730f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "notes", "id": "notes@mozilla.com", "description": "Displays a sidebar that lets you take notes on web pages.", - "version": "1.8.0dev", + "version": "2.0.0dev", "author": "Storage team", "bugs": { "url": "https://github.com/mozilla/notes/issues" diff --git a/src/background.js b/src/background.js index 7d3705447..b8b15b678 100644 --- a/src/background.js +++ b/src/background.js @@ -21,7 +21,7 @@ const analytics = new TestPilotGA({ ds: 'addon', an: 'Notes Experiment', aid: 'notes@mozilla.com', - av: '1.8.0dev' // XXX: Change version on release + av: '2.0.0dev' // XXX: Change version on release }); function sendMetrics(event, context = {}) { diff --git a/src/manifest.json b/src/manifest.json index eed4534f2..180fe05e4 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Firefox Notes", "description": "Displays a sidebar that lets you take notes on web pages.", - "version": "1.8.0dev", + "version": "2.0.0dev", "default_locale": "en_US", "applications": { "gecko": { From b03c9e07ffc480dba794c959168c3828c05d60d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 14:23:52 +0200 Subject: [PATCH 115/125] Upgrade Quill to 1.3.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f1ec730f..48dcc8fa3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "kinto-http": "^4.3.4", "kinto": "^9.0.2", "material-design-lite": "1.3.0", - "quill": "1.2.6", + "quill": "1.3.3", "testpilot-ga": "^0.2.1" }, "devDependencies": { From 5020d2be1b8cbd71ca6671f48c16987437727a43 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Tue, 10 Oct 2017 09:14:39 -0400 Subject: [PATCH 116/125] Document why we put this in here --- src/sync.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sync.js b/src/sync.js index f1ed07496..13145f650 100644 --- a/src/sync.js +++ b/src/sync.js @@ -91,6 +91,9 @@ class JWETransformer { throw new Error('No ciphertext: nothing to decrypt?'); } + // FIXME: this is hack to work around a bug with FxA keys, which + // seem to have timestamps embedded in them that are affected by + // TZ offsets. Take out the substr calls once vladikoff says we can. if (record.kid.substr(15) !== this.key.kid.substr(15)) { if (this.key.kid < record.kid) { throw new ServerKeyNewerError(); From a597663170dda2c9f9853f323a4433691dd6f1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 16:08:15 +0200 Subject: [PATCH 117/125] Fix menu wording. --- locales/en-US/notes.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/en-US/notes.properties b/locales/en-US/notes.properties index 2866a669c..97d75afdf 100644 --- a/locales/en-US/notes.properties +++ b/locales/en-US/notes.properties @@ -4,11 +4,11 @@ welcomeText2=Welcome to this one-page notepad built in to Firefox. Browse the we emptyPlaceHolder=Take a note… giveFeedback=Click here to give us some feedback -feedback = Feedback +feedback = Give Feedback openingLogin=Opening Login… forgetEmail=Forget this Email -disconnected=Disconnected +disconnected=Disable Sync savingChanges=Saving changes… changesSaved=All changes saved From 16207cfb86598321e83e1bab50511a87594c2b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 16:41:08 +0200 Subject: [PATCH 118/125] Upgrade test timeout. --- test/unit/main.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/main.test.js b/test/unit/main.test.js index a9813dde0..23e505511 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -142,6 +142,7 @@ describe('Authorization', function() { }); it('should not fail if syncKinto rejects', () => { + this.timeout(5000); const syncKinto = sandbox.stub(global, 'syncKinto').rejects('server busy playing Minesweeper'); collection.getAny.resolves({data: {last_modified: 'abc', content: 'def'}}); return saveToKinto(client, undefined, 'imaginary content') From 54299d275c0020d26fdef602a44cb0b46eb94b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 10 Oct 2017 16:54:43 +0200 Subject: [PATCH 119/125] Use mocha spec reporter. --- karma.conf.js | 7 +++++-- package.json | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 815e850e1..f46773cc4 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,4 +1,4 @@ -const reporters = ["mocha", "coverage"]; +const reporters = ["spec", "coverage"]; if (process.env.COVERALLS_REPO_TOKEN) { reporters.push("coveralls"); } @@ -9,6 +9,9 @@ module.exports = function(config) { browsers: ["Firefox"], frameworks: ["mocha"], reporters, + specReporter: { + showSpecTiming: true + }, coverageReporter: { dir: "build/coverage", reporters: [ @@ -38,7 +41,7 @@ module.exports = function(config) { "karma-coverage", "karma-firefox-launcher", "karma-mocha", - "karma-mocha-reporter" + "karma-spec-reporter" ] }); }; diff --git a/package.json b/package.json index 48dcc8fa3..a2652b4cf 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "karma-coveralls": "^1.1.2", "karma-firefox-launcher": "^1.0.1", "karma-mocha": "^1.3.0", - "karma-mocha-reporter": "^2.2.4", + "karma-spec-reporter": "0.0.31", "mocha": "^3.2.0", "npm-run-all": "^4.0.2", "pontoon-to-webext": "^1.0.2", From 865b9475c203f5cbda21ecb4db2d36eb0dcdd322 Mon Sep 17 00:00:00 2001 From: vladikoff Date: Tue, 10 Oct 2017 11:59:55 -0400 Subject: [PATCH 120/125] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99a3b92e0..caf1d386b 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Firefox Notes localization is managed via [Pontoon](https://pontoon.mozilla.org/ [Quill Rich Text Editor License](https://github.com/quilljs/quill/blob/develop/LICENSE) -## Other +## Design Design for reference https://mozilla.invisionapp.com/share/6VBUYHMRB#/235284916_Desktop_Sidebar From a0fc8fba38456e8cd051b4c26110a88b952d1fef Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Tue, 10 Oct 2017 14:51:22 -0400 Subject: [PATCH 121/125] Use mocha reporter Revert "Use mocha spec reporter.", moving from the karma spec reporter back to the karma mocha reporter, just because it seems better supported and is part of the example-webextension standard we're trying to follow. Try to achieve the same effect using the built-in Karma option reportSlowerThan -- set it to a generous 40ms. This reverts commit 54299d275c0020d26fdef602a44cb0b46eb94b3f. --- karma.conf.js | 8 +++----- package.json | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index f46773cc4..e9d07174e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,4 +1,4 @@ -const reporters = ["spec", "coverage"]; +const reporters = ["mocha", "coverage"]; if (process.env.COVERALLS_REPO_TOKEN) { reporters.push("coveralls"); } @@ -9,9 +9,7 @@ module.exports = function(config) { browsers: ["Firefox"], frameworks: ["mocha"], reporters, - specReporter: { - showSpecTiming: true - }, + reportSlowerThan: 40, coverageReporter: { dir: "build/coverage", reporters: [ @@ -41,7 +39,7 @@ module.exports = function(config) { "karma-coverage", "karma-firefox-launcher", "karma-mocha", - "karma-spec-reporter" + "karma-mocha-reporter" ] }); }; diff --git a/package.json b/package.json index a2652b4cf..48dcc8fa3 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "karma-coveralls": "^1.1.2", "karma-firefox-launcher": "^1.0.1", "karma-mocha": "^1.3.0", - "karma-spec-reporter": "0.0.31", + "karma-mocha-reporter": "^2.2.4", "mocha": "^3.2.0", "npm-run-all": "^4.0.2", "pontoon-to-webext": "^1.0.2", From 38f06432b86069038afc84b4dca9751eb2eb38e7 Mon Sep 17 00:00:00 2001 From: vladikoff Date: Tue, 10 Oct 2017 18:34:18 -0400 Subject: [PATCH 122/125] BREAKING CHANGE: change servers to oauth-scoped-keys-oct10.dev.lcip.org --- package.json | 2 +- src/background.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 48dcc8fa3..5a07acada 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/mozilla/notes/issues" }, "dependencies": { - "fxa-crypto-relier": "1.0.1", + "fxa-crypto-relier": "1.0.2", "jose-jwe-jws": "^0.1.5", "kinto-http": "^4.3.4", "kinto": "^9.0.2", diff --git a/src/background.js b/src/background.js index b8b15b678..b516fa09c 100644 --- a/src/background.js +++ b/src/background.js @@ -6,7 +6,7 @@ const TRACKING_ID = 'UA-35433268-79'; const KINTO_SERVER = 'https://kinto.dev.mozaws.net/v1'; // XXX: Read this from Kinto fxa-params const FXA_CLIENT_ID = 'c6d74070a481bc10'; -const FXA_OAUTH_SERVER = 'https://oauth-scoped-keys.dev.lcip.org/v1'; +const FXA_OAUTH_SERVER = 'https://oauth-scoped-keys-oct10.dev.lcip.org/v1'; const timeouts = {}; @@ -48,13 +48,14 @@ function sendMetrics(event, context = {}) { } function authenticate() { - const fxaKeysUtil = new fxaCryptoRelier.OAuthUtils(); + const fxaKeysUtil = new fxaCryptoRelier.OAuthUtils({ + oauthServer: FXA_OAUTH_SERVER + }); chrome.runtime.sendMessage({ action: 'sync-opening' }); fxaKeysUtil.launchFxaScopedKeyFlow({ client_id: FXA_CLIENT_ID, - oauth_uri: FXA_OAUTH_SERVER, pkce: true, redirect_uri: browser.identity.getRedirectURL(), scopes: ['profile', 'https://identity.mozilla.org/apps/notes'], From 15a4445a9af58357e15832ce926903672e1da4a6 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Wed, 11 Oct 2017 14:30:23 -0400 Subject: [PATCH 123/125] Failing test demonstrating how conflicts should be handled --- src/sync.js | 4 +-- test/unit/main.test.js | 82 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/sync.js b/src/sync.js index 13145f650..90fd8ead1 100644 --- a/src/sync.js +++ b/src/sync.js @@ -182,13 +182,13 @@ function syncKinto(client, credentials) { }) .sync({ headers: { Authorization: `Bearer ${credential.access_token}` }, - // FIXME: Handle conflicts - strategy: 'server_wins', + strategy: 'manual', }); }) .then(syncResult => { // FIXME: conflicts would happen here. // Do we need to do anything with errors, published, updated, etc.? + console.log('sync result', syncResult); return syncResult; }) .catch(error => { diff --git a/test/unit/main.test.js b/test/unit/main.test.js index 23e505511..0f17d4da0 100644 --- a/test/unit/main.test.js +++ b/test/unit/main.test.js @@ -9,6 +9,14 @@ chai.use(chaiAsPromised); // Many of these are "functional" tests that are run using Karma, and // so "unit" tests from the browser perspective (not including browser interaction). describe('Authorization', function() { + const promiseCredential = Promise.resolve({ + key: { + kid: "20171005", + kty: "kty", + }, + access_token: "access_token" + }); + let sandbox; beforeEach(function() { sandbox = sinon.sandbox.create(); @@ -24,13 +32,6 @@ describe('Authorization', function() { }); describe('401s', function() { - const promiseCredential = Promise.resolve({ - key: { - kid: 20171005, - kty: "kty", - }, - access_token: "access_token" - }); const client = new Kinto(); let credentials; @@ -46,9 +47,7 @@ describe('Authorization', function() { }; }); - afterEach(function() { - fetchMock.reset(); - }); + afterEach(fetchMock.restore); it('should respond to 401s by deleting the token', function() { return syncKinto(client, credentials).then(() => { @@ -89,6 +88,69 @@ describe('Authorization', function() { }); }); + describe('syncKinto', function() { + let client, collection, credentials; + beforeEach(() => { + // We don't try to cover every single scenario where a conflict + // is possible, since kinto.js already has a set of tests for + // that. Instead, we just cover the easiest possible scenario + // that generates a conflict (pulling the same record ID from + // the server) and assume that kinto.js will treat other + // conflicts comparably. + fetchMock.mock('end:/v1/', { + settings: { + batch_max_requests: 25, + readonly: false + } + }); + + fetchMock.mock(new RegExp('/v1/buckets/default/collections/notes/records\\?_sort=-last_modified$'), { + data: [{ + id: "singleNote", + content: "encrypted content", + kid: "20171005", + last_modified: 1234, + }] + }); + + sandbox.stub(global, 'decrypt').resolves({ + id: "singleNote", + content: {ops: [{insert: "Hi there"}]}, + }); + + // sync() tries to gather local changes, even when a conflict + // has already been detected. + sandbox.stub(global, 'encrypt').resolves("encrypted local"); + + credentials = { + get: sinon.mock().returns(promiseCredential), + clear: sinon.mock() + }; + + client = new Kinto({remote: 'https://example.com/v1', bucket: 'default'}); + collection = client.collection('notes', { + idSchema: notesIdSchema + }); + return collection.upsert({id: "singleNote", content: {ops: [{insert: "Local"}]}}); + }); + + afterEach(fetchMock.restore); + + it('should handle a conflict', () => { + return syncKinto(client, credentials) + .then(() => collection.getAny('singleNote')) + .then(result => { + chai.expect(result.data.content).eql( + {ops: [ + {insert: "Hi there"}, + {insert: "\n====== On this computer: ======\n\n"}, + {insert: "Local"}, + ]} + ); + }); + }); + }); + describe('loadKinto', function() { let collection, client; beforeEach(() => { From 37e04704a960a6c96399f8be9379f2c9a2126e44 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Wed, 11 Oct 2017 14:38:58 -0400 Subject: [PATCH 124/125] Handle conflicts --- src/sync.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/sync.js b/src/sync.js index 90fd8ead1..0c846e170 100644 --- a/src/sync.js +++ b/src/sync.js @@ -168,28 +168,39 @@ class BrowserStorageCredentials extends Credentials { */ function syncKinto(client, credentials) { // Get credentials and lastmodified - let credential; + let collection, credential; return credentials.get() .then(received => { credential = received; // XXX: Ask for an refresh token // Query Kinto with the Bearer Token if (!received) return; - return client + collection = client .collection('notes', { idSchema: notesIdSchema, remoteTransformers: [new JWETransformer(credential.key)], - }) + }); + return collection .sync({ headers: { Authorization: `Bearer ${credential.access_token}` }, strategy: 'manual', }); }) .then(syncResult => { - // FIXME: conflicts would happen here. - // Do we need to do anything with errors, published, updated, etc.? - console.log('sync result', syncResult); - return syncResult; + // FIXME: Do we need to do anything with errors, published, + // updated, etc.? + return Promise.all(syncResult.conflicts.map(conflict => { + console.log(conflict); + let totalOps = conflict.remote.content.ops.slice(); + totalOps.push({ insert: '\n====== On this computer: ======\n\n' }); + totalOps = totalOps.concat(conflict.local.content.ops); + const resolution = { + id: conflict.remote.id, + content: {ops: totalOps}, + }; + return collection.resolve(conflict, resolution); + })); + // FIXME: Maybe sync again to "push" the resolution? }) .catch(error => { if (error.response && error.response.status === 401) { From deda4782a5d667b466df0a4543228fffc9047131 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Thu, 12 Oct 2017 11:28:10 -0400 Subject: [PATCH 125/125] No longer need to hack around tz offset bug --- src/sync.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sync.js b/src/sync.js index 0c846e170..b37070387 100644 --- a/src/sync.js +++ b/src/sync.js @@ -91,10 +91,7 @@ class JWETransformer { throw new Error('No ciphertext: nothing to decrypt?'); } - // FIXME: this is hack to work around a bug with FxA keys, which - // seem to have timestamps embedded in them that are affected by - // TZ offsets. Take out the substr calls once vladikoff says we can. - if (record.kid.substr(15) !== this.key.kid.substr(15)) { + if (record.kid !== this.key.kid) { if (this.key.kid < record.kid) { throw new ServerKeyNewerError(); } else {