├── README.md ├── _locales ├── cs │ └── messages.json ├── de │ └── messages.json ├── en │ └── messages.json ├── es │ └── messages.json ├── fr │ └── messages.json ├── hr │ └── messages.json ├── hu │ └── messages.json ├── it │ └── messages.json ├── ja │ └── messages.json ├── ko │ └── messages.json ├── pl │ └── messages.json ├── pt_BR │ └── messages.json ├── pt_PT │ └── messages.json ├── ru │ └── messages.json ├── zh │ └── messages.json └── zh_TW │ └── messages.json ├── advanced-options.html ├── background.html ├── codemirror.css ├── codemirror.js ├── document-code.png ├── folder.png ├── icon-2.png ├── icon-3.png ├── icon.png ├── icon128.png ├── icon16.png ├── icon32.png ├── icon48.png ├── license.txt ├── manifest.json ├── neat-bookmarks-header-bg.png ├── neat-bookmarks-options-screenshot.png ├── neat-bookmarks-promo-large.png ├── neat-bookmarks-promo-small.png ├── neat-bookmarks-screenshot.png ├── neat.css ├── neat.js ├── neat.xar ├── neatools.js ├── omni-icon.png ├── options.css ├── options.html └── popup.html /README.md: -------------------------------------------------------------------------------- 1 | **Notice: Neat Bookmarks has been sold and I'm no longer the owner of the extension.** 2 | 3 | Try [Neater Bookmarks](https://chrome.google.com/webstore/detail/neater-bookmarks/ofgjggbjanlhbgaemjbkiegeebmccifi/) instead. 4 | 5 | Neat Bookmarks 6 | ============== 7 | 8 | A neat bookmarks tree popup extension for Google Chrome. Licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php). 9 | 10 | Read the [FAQ](https://github.com/cheeaun/neat-bookmarks/wiki/FAQ). 11 | 12 | Technical Details 13 | ----------------- 14 | 15 | Neat Bookmarks was powered by [MooTools](http://mootools.net/), but is now powered by Neatools, a custom-coded smaller subset of MooTools. [CodeMirror](http://codemirror.net/) is used for the Custom CSS section. -------------------------------------------------------------------------------- /_locales/cs/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Ani nápad" 4 | }, 5 | "name": { 6 | "description": "Jméno adresáře se záložkami.", 7 | "message": "Jméno" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Otevřít všechny záložky v anonymním okně" 11 | }, 12 | "reportError": { 13 | "message": "Nahlásit chybu" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Chcete smazat adresář $folderName$, $subFolderCount$ podadresářů a $bookmarkCount$ záložek v nich?" 28 | }, 29 | "extName": { 30 | "description": "Jméno rozšíření.", 31 | "message": "Elegantní záložky" 32 | }, 33 | "noTitle": { 34 | "description": "Titulek pro nepojmenované záložky bez http(s) adresy nebo nepojmenované adresáře.", 35 | "message": "(bez titulku)" 36 | }, 37 | "edit": { 38 | "message": "Upravit..." 39 | }, 40 | "open": { 41 | "description": "Akce pro otevření záložek.", 42 | "message": "Otevřít" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Text rezervující místo pro pole vyhledávání.", 46 | "message": "Prohledat záložky" 47 | }, 48 | "delete": { 49 | "message": "Smazat" 50 | }, 51 | "editBookmark": { 52 | "message": "Upravit záložku" 53 | }, 54 | "openNewTab": { 55 | "message": "Otevřít v nové kartě" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Zobrazovat dotaz při otevírání mnoha záložek." 59 | }, 60 | "editFolder": { 61 | "message": "Upravit adresář" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Lišta záložek", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Zobrazení informací o nadřazeném adresáři v bublině ve výsledcích hledání.", 71 | "message": "Nadřazený adresář: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Potvrzení otevření všech záložek v novém anonymním okně.", 80 | "message": "Chcete otevřít všech $count$ záložek záložek v novém anonymním okně?" 81 | }, 82 | "url": { 83 | "message": "Adresa" 84 | }, 85 | "errorOccured": { 86 | "message": "Nastala nějaká chyba." 87 | }, 88 | "optionPopupStays": { 89 | "message": "Vyskakovací okno zůstává otevřené při otevírání záložek levým tlačítkem." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Při otevírání adresáře ostatní zavřít." 93 | }, 94 | "accessibility": { 95 | "message": "Přístupnost" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Smazat..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Chcete smazat adresář $folderName$ a $bookmarkCount$ záložek v něm?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Pokročilé nastavení" 113 | }, 114 | "extDesc": { 115 | "description": "Popis rozšíření.", 116 | "message": "Elegantní vyskakovací okno se záložkami." 117 | }, 118 | "save": { 119 | "message": "Uložit" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Potvrzení otevření všech záložek v novém okně.", 128 | "message": "Chcete otevřít všech $count$ záložek záložek v novém okně?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Potvrzení otevření všech záložek.", 137 | "message": "Chcete otevřít všech $count$ záložek?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Otevřít všechny záložky" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Pamatovat předchozí stav (posun a otevřené adresáře)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Patička stránky s nastavením", 152 | "message": "Vytvořil $authorName$." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Otevřít všechny záložky v novém okně" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Kliknutí prostředním tlačítkem, nebo s přidržením klávesy Ctrl otevře záložku v kartě na pozadí (místo otevření karty v popředí)." 159 | }, 160 | "ignore": { 161 | "message": "Ignorovat" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Otevřít anonymní okno" 165 | }, 166 | "general": { 167 | "message": "Obecné" 168 | }, 169 | "openNewWindow": { 170 | "message": "Otevřít v novém okně" 171 | }, 172 | "optionZoom": { 173 | "message": "Zvětšení" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Kliknutí levým tlačítkem otevře záložku v nové kartě." 177 | }, 178 | "options": { 179 | "message": "Nastavení" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Chcete smazat adresář $folderName$ a $subFolderCount$ podadresářů v něm?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/de/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Nein" 4 | }, 5 | "name": { 6 | "description": "Der Name des Lesezeichen oder des Ordners.", 7 | "message": "Name" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Alle Lesezeichen in einem Incognito-Fenster öffnen" 11 | }, 12 | "reportError": { 13 | "message": "Ein Fehler melden" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Möchten Sie wirklich den gesamten $folderName$ Ordner, $subFolderCount$ Unterordner und $bookmarkCount$ Lesezeichen löschen?" 28 | }, 29 | "extName": { 30 | "description": "Der Name der Erweiterung.", 31 | "message": "Neat Bookmarks" 32 | }, 33 | "noTitle": { 34 | "description": "Lesezeichen oder Ordner ohne Namen oder Adresse.", 35 | "message": "(kein Name)" 36 | }, 37 | "edit": { 38 | "message": "Bearbeiten..." 39 | }, 40 | "open": { 41 | "description": "Aktion um Lesezeichen zu öffnen.", 42 | "message": "Öffnen" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Suchen", 46 | "message": "Lesezeichen suchen" 47 | }, 48 | "delete": { 49 | "message": "Löschen" 50 | }, 51 | "editBookmark": { 52 | "message": "Lesezeichen bearbeiten" 53 | }, 54 | "openNewTab": { 55 | "message": "Einen neuen Tab öffnen" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Sie öffnen nun sehr viele Lesezeichen von diesem Ordner." 59 | }, 60 | "editFolder": { 61 | "message": "Ordner bearbeiten" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Lesezeichen-Leiste", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Tooltip- Informationen zu den Lesezeichen des übergeordneter Ordners.", 71 | "message": "Übergeordneter Ordner: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Sie haben alle Lesezeichen in einem neuen Incognito-Fenster geöffnet.", 80 | "message": "Möchten Sie wirklich alle Lesezeichen in einem neuen Incognito-Fenster öffnen?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "errorOccured": { 86 | "message": "Upps, es ist ein Fehler aufgetreten." 87 | }, 88 | "optionPopupStays": { 89 | "message": "Das Pop-Up bleibt - beim Öffnen der Lesezeichen mit einem Links-Klick - geöffnet." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Schließe nicht genutzte Ordner beim Öffnen des Ordners." 93 | }, 94 | "accessibility": { 95 | "message": "Erreichbarkeit" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Löschen..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Möchten Sie wirklich den gesamten $folderName$ Ordner mit $bookmarkCount$ Lesezeichen löschen?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Erweiterte Einstellungen" 113 | }, 114 | "extDesc": { 115 | "description": "Die Beschreibung der Erweiterung.", 116 | "message": "Ein Neat Bookmarks Pop-Up." 117 | }, 118 | "save": { 119 | "message": "Speichern" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Sie haben alle Lesezeichen in einem neuen Fenster geöffnet.", 128 | "message": "Möchten Sie wirklich alle $count$ Lesezeichen in einem neuen Fenster öffnen?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Sie haben alle Lesezeichen geöffnet.", 137 | "message": "Möchten Sie wirklich alle $count$ Lesezeichen öffnen?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Alle Lesezeichen öffnen" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Behalte vorherigen Status (Scroll-Position und geöffnete Lesezeichen)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Hier können Sie Ihre Einstellungen vornehmen.", 152 | "message": "Von zsdr erstellt." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Alle Lesezeichen in einem neuen Fenster öffnen" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Mitte-Klick oder STRG+Klick öffnet das Lesezeichen in einen neuen Hintergrund-Tab (anstatt im Vordergrund)." 159 | }, 160 | "ignore": { 161 | "message": "Ignorieren" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Incognito-Fenster öffnen" 165 | }, 166 | "general": { 167 | "message": "Generell" 168 | }, 169 | "openNewWindow": { 170 | "message": "Ein neues Fenster öffnen" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoom" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Links-Klick öffnet Lesezeichen in einem neuen Tab." 177 | }, 178 | "options": { 179 | "message": "Einstellungen" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Möchten Sie wirklich den gesamten $folderName$ Ordner mit $subFolderCount$ Unterordnern löschen?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extName": { 3 | "message": "Neat Bookmarks", 4 | "description": "The extension name." 5 | }, 6 | "extDesc": { 7 | "message": "A neat bookmarks tree popup.", 8 | "description": "The extension description." 9 | }, 10 | "searchBookmarks": { 11 | "message": "Search Bookmarks", 12 | "description": "Placeholder text for search field." 13 | }, 14 | "openNewTab": { 15 | "message": "Open in New Tab" 16 | }, 17 | "openNewWindow": { 18 | "message": "Open in New Window" 19 | }, 20 | "openIncognitoWindow": { 21 | "message": "Open in Incognito Window" 22 | }, 23 | "edit": { 24 | "message": "Edit..." 25 | }, 26 | "delete": { 27 | "message": "Delete" 28 | }, 29 | "deleteEllipsis": { 30 | "message": "Delete..." 31 | }, 32 | "openBookmarks": { 33 | "message": "Open All Bookmarks" 34 | }, 35 | "openBookmarksNewWindow": { 36 | "message": "Open All Bookmarks in New Window" 37 | }, 38 | "openBookmarksIncognitoWindow": { 39 | "message": "Open All Bookmarks in Incognito Window" 40 | }, 41 | "noTitle": { 42 | "message": "(no title)", 43 | "description": "The title for untitled bookmarks with no http(s) URL or untitled folders." 44 | }, 45 | "parentFolder": { 46 | "message": "Parent folder: \"$folderName$\"", 47 | "description": "Parent folder information displayed in the tooltip of bookmarks in search results list.", 48 | "placeholders": { 49 | "folderName": { 50 | "content": "$1", 51 | "example": "Bookmarks bar" 52 | } 53 | } 54 | }, 55 | "confirmOpenBookmarks": { 56 | "message": "Are you sure you want to open all $count$ bookmarks?", 57 | "description": "Confirmation message for opening all bookmarks.", 58 | "placeholders": { 59 | "count": { 60 | "content": "$1" 61 | } 62 | } 63 | }, 64 | "confirmOpenBookmarksNewWindow": { 65 | "message": "Are you sure you want to open all $count$ bookmarks in a new window?", 66 | "description": "Confirmation message for opening all bookmarks in a new window.", 67 | "placeholders": { 68 | "count": { 69 | "content": "$1" 70 | } 71 | } 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "message": "Are you sure you want to open all $count$ bookmarks in a new incognito window?", 75 | "description": "Confirmation message for opening all bookmarks in a new incognito window.", 76 | "placeholders": { 77 | "count": { 78 | "content": "$1" 79 | } 80 | } 81 | }, 82 | "confirmDeleteFolderSubfoldersBookmarks": { 83 | "message": "Are you sure you want to delete $folderName$ folder, $subFolderCount$ sub-folder(s) and $bookmarkCount$ bookmark(s) in it?", 84 | "placeholders": { 85 | "folderName": { 86 | "content": "$1" 87 | }, 88 | "subFolderCount": { 89 | "content": "$2" 90 | }, 91 | "bookmarkCount": { 92 | "content": "$3" 93 | } 94 | } 95 | }, 96 | "confirmDeleteFolderBookmarks": { 97 | "message": "Are you sure you want to delete $folderName$ folder and $bookmarkCount$ bookmark(s) in it?", 98 | "placeholders": { 99 | "folderName": { 100 | "content": "$1" 101 | }, 102 | "bookmarkCount": { 103 | "content": "$2" 104 | } 105 | } 106 | }, 107 | "confirmDeleteFolderSubfolders": { 108 | "message": "Are you sure you want to delete $folderName$ folder and $subFolderCount$ sub-folder(s) in it?", 109 | "placeholders": { 110 | "folderName": { 111 | "content": "$1" 112 | }, 113 | "subFolderCount": { 114 | "content": "$2" 115 | } 116 | } 117 | }, 118 | "open": { 119 | "message": "Open", 120 | "description": "Action to open bookmarks." 121 | }, 122 | "nope": { 123 | "message": "Nope" 124 | }, 125 | "editBookmark": { 126 | "message": "Edit bookmark" 127 | }, 128 | "editFolder": { 129 | "message": "Edit folder" 130 | }, 131 | "save": { 132 | "message": "Save" 133 | }, 134 | "name": { 135 | "message": "Name", 136 | "description": "Name of bookmark or folder." 137 | }, 138 | "url": { 139 | "message": "URL" 140 | }, 141 | "errorOccured": { 142 | "message": "Oops, an error occured." 143 | }, 144 | "reportedToDeveloper": { 145 | "message": "This has been reported to the developer.", 146 | "description": "A message for an error occured in the extension, has been reported to the developer." 147 | }, 148 | "reportError": { 149 | "message": "Report Error" 150 | }, 151 | "ignore": { 152 | "message": "Ignore" 153 | }, 154 | "options": { 155 | "message": "Options" 156 | }, 157 | "advancedOptions": { 158 | "message": "Advanced Options" 159 | }, 160 | "general": { 161 | "message": "General" 162 | }, 163 | "accessibility": { 164 | "message": "Accessibility" 165 | }, 166 | "optionClickNewTab": { 167 | "message": "Left-click opens bookmark in new tab." 168 | }, 169 | "optionOpenNewTab": { 170 | "message": "Middle-click or control-click opens bookmark in new background tab (instead of foreground)." 171 | }, 172 | "optionCloseUnusedFolders": { 173 | "message": "Close unused folders when opening a folder." 174 | }, 175 | "optionPopupStays": { 176 | "message": "Popup stays open when opening (left-clicking) bookmarks." 177 | }, 178 | "optionConfirmOpenFolder": { 179 | "message": "Display confirmation when opening a lot of bookmarks from a folder." 180 | }, 181 | "optionRememberPrevState": { 182 | "message": "Remember previous state (scroll position and opened folders)." 183 | }, 184 | "optionZoom": { 185 | "message": "Zoom" 186 | }, 187 | "optionsFooterText": { 188 | "message": "Built by $authorName$.", 189 | "description": "Footer text for the Options page", 190 | "placeholders": { 191 | "authorName": { 192 | "content": "$1" 193 | } 194 | } 195 | } 196 | } -------------------------------------------------------------------------------- /_locales/es/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "¡No!" 4 | }, 5 | "name": { 6 | "description": "Nombre de marcador o de carpeta.", 7 | "message": "Nombre" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Abrir todos los marcadores en ventana de incógnito" 11 | }, 12 | "reportError": { 13 | "message": "Informar de este error" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "¿Está seguro de que quiere eliminar la carpeta $folderName$, $subFolderCount$ subcarpeta(s) y $bookmarkCount$ marcador(es) almacenados en ésta?" 28 | }, 29 | "extName": { 30 | "description": "Nombre de la extensión.", 31 | "message": "Neat Bookmarks" 32 | }, 33 | "noTitle": { 34 | "description": "Título para marcadores sin título con URL sin http(s) o carpetas sin título.", 35 | "message": "(sin título)" 36 | }, 37 | "edit": { 38 | "message": "Editar..." 39 | }, 40 | "open": { 41 | "description": "Acción al abrir marcadores.", 42 | "message": "Abrir" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Texto contenedor del campo de búsqueda.", 46 | "message": "Buscar marcadores" 47 | }, 48 | "delete": { 49 | "message": "Eliminar" 50 | }, 51 | "editBookmark": { 52 | "message": "Editar marcador" 53 | }, 54 | "openNewTab": { 55 | "message": "Abrir en una nueva pestaña" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Mostrar confirmación al abrir varios marcadores de una carpeta." 59 | }, 60 | "editFolder": { 61 | "message": "Editar carpeta" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Barra de marcadores", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Información de la carpeta superior mostrada en la descripción del marcador en la lista de resultados de búsqueda.", 71 | "message": "Carpeta superior: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Mensaje de confirmación para abrir todos los marcadores en una nueva ventana de incógnito.", 80 | "message": "¿Está seguro de que quiere abrir $count$ marcadores en una nueva ventana de incógnito?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "errorOccured": { 86 | "message": "Ups, ha ocurrido un error." 87 | }, 88 | "optionPopupStays": { 89 | "message": "El pop-up se mantiene abierto al abrir (con click izquierdo) los marcadores." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Cerrar carpetas inactivas al abrir una carpeta." 93 | }, 94 | "accessibility": { 95 | "message": "Accesibilidad" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Eliminar..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "¿Está seguro de que quiere eliminar la carpeta $folderName$ y $bookmarkCount$ marcador(es) almacenado(s) en ésta?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Opciones Avanzadas" 113 | }, 114 | "extDesc": { 115 | "description": "Descripción de la extensión.", 116 | "message": "Un pop-up de marcadores en forma de árbol." 117 | }, 118 | "save": { 119 | "message": "Guardar" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Mensaje de confirmación para abrir todos los marcadores en una nueva ventana.", 128 | "message": "¿Está seguro de que quiere abrir $count$ marcadores en una nueva ventana?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Mensaje de confirmación para abrir todos los marcadores.", 137 | "message": "¿Está seguro de que quiere abrir $count$ marcadores?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Abrir todos los marcadores" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Recordar estado previo (posición de la barra de desplazamiento y carpetas abiertas)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Texto de pie para la página Opciones", 152 | "message": "Escrito por $authorName$." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Abrir todos los marcadores en una nueva ventana" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Botón central del ratón o control-clic abre el marcador en segundo plano (en lugar de en primer plano)." 159 | }, 160 | "ignore": { 161 | "message": "Ignorar" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Abrir en una ventana de incógnito" 165 | }, 166 | "general": { 167 | "message": "General" 168 | }, 169 | "openNewWindow": { 170 | "message": "Abrir en una nueva ventana" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoom" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Clic izquierdo abre el marcador en una nueva pestaña." 177 | }, 178 | "options": { 179 | "message": "Opciones" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "¿Está seguro de que quiere eliminar la carpeta $folderName$ y $subFolderCount$ subcarpeta(s) almacenado(s) en ésta?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/fr/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Non" 4 | }, 5 | "name": { 6 | "description": "Nom du signet ou du dossier.", 7 | "message": "Nom" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Ouvrir tous les signets dans une nouvelle fenêtre incognito" 11 | }, 12 | "reportError": { 13 | "message": "Signaler l’erreur" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Êtes-vous certain de bien vouloir supprimer le répertoire $folderName$, $subFolderCount$ sous-répertoire(s) et $bookmarkCount$ signets les contenant?" 28 | }, 29 | "extName": { 30 | "description": "Le nom de l’extension.", 31 | "message": "Neat Bookmarks" 32 | }, 33 | "noTitle": { 34 | "description": "Le titre donné aux répertoires ou signets sans noms.", 35 | "message": "(Sans titre)" 36 | }, 37 | "edit": { 38 | "message": "Éditer..." 39 | }, 40 | "open": { 41 | "description": "Action pour ouvrir les signets.", 42 | "message": "Ouvrir" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Texte d’information du champ de recherche.", 46 | "message": "Rechercher Signets" 47 | }, 48 | "delete": { 49 | "message": "Supprimer" 50 | }, 51 | "editBookmark": { 52 | "message": "Éditer le signet" 53 | }, 54 | "openNewTab": { 55 | "message": "Ouvrir dans un nouvel onglet" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Afficher un message de confirmation lors de l’ouverture de beaucoup de signets d’un dossier." 59 | }, 60 | "editFolder": { 61 | "message": "Éditer le répertoire" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Barre de favoris", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "L’information des répertoires parents est affichée dans l’infobulle des signets dans la liste des résultats.", 71 | "message": "Répertoire parent: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Message de confirmation pour ouvrir tous les signets dans une nouvelle fenêtre de navigation incognito.", 80 | "message": "Etes-vous certain de bien vouloir ouvrir tous les $count$ signets dans une nouvelle fenêtre incognito?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "errorOccured": { 86 | "message": "Oups, une erreur s'est produite." 87 | }, 88 | "optionPopupStays": { 89 | "message": "La popup reste ouverte lors de l'ouverture (clic gauche) de signets." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Fermer les répertoires non utilisés lors de l'ouverture d’un répertoire." 93 | }, 94 | "accessibility": { 95 | "message": "Accessibilité" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Supprimer..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Êtes-vous certain de bien vouloir supprimer le répertoire $folderName$ et $bookmarkCount$ signet(s) les contenant?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Options Avancées" 113 | }, 114 | "extDesc": { 115 | "description": "La description de l’extension.", 116 | "message": "Un extention pratique pour gérer ses signets." 117 | }, 118 | "save": { 119 | "message": "Enregistrer" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Message de confirmation pour ouvrir tous les signets dans une nouvelle fenêtre de navigation.", 128 | "message": "Etes-vous certain de bien vouloir ouvrir tous les $count$ signets dans une nouvelle fenêtre?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Message de confirmation pour ouvrir tous les signets.", 137 | "message": "Etes-vous certain de bien vouloir ouvrir tous les $count$ signets?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Ouvrir tous les signets" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Se rappeler de l’état précédent (position dans la page et répertoires ouverts)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Texte du pied de la page Options", 152 | "message": "Créé par $authorName$." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Ouvrir tous les signets dans une nouvelle fenêtre" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Clic milieu ou Ctrl-clic ouvre le signet dans un nouvel onglet en arrière-plan (au lieu d’en premier plan)." 159 | }, 160 | "ignore": { 161 | "message": "Ignorer" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Ouvrir dans une fenêtre incognito" 165 | }, 166 | "general": { 167 | "message": "Général" 168 | }, 169 | "openNewWindow": { 170 | "message": "Ouvrir dans une nouvelle fenêtre" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoom" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Clic gauche ouvre le signet dans un nouvel onglet." 177 | }, 178 | "options": { 179 | "message": "Options" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Êtes-vous certain de bien vouloir supprimer le répertoire $folderName$ et $subFolderCount$ sous-répertoire(s) les contenant?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/hr/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Ne" 4 | }, 5 | "name": { 6 | "description": "Ime oznake ili mape", 7 | "message": "Ime" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Otvori sve oznake u Inkognito prozoru" 11 | }, 12 | "reportError": { 13 | "message": "Prijavi grešku" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Jeste li sigurni da želite obrisati mapu oznaka \"$folderName$\" koja sadrži $subFolderCount$ podmapa/e/u i $bookmarkCount$ zabilješki/e?" 28 | }, 29 | "extName": { 30 | "description": "Ime ekstenzije", 31 | "message": "Praktične oznake" 32 | }, 33 | "noTitle": { 34 | "description": "Naziv za oznaku(bookmark) koji nema URL-a ili ima neimenovanih prozora", 35 | "message": "(neimenovano)" 36 | }, 37 | "edit": { 38 | "message": "Uredi..." 39 | }, 40 | "open": { 41 | "description": "Opcija koja služi za otvaranje oznaka ( bookmarkov-a)", 42 | "message": "Otvori" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Sivi (placeholder) tekst koji se pojavi kada otvorimo NeatBookmarks pored ikone za pretraživanje, uglavnom je odmah u fokusu, tako da trebamo kliknuti na prazan prostor u ekstenziji ili na neku od mapa.", 46 | "message": "Pretraži oznake" 47 | }, 48 | "delete": { 49 | "message": "Obriši" 50 | }, 51 | "editBookmark": { 52 | "message": "Uredi oznaku" 53 | }, 54 | "openNewTab": { 55 | "message": "Otvori u novoj kartici" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Prikaži upozorenje prilikom otvaranja velikog broja oznaka iz mape" 59 | }, 60 | "editFolder": { 61 | "message": "Uredi mapu" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Traka oznaka", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Informacije koje se pojave kada držimo pokazivač miša na oznaci(bookmark-u) u rezultatima pretraživanja a govore nam u kojoj se mapi(folder-u) pronađena oznaka nalazi.", 71 | "message": "Pripada mapi \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Poruka koja se pojavi kada želimo otvoriti sve oznake u novome inkognito prozoru.", 80 | "message": "Jeste li sigurni da želite otvoriti $count$ oznaku/e/a u novom inkognito prozoru ?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "errorOccured": { 86 | "message": "Pojavila se pogreška." 87 | }, 88 | "optionPopupStays": { 89 | "message": "Iskočni prozor ekstenzije će ostati otvoren nakon otvaranja oznake." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Zatvori nekorištene mape kad otvaram novu mapu" 93 | }, 94 | "accessibility": { 95 | "message": "Dostupnost" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Obriši..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Jeste li sigurni da želite obrisati mapu oznaka \"$folderName$\" koja sadrži $bookmarkCount$ zabilježaka/zabilješke ?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Napredne opcije" 113 | }, 114 | "extDesc": { 115 | "description": "Opis ekstenzije (dodatka).", 116 | "message": "Praktičan prikaz oznaka u pop-up prozoru." 117 | }, 118 | "save": { 119 | "message": "Spremi" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Poruka koja se pojavi kada želimo otvoriti sve oznake u novome prozoru.", 128 | "message": "Jeste li sigurni da želite otvoriti $count$ oznaka/e/u u novom prozoru ?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Jeste li sigurni da želite otvoriti sve oznake odjednom ?", 137 | "message": "Jeste li sigurni da želite otvoriti $count$ oznaku/e/a odjednom ?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Otvori sve oznake" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Zapamti prijašnje stanje (poziciju u iskočnom prozoru i mape koje su bile otvorene)" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Tekst na dnu stranice koji se može vidjeti kada pristupimo opcijama(Options)", 152 | "message": "Izradio $authorName$" 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Otvori sve oznake u novom prozoru" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Srednji klik (ili CONTROL+klik ) otvara oznaku u novoj kartici, ali se ne prebacuje automatski na nju." 159 | }, 160 | "ignore": { 161 | "message": "Zanemari" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Otvori u Inkognito prozoru" 165 | }, 166 | "general": { 167 | "message": "Općenito" 168 | }, 169 | "openNewWindow": { 170 | "message": "Otvori u novom prozoru" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoomiranje" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Lijevim klikom otvarate oznaku u novoj kartici" 177 | }, 178 | "options": { 179 | "message": "Mogućnosti/Opcije" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Jeste li sigurni da želite obrisati mapu \"$folderName$\" koja sadrži $subFolderCount$ podmapa/e/u ?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/hu/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Dehogy" 4 | }, 5 | "openBookmarksIncognitoWindow": { 6 | "message": "Összes könyvjelző megnyitása Inkognitó ablakban" 7 | }, 8 | "name": { 9 | "description": "A könyvjelző, vagy mappa neve.", 10 | "message": "Név" 11 | }, 12 | "reportError": { 13 | "message": "Hiba jelentése" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Biztososan ki szeretné törölni a $folderName$ nevű mappát, $subFolderCount$ almappát és $bookmarkCount$ könyvjelzőt benne?" 28 | }, 29 | "noTitle": { 30 | "description": "Cím nélküli könyvjelzők http(s) URL nélkül, vagy cím nélküli mappák.", 31 | "message": "(nincs cím)" 32 | }, 33 | "extName": { 34 | "description": "A bővítmény neve.", 35 | "message": "Neat könyvjelzők." 36 | }, 37 | "edit": { 38 | "message": "Szerkesztés..." 39 | }, 40 | "searchBookmarks": { 41 | "description": "Helykitöltő szöveg a kereső mezőben.", 42 | "message": "Könyvjelzők keresése" 43 | }, 44 | "open": { 45 | "description": "Művelet a könyvjelzők megnyitásához.", 46 | "message": "Megnyitás" 47 | }, 48 | "delete": { 49 | "message": "Törlés" 50 | }, 51 | "editBookmark": { 52 | "message": "Könyvjelző szerkesztése..." 53 | }, 54 | "openNewTab": { 55 | "message": "Megnyitás Új fülön" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Megerősítő üzenet megjelenítése, amikor egyszerre sok könyvjelzőt nyit meg egy mappából." 59 | }, 60 | "editFolder": { 61 | "message": "Mappa szerkesztése" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Könyvjelző sáv", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Könyvjelzőt tartalmazó mappa nevének kijelzése egértipp formájában a keresési eredmény listában.", 71 | "message": "Könyvjelzőt tartalmazó mappa: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Megerősítő üzenet az összes könyvjelző megnyitásához új inkognitó ablakban.", 80 | "message": "Biztosan meg szeretné nyitni az összes $count$ könyvjelzőt egy új inkognitó ablakban?" 81 | }, 82 | "url": { 83 | "message": "Hivatkozás" 84 | }, 85 | "optionPopupStays": { 86 | "message": "A Popup nyitva marad, amikor bal egérgombbal megnyitunk egy könyvjelzőt." 87 | }, 88 | "errorOccured": { 89 | "message": "Hoppá, valami hiba történt." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Nem használt mappák becsukása, amikor egy új mappa nyílik meg." 93 | }, 94 | "accessibility": { 95 | "message": "Megközelíthetőség" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Törlés..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Biztososan ki szeretné törölni a $folderName$ nevű mappát és $bookmarkCount$ könyvjelzőt benne?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Haladó beállítások" 113 | }, 114 | "save": { 115 | "message": "Mentés" 116 | }, 117 | "extDesc": { 118 | "description": "A bővítmény leírása.", 119 | "message": "Egy elegáns popup könyvjelző fa. " 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Megerősítő üzenet az összes könyvjelző megnyitásához egy új ablakban.", 128 | "message": "Biztosan meg szeretné nyitni az összes $count$ könyvjelzőt egy új ablakban?" 129 | }, 130 | "openBookmarks": { 131 | "message": "Összes könyvjelző megnyitása" 132 | }, 133 | "confirmOpenBookmarks": { 134 | "placeholders": { 135 | "count": { 136 | "content": "$1" 137 | } 138 | }, 139 | "description": "Megerősítő üzenet az összes könyvjelző megnyitásához.", 140 | "message": "Biztosan meg szeretné nyitni az összes $count$ könyvjelzőt?" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Előző állapot megjegyzése (görgetés pozíció és megnyitott mappák)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Lábléc szöveg a Beállítások oldalon", 152 | "message": "Készítette: $authorName$." 153 | }, 154 | "optionOpenNewTab": { 155 | "message": "Középső egérgomb, vagy Ctrl+bal egérgomb használatakor egy könyvjelzőt megnyitva a böngésző nem ugrik át az Új fülre (hanem egy marad az aktív fülön). " 156 | }, 157 | "openBookmarksNewWindow": { 158 | "message": "Összes könyvjelző megnyitása Új ablakban" 159 | }, 160 | "openIncognitoWindow": { 161 | "message": "Megnyitás Inkognitó ablakban" 162 | }, 163 | "ignore": { 164 | "message": "Figyelmen kívül hagy" 165 | }, 166 | "openNewWindow": { 167 | "message": "Megnyitás Új ablakban" 168 | }, 169 | "general": { 170 | "message": "Általános" 171 | }, 172 | "optionZoom": { 173 | "message": "Közelítés" 174 | }, 175 | "options": { 176 | "message": "Opciók" 177 | }, 178 | "optionClickNewTab": { 179 | "message": "Könyvjelző megnyitása Új fülön bal egérgombbal." 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Biztososan ki szeretné törölni a $folderName$ nevű mappát és benne $subFolderCount$ almappát?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/it/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "No" 4 | }, 5 | "name": { 6 | "description": "Nome del preferito o della cartella.", 7 | "message": "Nome" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Apri tutti i preferiti in una finestra di navigazione in incognito" 11 | }, 12 | "reportError": { 13 | "message": "Segnala questo errore" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Eliminare la cartella $folderName$, le $subFolderCount$ sottocartelle e i $bookmarkCount$ preferiti contenuti in essa?" 28 | }, 29 | "extName": { 30 | "description": "Nome dell'estensione.", 31 | "message": "Neat Bookmarks" 32 | }, 33 | "noTitle": { 34 | "description": "Nome dei preferiti senza nome non contenente indirizzi Web http(s) o delle cartelle senza nome.", 35 | "message": "(senza nome)" 36 | }, 37 | "edit": { 38 | "message": "Modifica..." 39 | }, 40 | "open": { 41 | "description": "Azione per aprire i preferiti.", 42 | "message": "Apri" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Testo iniziale del campo di ricerca.", 46 | "message": "Cerca preferiti" 47 | }, 48 | "delete": { 49 | "message": "Elimina" 50 | }, 51 | "editBookmark": { 52 | "message": "Modifica preferito" 53 | }, 54 | "openNewTab": { 55 | "message": "Apri in un'altra scheda" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Mostra un messaggio di conferma all'apertura di molti preferiti da una cartella." 59 | }, 60 | "editFolder": { 61 | "message": "Modifica cartella" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Barra dei preferiti", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Informazioni sulla cartella principale visualizzate nel suggerimento dei preferiti nell'elenco dei risultati di ricerca.", 71 | "message": "Cartella principale: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Messaggio di conferma di apertura di tutti i preferiti in una finestra di navigazione in incognito.", 80 | "message": "Aprire tutti i $count$ preferiti in una finestra di navigazione in incognito?" 81 | }, 82 | "url": { 83 | "message": "Indirizzo Web" 84 | }, 85 | "errorOccured": { 86 | "message": "Si è verificato un errore." 87 | }, 88 | "optionPopupStays": { 89 | "message": "Non chiudere la finestra di Neat Bookmarks quando si aprono i preferiti (clic con il pulsante sinistro del mouse)." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "All'apertura di una cartella, chiudi tutte le altre." 93 | }, 94 | "accessibility": { 95 | "message": "Accessibilità" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Elimina..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Eliminare la cartella $folderName$ e i $bookmarkCount$ preferiti contenuti in essa?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Opzioni avanzate" 113 | }, 114 | "extDesc": { 115 | "description": "Descrizione dell'estensione.", 116 | "message": "Una pratica estensione per la gestione dei preferiti." 117 | }, 118 | "save": { 119 | "message": "Salva" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Messaggio di conferma di apertura di tutti i preferiti in un'altra finestra.", 128 | "message": "Aprire tutti i $count$ preferiti in un'altra finestra?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Messaggio di conferma di apertura di tutti i preferiti.", 137 | "message": "Aprire tutti i $count$ preferiti?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Apri tutti i preferiti" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Memorizza lo stato della finestra di Neat Bookmarks (posizione di scorrimento dell'elenco e cartelle aperte)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Testo in basso alla pagina Opzioni", 152 | "message": "Creato da $authorName$." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Apri tutti i preferiti in un'altra finestra" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Fai clic con il pulsante centrale del mouse o con il pulsante sinistro tenendo premuto il tasto Ctrl per aprire i preferiti in un'altra scheda in secondo piano (anziché in primo piano)." 159 | }, 160 | "ignore": { 161 | "message": "Ignora" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Apri in una finestra di navigazione in incognito" 165 | }, 166 | "general": { 167 | "message": "Generale" 168 | }, 169 | "openNewWindow": { 170 | "message": "Apri in un'altra finestra" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoom" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Apri i preferiti in un'altra finestra quando si fa clic con il pulsante sinistro del mouse su di essi." 177 | }, 178 | "options": { 179 | "message": "Opzioni" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Eliminare la cartella $folderName$ e le $subFolderCount$ sottocartelle contenute in essa?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/ja/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "いいえ" 4 | }, 5 | "name": { 6 | "description": "ブックマークとフォルダの名前", 7 | "message": "名前" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "すべてのブックマークをシークレットウィンドウで開く" 11 | }, 12 | "reportError": { 13 | "message": "エラーレポート" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "$folderName$ フォルダと $subFolderCount$ 個のサブフォルダと $bookmarkCount$ 個のブックマークを削除します。よろしいですか。" 28 | }, 29 | "extName": { 30 | "description": "拡張名", 31 | "message": "Neat Bookmarks" 32 | }, 33 | "noTitle": { 34 | "description": "名前の無いブックマークのための名前", 35 | "message": "無題" 36 | }, 37 | "edit": { 38 | "message": "編集..." 39 | }, 40 | "open": { 41 | "description": "ブックマークを開く", 42 | "message": "開く" 43 | }, 44 | "searchBookmarks": { 45 | "description": "検索フィールドのためのプレースホルダーテキスト", 46 | "message": "ブックマークの検索" 47 | }, 48 | "delete": { 49 | "message": "削除" 50 | }, 51 | "editBookmark": { 52 | "message": "ブックマークの編集" 53 | }, 54 | "openNewTab": { 55 | "message": "新しいタブで開く" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "フォルダから多くのブックマークを開くとき、警告する" 59 | }, 60 | "editFolder": { 61 | "message": "フォルダの編集" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "ブックマークバー", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "ブックマークが格納されているフォルダの情報は、検索結果リストのブックマーク吹き出しに表示される", 71 | "message": "フォルダ名 \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "確認メッセージ - すべてのブックマークを新規シークレットウィンドウで表示する場合", 80 | "message": "$count$ 個のブックマークを新しいシークレットウィンドウで開こうとしています。よろしいですか。" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "errorOccured": { 86 | "message": "エラーが発生しました" 87 | }, 88 | "optionPopupStays": { 89 | "message": "ブックマークをクリックしたとき、ポップアップを表示したままにする" 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "フォルダを開くとき、アクティブでないフォルダを閉じる" 93 | }, 94 | "accessibility": { 95 | "message": "アクセシビリティ" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "削除..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "$folderName$ フォルダと $bookmarkCount$ 個のブックマークを削除します。よろしいですか。" 110 | }, 111 | "advancedOptions": { 112 | "message": "拡張オプション" 113 | }, 114 | "extDesc": { 115 | "description": "詳細な説明", 116 | "message": "すっきりしたツリー構造のブックマーク" 117 | }, 118 | "save": { 119 | "message": "保存" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "確認メッセージ - すべてのブックマークを新規ウィンドウで表示する場合", 128 | "message": "$count$ 個のブックマークを新しいウィンドウで開こうとしています。よろしいですか。" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "確認メッセージ - すべてのブックマークを開く場合", 137 | "message": "$count$ 個のブックマークを開こうとしています。よろしいですか。" 138 | }, 139 | "openBookmarks": { 140 | "message": "すべてのブックマークを開く" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "スクロール位置と開いたフォルダの情報を保持する" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "オプションページのフッターテキスト", 152 | "message": "作成者 $authorName$." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "すべてのブックマークを新しいウィンドウで開く" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "マウスホイール・クリック、または「Ctrl」キーを押しながらクリックしたとき、ブックマークを新しい背面タブで開く" 159 | }, 160 | "ignore": { 161 | "message": "無視" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "シークレットウィンドウで開く" 165 | }, 166 | "general": { 167 | "message": "全般" 168 | }, 169 | "openNewWindow": { 170 | "message": "新しいウィンドウで開く" 171 | }, 172 | "optionZoom": { 173 | "message": "拡大" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "ブックマークを新しいタブで開く" 177 | }, 178 | "options": { 179 | "message": "オプション" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "$folderName$ フォルダと $subFolderCount$ 個のサブフォルダを削除します。よろしいですか。" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/ko/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "아니오" 4 | }, 5 | "name": { 6 | "description": "북마크 혹은 폴더의 이름", 7 | "message": "이름" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "시크릿 창으로 모든 북마크 열기" 11 | }, 12 | "reportError": { 13 | "message": "오류 보고" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "정말 $subFolderCount$ 개의 하위 폴더와 $bookmarkCount$ 개의 북마크가 들어있는 $folderName$ 폴더를 삭제하시겠습니까?" 28 | }, 29 | "extName": { 30 | "description": "확장 프로그램 이름", 31 | "message": "Neat Bookmarks" 32 | }, 33 | "noTitle": { 34 | "description": "http(s) 형식이 아닌 URL(주소)이거나 제목없는 폴더에 있는 제목없는 북마크에 대한 제목", 35 | "message": "(제목 없음)" 36 | }, 37 | "edit": { 38 | "message": "편집하기..." 39 | }, 40 | "open": { 41 | "description": "북마크 열기를 실행", 42 | "message": "열기" 43 | }, 44 | "searchBookmarks": { 45 | "description": "검색어 입력상자에 미리 입력되어 있는 텍스트", 46 | "message": "북마크 검색" 47 | }, 48 | "delete": { 49 | "message": "삭제" 50 | }, 51 | "editBookmark": { 52 | "message": "북마크 편집" 53 | }, 54 | "openNewTab": { 55 | "message": "새로운 탭으로 열기" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "한 폴더에 있는 많은 북마크를 열 때 확인창 보여주기" 59 | }, 60 | "editFolder": { 61 | "message": "폴더 편집" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "북마크바", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "검색 결과 리스트 중 북마크에 대한 툴팁으로 표시되는 상위 폴더 정보", 71 | "message": "상위 폴더: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "모든 북마크를 시크릿 창으로 여는 것에 대한 확인 메시지", 80 | "message": "정말 $count$ 개의 북마크를 모두 새로운 시크릿 창으로 여시겠습니까?" 81 | }, 82 | "url": { 83 | "message": "URL(주소)" 84 | }, 85 | "errorOccured": { 86 | "message": "오류가 발생하였습니다." 87 | }, 88 | "optionPopupStays": { 89 | "message": "(왼쪽 버튼 클릭으로) 북마크를 열 때 팝업메뉴 계속 보여주기" 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "한 폴더를 펼칠 때 다른 폴더는 접기" 93 | }, 94 | "accessibility": { 95 | "message": "보기 옵션" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "삭제하기..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "정말 $bookmarkCount$ 개의 북마크가 들어있는 $folderName$ 폴더를 삭제하시겠습니까?" 110 | }, 111 | "advancedOptions": { 112 | "message": "고급 옵션" 113 | }, 114 | "extDesc": { 115 | "description": "확장 프로그램에 대한 설명", 116 | "message": "깔끔하게 정리된 북마크 트리를 팝업으로 보여줍니다." 117 | }, 118 | "save": { 119 | "message": "저장" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "모든 북마크를 새로운 창으로 열기 위한 확인 메세지", 128 | "message": "정말 $count$ 개의 북마크를 모두 새로운 창으로 여시겠습니까?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "모든 북마크를 여는 것에 대한 확인 메시지", 137 | "message": "정말 $count$ 개의 북마크를 모두 여시겠습니까?" 138 | }, 139 | "openBookmarks": { 140 | "message": "모든 북마크 열기" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "(스크롤한 위치와 열렸던 폴더에 대한) 이전 상태 기억하기" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "옵션 설정 페이지의 꼬리말", 152 | "message": "만든이 : $authorName$." 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "새로운 창으로 모든 북마크 열기" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "가운데 버튼이나 오른쪽 버튼 클릭시 새로운 백그라운드 탭으로 북마크 열기" 159 | }, 160 | "ignore": { 161 | "message": "무시" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "시크릿 창으로 열기" 165 | }, 166 | "general": { 167 | "message": "일반 옵션" 168 | }, 169 | "openNewWindow": { 170 | "message": "새로운 창으로 열기" 171 | }, 172 | "optionZoom": { 173 | "message": "확대" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "왼쪽 버튼 클릭시 새로운 탭으로 북마크 열기" 177 | }, 178 | "options": { 179 | "message": "옵션" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "정말 $subFolderCount$ 개의 하위 폴더가 들어있는 $folderName$ 폴더를 삭제하시겠습니까?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/pl/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Nie" 4 | }, 5 | "name": { 6 | "description": "Nazwa zakładki lub folderu.", 7 | "message": "Nazwa" 8 | }, 9 | "openBookmarksIncognitoWindow": { 10 | "message": "Otwórz wszystkie zakładki w oknie incognito" 11 | }, 12 | "reportError": { 13 | "message": "Zgłoś błąd" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Czy jesteś pewien, że chcesz usunąć folder $folderName$, $subFolderCount$ podfolderów i $bookmarkCount$ zakładek w nich zawartych?" 28 | }, 29 | "extName": { 30 | "description": "Nazwa rozszerzenia", 31 | "message": "Zgrabne zakładki" 32 | }, 33 | "noTitle": { 34 | "description": "Tytuł dla zakładek bez tytułu bez adresów URL lub folderów bez tytułu", 35 | "message": "(bez tytułu)" 36 | }, 37 | "edit": { 38 | "message": "Edytuj..." 39 | }, 40 | "open": { 41 | "description": "Akcja otwierania zakładek", 42 | "message": "Otwórz" 43 | }, 44 | "searchBookmarks": { 45 | "description": "Tekst zastępczy w polu wyszukiwania", 46 | "message": "Przeszukaj zakładki" 47 | }, 48 | "delete": { 49 | "message": "Usuń" 50 | }, 51 | "editBookmark": { 52 | "message": "Edytuj zakładkę" 53 | }, 54 | "openNewTab": { 55 | "message": "Otwórz w nowej karcie" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Wyświetl potwierdzenie podczas otwierania dużej ilości zakładek z folderu" 59 | }, 60 | "editFolder": { 61 | "message": "Edytuj folder" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Pasek zakładek", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Informacje o folderze nadrzędnym wyświetlane w dymku zakładek w wynikach wyszukiwania.", 71 | "message": "Folder nadrzędny: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Komunikat potwierdzenia otwarcia wszystkich zakładek w nowym oknie incognito", 80 | "message": "Czy jesteś pewien, że chcesz otworzyć wszystkie ($count$) zakładki w nowym oknie incognito?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "errorOccured": { 86 | "message": "Ups, wystąpił błąd." 87 | }, 88 | "optionPopupStays": { 89 | "message": "Okienko pozostaje otwarte podczas otwierania (lewy przycisk myszy) zakładek" 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Zamknij nieużywane foldery, podczas otwierania folderu" 93 | }, 94 | "accessibility": { 95 | "message": "Dostępność" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Usuń..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Czy jesteś pewien, że chcesz usunąć folder $folderName$ i $bookmarkCount$ zakładek zawartych w tym folderze?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Opcje zaawansowane" 113 | }, 114 | "extDesc": { 115 | "description": "Opis rozszerzenia", 116 | "message": "Okienko z drzewkiem zgrabnych zakładek" 117 | }, 118 | "save": { 119 | "message": "Zapisz" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Komunikat potwierdzenia otwarcia wszystkich zakładek w nowym oknie", 128 | "message": "Czy jesteś pewien, że chcesz otworzyć wszystkie ($count$) zakładki w nowym oknie?" 129 | }, 130 | "confirmOpenBookmarks": { 131 | "placeholders": { 132 | "count": { 133 | "content": "$1" 134 | } 135 | }, 136 | "description": "Komunikat potwierdzenia otwarcia wszystkich zakładek", 137 | "message": "Czy jesteś pewien, że chcesz otworzyć wszystkie ($count$) zakładki?" 138 | }, 139 | "openBookmarks": { 140 | "message": "Otwórz wszystkie zakładki" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Pamiętaj poprzedni stan (pozycja przewijania i otwarte foldery)" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Tekst stopki dla strony z opcjami", 152 | "message": "Stworzone przez $authorName$" 153 | }, 154 | "openBookmarksNewWindow": { 155 | "message": "Otwórz wszystkie zakładki w nowym oknie" 156 | }, 157 | "optionOpenNewTab": { 158 | "message": "Kliknięcie środkowym przyciskiem myszy lub wciśnięcie CTRL na klawiaturze i kliknięcie otwiera zakładkę na nowej karcie w tle (zamiast na pierwszym planie)" 159 | }, 160 | "ignore": { 161 | "message": "Ignoruj" 162 | }, 163 | "openIncognitoWindow": { 164 | "message": "Otwórz w oknie incognito" 165 | }, 166 | "general": { 167 | "message": "Ogólne" 168 | }, 169 | "openNewWindow": { 170 | "message": "Otwórz w nowym oknie" 171 | }, 172 | "optionZoom": { 173 | "message": "Przybliżanie" 174 | }, 175 | "optionClickNewTab": { 176 | "message": "Kliknięcie lewym przyciskiem myszy otwiera zakładkę w nowej karcie" 177 | }, 178 | "options": { 179 | "message": "Opcje" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Czy jesteś pewien, że chcesz usunąć folder $folderName$ i $subFolderCount$ podfolderów?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/pt_BR/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Nãaoo" 4 | }, 5 | "openBookmarksIncognitoWindow": { 6 | "message": "Abrir todos os favoritos em uma janela anônima" 7 | }, 8 | "name": { 9 | "description": "Nome do favorito ou pasta.", 10 | "message": "Nome" 11 | }, 12 | "reportError": { 13 | "message": "Reportar erro" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Você tem certeza que quer apagar a pasta $folderName$, $subFolderCount$ sub-pasta(s) e $bookmarkCount$ favorito(s) incluído(s)?" 28 | }, 29 | "noTitle": { 30 | "description": "Título para favoritos sem título e sem URL http(s) ou pastas sem título.", 31 | "message": "(sem título)" 32 | }, 33 | "extName": { 34 | "description": "Nome da extensão.", 35 | "message": "Neat Bookmarks" 36 | }, 37 | "edit": { 38 | "message": "Editar..." 39 | }, 40 | "searchBookmarks": { 41 | "description": "Texto contido no campo de pesquisa.", 42 | "message": "Procurar favoritos" 43 | }, 44 | "open": { 45 | "description": "Ação para abrir favoritos", 46 | "message": "Abrir" 47 | }, 48 | "delete": { 49 | "message": "Apagar" 50 | }, 51 | "editBookmark": { 52 | "message": "Editar favorito" 53 | }, 54 | "openNewTab": { 55 | "message": "Abrir em uma nova guia" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Mostrar confirmação quando abrir vários favoritos de uma pasta." 59 | }, 60 | "editFolder": { 61 | "message": "Editar pasta" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Barra de favoritos", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Informação da pasta principal mostrada em dicas dos marcadores nas listas dos resultados das pesquisas.", 71 | "message": "Pasta principal: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Mensagem de confirmação para abertura de todos os favoritos em uma nova janela anônima.", 80 | "message": "Você tem certeza que quer abrir todos os $count$ favoritos em uma nova janela anônima?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "optionPopupStays": { 86 | "message": "O pop-up continua aberto quando abrir um favorito (clicando com o botão esquerdo) ." 87 | }, 88 | "errorOccured": { 89 | "message": "Oops, ocorreu um erro." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Fechar pastas não utilizadas quando abrir uma nova pasta." 93 | }, 94 | "accessibility": { 95 | "message": "Acessibilidade" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Apagar..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Você tem certeza que quer apagar a pasta $folderName$ e $bookmarkCount$ favorito(s) incluído(s)?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Opções Avançadas" 113 | }, 114 | "save": { 115 | "message": "Salvar" 116 | }, 117 | "extDesc": { 118 | "description": "Descrição da extensão.", 119 | "message": "Um prático gerenciador de favoritos de estilo pop-up." 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Mensagem de confirmação para abertura de todos os favoritos em uma nova janela.", 128 | "message": "Você tem certeza que quer abrir todos os $count$ favoritos em uma nova janela?" 129 | }, 130 | "openBookmarks": { 131 | "message": "Abrir todos os favoritos" 132 | }, 133 | "confirmOpenBookmarks": { 134 | "placeholders": { 135 | "count": { 136 | "content": "$1" 137 | } 138 | }, 139 | "description": "Mensagem de confirmação para abertura de todos os favoritos.", 140 | "message": "Você tem certeza que quer abrir todos os $count$ favoritos?" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Lembrar do estado anterior (posição e pastas abertas)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Texto de rodapé para a página de Opções", 152 | "message": "Criado por $authorName$." 153 | }, 154 | "optionOpenNewTab": { 155 | "message": "Clique com o botão do meio do mouse ou control-clique abre o favorito em um nova guia em 2º plano (em vez de 1º plano)." 156 | }, 157 | "openBookmarksNewWindow": { 158 | "message": "Abrir todos os favoritos em uma nova janela" 159 | }, 160 | "openIncognitoWindow": { 161 | "message": "Abrir em uma janela anônima" 162 | }, 163 | "ignore": { 164 | "message": "Ignorar" 165 | }, 166 | "openNewWindow": { 167 | "message": "Abrir em uma nova janela" 168 | }, 169 | "general": { 170 | "message": "Geral" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoom" 174 | }, 175 | "options": { 176 | "message": "Opções" 177 | }, 178 | "optionClickNewTab": { 179 | "message": "Clique com o botão esquerdo do mouse abre favorito em uma nova guia" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Você tem certeza que quer apagar a pasta $folderName$ e $subFolderCount$ sub-pasta(s) incluída(s)?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/pt_PT/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Nãaoo" 4 | }, 5 | "openBookmarksIncognitoWindow": { 6 | "message": "Abrir Todos os Marcadores numa Janela Privada" 7 | }, 8 | "name": { 9 | "description": "Nome do marcador ou pasta.", 10 | "message": "Nome" 11 | }, 12 | "reportError": { 13 | "message": "Reportar Erro" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Tem a certeza que pretende apagar a pasta $folderName$, $subFolderCount$ sub-pasta(s) e $bookmarkCount$ marcador(es) incluído(s)?" 28 | }, 29 | "noTitle": { 30 | "description": "Título para marcadores sem título e sem http(s) URL ou pastas sem título.", 31 | "message": "(sem título)" 32 | }, 33 | "extName": { 34 | "description": "Nome da extensão.", 35 | "message": "Neat Bookmarks" 36 | }, 37 | "edit": { 38 | "message": "Editar..." 39 | }, 40 | "searchBookmarks": { 41 | "description": "Texto contido no campo de pesquisa.", 42 | "message": "Pesquisar Marcadores" 43 | }, 44 | "open": { 45 | "description": "Acção para abrir marcadores.", 46 | "message": "Abrir" 47 | }, 48 | "delete": { 49 | "message": "Apagar" 50 | }, 51 | "editBookmark": { 52 | "message": "Editar marcador" 53 | }, 54 | "openNewTab": { 55 | "message": "Abrir num Novo Separador" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Mostra confirmação quando abre vários marcadores duma pasta." 59 | }, 60 | "editFolder": { 61 | "message": "Editar pasta" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Barra de marcadores", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Informação da pasta principal mostrada nas dicas dos marcadores, nas listas dos resultados das pesquisas.", 71 | "message": "Pasta principal: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Mensagem de confirmação para abertura de todos os marcadores numa nova janela privada.", 80 | "message": "Tem a certeza que pretende abrir todos os $count$ marcadores numa nova janela privada?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "optionPopupStays": { 86 | "message": "Popup continua aberto quando abrir (click-esquerdo no rato) marcadores." 87 | }, 88 | "errorOccured": { 89 | "message": "Oops, ocorreu um erro." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Fecha pastas não utilizadas quando abre uma nova pasta." 93 | }, 94 | "accessibility": { 95 | "message": "Acessibilidade" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Apagar..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Tem a certeza que pretende apagar a pasta $folderName$ e $bookmarkCount$ marcador(es) incluídos?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Opções Avançadas" 113 | }, 114 | "save": { 115 | "message": "Gravar" 116 | }, 117 | "extDesc": { 118 | "description": "Descrição de extensão.", 119 | "message": "Um prático gestor de marcadores de estilo popup." 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Mensagem de confirmação para abertura de todos os marcadores numa nova janela.", 128 | "message": "Tem a certeza que pretende abrir todos os $count$ marcadores numa nova janela?" 129 | }, 130 | "openBookmarks": { 131 | "message": "Abrir Todos os Marcadores" 132 | }, 133 | "confirmOpenBookmarks": { 134 | "placeholders": { 135 | "count": { 136 | "content": "$1" 137 | } 138 | }, 139 | "description": "Mensagem de confirmação para abertura de todos os marcadores.", 140 | "message": "Tem a certeza que pretende abrir todos os $count$ marcadores?" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Memoriza o estado anterior (posição vertical e pastas abertas)." 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Texto de rodapé para a página de Opções", 152 | "message": "Criado por $authorName$." 153 | }, 154 | "optionOpenNewTab": { 155 | "message": "click-botão do meio do rato ou control-click abre marcador num novo separador em 2º plano (em vez de 1º plano)." 156 | }, 157 | "openBookmarksNewWindow": { 158 | "message": "Abrir Todos os Marcadores numa Nova Janela" 159 | }, 160 | "openIncognitoWindow": { 161 | "message": "Abrir numa Janela Privada" 162 | }, 163 | "ignore": { 164 | "message": "Ignorar" 165 | }, 166 | "openNewWindow": { 167 | "message": "Abrir numa Nova Janela" 168 | }, 169 | "general": { 170 | "message": "Geral" 171 | }, 172 | "optionZoom": { 173 | "message": "Zoom" 174 | }, 175 | "options": { 176 | "message": "Opções" 177 | }, 178 | "optionClickNewTab": { 179 | "message": "click-botão esquerdo do rato abre marcador num novo separador." 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Tem a certeza que pretende apagar a pasta $folderName$ e $subFolderCount$ sub-pasta(s) incluída(s)?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/ru/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "Нету" 4 | }, 5 | "openBookmarksIncognitoWindow": { 6 | "message": "Открыть все закладки в режиме инкогнито" 7 | }, 8 | "name": { 9 | "description": "Имя закладки или папки", 10 | "message": "Имя" 11 | }, 12 | "reportError": { 13 | "message": "Сообщить об ошибке" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "Вы уверены что хотите удалить $folderName$ папку, $subFolderCount$ подпапок и $bookmarkCount$ закладок в ней?" 28 | }, 29 | "noTitle": { 30 | "description": "Заголовок для безыменных закладок не имеющих ссылки и безыменных папок.", 31 | "message": "(без заголовка)" 32 | }, 33 | "extName": { 34 | "description": "Имя расширения", 35 | "message": "Neat Bookmarks" 36 | }, 37 | "edit": { 38 | "message": "Редактировать ..." 39 | }, 40 | "searchBookmarks": { 41 | "description": "Впишите текст для поиска.", 42 | "message": "Поиск Закладок" 43 | }, 44 | "open": { 45 | "description": "Действие для открытие закладки.", 46 | "message": "Открыть" 47 | }, 48 | "delete": { 49 | "message": "Удалить" 50 | }, 51 | "editBookmark": { 52 | "message": "Редактировать закладку" 53 | }, 54 | "openNewTab": { 55 | "message": "Открыть в новой вкладке" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "Подтверждающее сообщение при открытии большого количества закладок из папки." 59 | }, 60 | "editFolder": { 61 | "message": "Редактировать папку" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "Панель закладок", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "Отображение информации родительской папки в всплывающем окне закладок в списке результата поиска.", 71 | "message": "Родительская папка: \"$folderName$\"" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "Подтверждающие сообщение при открытии всех закладок в режиме инкогнито.", 80 | "message": "Вы уверены что хотите открыть все $count$ закладок в режиме инкогнито?" 81 | }, 82 | "url": { 83 | "message": "URL" 84 | }, 85 | "optionPopupStays": { 86 | "message": "Оставить окно открытым при открытии (ЛКМ) вкладок." 87 | }, 88 | "errorOccured": { 89 | "message": "Упс, к сожалению произошла ошибка." 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "Закрыть неиспользуемые папки когда открыта папка." 93 | }, 94 | "accessibility": { 95 | "message": "Доступность" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "Удалить ..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "Вы уверены что хотите удалить $folderName$ папку и $bookmarkCount$ закладок в ней?" 110 | }, 111 | "advancedOptions": { 112 | "message": "Дополнительные Опции" 113 | }, 114 | "save": { 115 | "message": "Сохранить" 116 | }, 117 | "extDesc": { 118 | "description": "Описание расширения.", 119 | "message": "Всплывающее окно закладок." 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "Подтверждающие сообщение при открытии всех закладок в новом окне.", 128 | "message": "Вы уверены что хотите открыть все $count$ закладок в новом окне?" 129 | }, 130 | "openBookmarks": { 131 | "message": "Открыть все закладки" 132 | }, 133 | "confirmOpenBookmarks": { 134 | "placeholders": { 135 | "count": { 136 | "content": "$1" 137 | } 138 | }, 139 | "description": "Подтверждающие сообщение при открытии всех закладок.", 140 | "message": "Вы уверены что хотите открыть все $count$ закладок?" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "Запомнить предыдущую позицию (позицию прокрутки и открытые папки)" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "Нижний колонтитул для страницы Опций", 152 | "message": "Автор проекта $authorName$." 153 | }, 154 | "optionOpenNewTab": { 155 | "message": "Клик средней кнопкой мыши открывает закладки в новой фоновой вкладке." 156 | }, 157 | "openBookmarksNewWindow": { 158 | "message": "Открыть все закладки в новом окне" 159 | }, 160 | "openIncognitoWindow": { 161 | "message": "Открыть в режиме инкогнито" 162 | }, 163 | "ignore": { 164 | "message": "Игнорировать" 165 | }, 166 | "openNewWindow": { 167 | "message": "Открыть в новом окне" 168 | }, 169 | "general": { 170 | "message": "Основной" 171 | }, 172 | "optionZoom": { 173 | "message": "Увеличить" 174 | }, 175 | "options": { 176 | "message": "Опции" 177 | }, 178 | "optionClickNewTab": { 179 | "message": "Левый клик откроет закладку в новой вкладке." 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "Вы уверены что хотите удалить $folderName$ папку и $subFolderCount$ подпапок в ней?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/zh/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "取消" 4 | }, 5 | "openBookmarksIncognitoWindow": { 6 | "message": "在隐身窗口中打开所有书签" 7 | }, 8 | "name": { 9 | "description": "书签名或文件夹名", 10 | "message": "名字" 11 | }, 12 | "reportError": { 13 | "message": "报告此错误" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "您确定要删除文件夹[$folderName$](包含 $subFolderCount$ 个子目录和 $bookmarkCount$ 个书签)?" 28 | }, 29 | "noTitle": { 30 | "description": "没 http(s) 开头的书签或没有命名的文件夹的统一标题", 31 | "message": "(无标题)" 32 | }, 33 | "extName": { 34 | "description": "扩展名", 35 | "message": "Neat Bookmarks" 36 | }, 37 | "edit": { 38 | "message": "編輯 ..." 39 | }, 40 | "searchBookmarks": { 41 | "description": "搜索框里的提示文字", 42 | "message": "书签搜索" 43 | }, 44 | "open": { 45 | "description": "打开书签的动作", 46 | "message": "打开" 47 | }, 48 | "delete": { 49 | "message": "删除" 50 | }, 51 | "editBookmark": { 52 | "message": "编辑书签" 53 | }, 54 | "openNewTab": { 55 | "message": "在新标签页中打开" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "打开多个书签前需确认" 59 | }, 60 | "editFolder": { 61 | "message": "编辑文件夹" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "书签栏", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "搜索结果列表中提示书签所在目录", 71 | "message": "所在目录:$folderName$" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "在隐身窗口中打开所有书签的确认信息", 80 | "message": "您确定要在隐身窗口中打开 $count$ 个书签?" 81 | }, 82 | "url": { 83 | "message": "网址" 84 | }, 85 | "optionPopupStays": { 86 | "message": "打开(鼠标左击)书签时 Popup 页面不关闭" 87 | }, 88 | "errorOccured": { 89 | "message": "有错误出现" 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "展开文件夹时折叠其他文件夹" 93 | }, 94 | "accessibility": { 95 | "message": "辅助功能" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "删除 ..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "您确定要删除文件夹[$folderName$](包含 $bookmarkCount$ 个书签)?" 110 | }, 111 | "advancedOptions": { 112 | "message": "高级选项" 113 | }, 114 | "save": { 115 | "message": "保存" 116 | }, 117 | "extDesc": { 118 | "description": "扩展描述", 119 | "message": "灵巧实用的侧置书签扩展" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "在新窗口中打开所有书签的确认信息", 128 | "message": "您确定要在新窗口中打开 $count$ 个书签?" 129 | }, 130 | "openBookmarks": { 131 | "message": "打开所有书签" 132 | }, 133 | "confirmOpenBookmarks": { 134 | "placeholders": { 135 | "count": { 136 | "content": "$1" 137 | } 138 | }, 139 | "description": "打开所有书签的确认信息", 140 | "message": "您确定要打开 $count$ 个书签?" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "记住上次状态(滚动条位置、所打开文件夹)" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "选项页的页脚信息", 152 | "message": "作者:$authorName$" 153 | }, 154 | "optionOpenNewTab": { 155 | "message": "用鼠标中键或按住 Ctrl 键左击在后台打开书签" 156 | }, 157 | "openBookmarksNewWindow": { 158 | "message": "在新窗口中打开所有书签" 159 | }, 160 | "openIncognitoWindow": { 161 | "message": "在隐身窗口中打开" 162 | }, 163 | "ignore": { 164 | "message": "忽略" 165 | }, 166 | "openNewWindow": { 167 | "message": "在新窗口中打开" 168 | }, 169 | "general": { 170 | "message": "常规功能" 171 | }, 172 | "optionZoom": { 173 | "message": "缩放" 174 | }, 175 | "options": { 176 | "message": "选项" 177 | }, 178 | "optionClickNewTab": { 179 | "message": "左击书签在新标签页中打开" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "您确定要删除文件夹[$folderName$](包含 $subFolderCount$ 个子目录)?" 191 | } 192 | } -------------------------------------------------------------------------------- /_locales/zh_TW/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "nope": { 3 | "message": "取消" 4 | }, 5 | "openBookmarksIncognitoWindow": { 6 | "message": "在無痕式視窗中開啟所有書籤" 7 | }, 8 | "name": { 9 | "description": "書籤名或資料夾名", 10 | "message": "名稱" 11 | }, 12 | "reportError": { 13 | "message": "報告此錯誤" 14 | }, 15 | "confirmDeleteFolderSubfoldersBookmarks": { 16 | "placeholders": { 17 | "subFolderCount": { 18 | "content": "$2" 19 | }, 20 | "bookmarkCount": { 21 | "content": "$3" 22 | }, 23 | "folderName": { 24 | "content": "$1" 25 | } 26 | }, 27 | "message": "您確定要刪除資料夾[$folderName$](包含 $subFolderCount$ 個子目錄和 $bookmarkCount$ 個書籤)?" 28 | }, 29 | "noTitle": { 30 | "description": "無 http(s) 開頭的書籤或無命名的資料夾的預設標題", 31 | "message": "(無標題)" 32 | }, 33 | "extName": { 34 | "description": "擴充功能名稱", 35 | "message": "Neat Bookmarks" 36 | }, 37 | "edit": { 38 | "message": "編輯 ..." 39 | }, 40 | "searchBookmarks": { 41 | "description": "搜索框裡的提示文字", 42 | "message": "搜尋書籤" 43 | }, 44 | "open": { 45 | "description": "開啟書籤的動作", 46 | "message": "開啟" 47 | }, 48 | "delete": { 49 | "message": "刪除" 50 | }, 51 | "editBookmark": { 52 | "message": "編輯書籤" 53 | }, 54 | "openNewTab": { 55 | "message": "在新分頁中開啟" 56 | }, 57 | "optionConfirmOpenFolder": { 58 | "message": "開啟多個書籤前需確認" 59 | }, 60 | "editFolder": { 61 | "message": "編輯資料夾" 62 | }, 63 | "parentFolder": { 64 | "placeholders": { 65 | "folderName": { 66 | "example": "書籤欄", 67 | "content": "$1" 68 | } 69 | }, 70 | "description": "搜索結果列表中提示書籤所在目錄", 71 | "message": "所在目錄:$folderName$" 72 | }, 73 | "confirmOpenBookmarksNewIncognitoWindow": { 74 | "placeholders": { 75 | "count": { 76 | "content": "$1" 77 | } 78 | }, 79 | "description": "在無痕式視窗中開啟所有書籤時的確認訊息", 80 | "message": "您確定要在無痕式視窗中開啟 $count$ 個書籤?" 81 | }, 82 | "url": { 83 | "message": "網址" 84 | }, 85 | "optionPopupStays": { 86 | "message": "開啟(滑鼠左擊)書籤時 Popup 頁面不關閉" 87 | }, 88 | "errorOccured": { 89 | "message": "有錯誤出現" 90 | }, 91 | "optionCloseUnusedFolders": { 92 | "message": "展開資料夾時收合其他資料夾" 93 | }, 94 | "accessibility": { 95 | "message": "輔助功能" 96 | }, 97 | "deleteEllipsis": { 98 | "message": "刪除 ..." 99 | }, 100 | "confirmDeleteFolderBookmarks": { 101 | "placeholders": { 102 | "folderName": { 103 | "content": "$1" 104 | }, 105 | "bookmarkCount": { 106 | "content": "$2" 107 | } 108 | }, 109 | "message": "您確定要刪除資料夾[$folderName$](包含 $bookmarkCount$ 個書籤)?" 110 | }, 111 | "advancedOptions": { 112 | "message": "進階設定" 113 | }, 114 | "save": { 115 | "message": "儲存" 116 | }, 117 | "extDesc": { 118 | "description": "擴充功能描述", 119 | "message": "靈巧實用的側置書籤擴充功能" 120 | }, 121 | "confirmOpenBookmarksNewWindow": { 122 | "placeholders": { 123 | "count": { 124 | "content": "$1" 125 | } 126 | }, 127 | "description": "在新視窗中開啟所有書籤時的確認訊息", 128 | "message": "您確定要在新視窗中開啟 $count$ 個書籤?" 129 | }, 130 | "openBookmarks": { 131 | "message": "開啟所有書籤" 132 | }, 133 | "confirmOpenBookmarks": { 134 | "placeholders": { 135 | "count": { 136 | "content": "$1" 137 | } 138 | }, 139 | "description": "開啟所有書籤時的確認訊息", 140 | "message": "您確定要開啟 $count$ 個書籤?" 141 | }, 142 | "optionRememberPrevState": { 143 | "message": "記住上次狀態(滾動軸位置、已展開資料夾)" 144 | }, 145 | "optionsFooterText": { 146 | "placeholders": { 147 | "authorName": { 148 | "content": "$1" 149 | } 150 | }, 151 | "description": "設定頁的頁腳訊息", 152 | "message": "作者:$authorName$" 153 | }, 154 | "optionOpenNewTab": { 155 | "message": "用滑鼠中鍵或按住 Ctrl 鍵左擊在背景開啟書籤" 156 | }, 157 | "openBookmarksNewWindow": { 158 | "message": "在新視窗中開啟所有書籤" 159 | }, 160 | "openIncognitoWindow": { 161 | "message": "在無痕式視窗中開啟" 162 | }, 163 | "ignore": { 164 | "message": "忽略" 165 | }, 166 | "openNewWindow": { 167 | "message": "在新視窗中開啟" 168 | }, 169 | "general": { 170 | "message": "一般功能" 171 | }, 172 | "optionZoom": { 173 | "message": "縮放" 174 | }, 175 | "options": { 176 | "message": "設定" 177 | }, 178 | "optionClickNewTab": { 179 | "message": "左擊書籤在新分頁中開啟" 180 | }, 181 | "confirmDeleteFolderSubfolders": { 182 | "placeholders": { 183 | "subFolderCount": { 184 | "content": "$2" 185 | }, 186 | "folderName": { 187 | "content": "$1" 188 | } 189 | }, 190 | "message": "您確定要刪除資料夾[$folderName$](包含 $subFolderCount$ 個子目錄)?" 191 | } 192 | } -------------------------------------------------------------------------------- /advanced-options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 82 |
x";return W.firstChild.offsetHeight|| 15 | 1}function qb(c){var c=ab(c,!0),o=M(G);return{x:o.left+c.x,y:o.top+c.y,yBot:o.top+c.yBot}}function ab(c,o){var a=S(),b=c.line-(o?C:0);return{x:Y(c.line,c.ch),y:b*a,yBot:(b+1)*a}}function pb(c,o){function a(c){W.innerHTML="
"+b.getHTML(null,null,!1,c)+"
";return W.firstChild.firstChild.offsetWidth}if(o<=0)return 0;for(var b=h[c],d=0,e=0,g=b.text.length,w,f=Math.min(g,Math.ceil(o/rb("x")));;){var m=a(f);if(m<=o&&f"+h[c].getHTML(null,null,!1,o)+"
";return W.firstChild.firstChild.offsetWidth}function rb(c){W.innerHTML="x
";W.firstChild.firstChild.firstChild.nodeValue=c;return W.firstChild.firstChild.offsetWidth||10}function Ya(c,o,a){function b(c,a,o,l){c=h[c];a=c.addMark(a,o,l);a.line=c;
17 | d.push(a)}var c=A(c),o=A(o),d=[];if(c.line==o.line)b(c.line,c.ch,o.ch,a);else{b(c.line,c.ch,null,a);for(var e=c.line+1,g=o.line;e",b,"")}$.style.display="none";Ka.innerHTML=c.join("");c=String(h.length).length;a=Ka.firstChild;l=a.textContent||a.innerText||a.nodeValue||"";for(b="";l.length+b.length
k&&(k=m.length,za=m)}f=[];j=b.length-j-1;i=0;for(m=V.length;ia.line&&f.push(k+j);if(b.length<5){m=c.line;i=c.line+b.length;for(k=s(m);m=0&&k>=0;--i,--k)if(d.charAt(i)!=g.charAt(k))break;d=k+1}else d=g.length;else d=d?d.length:0;f=A({line:f,ch:d});wb({line:b.start,ch:0},{line:e-1,ch:h[e-1].text.length},b.old,f,f);Q=!0}}function cb(c,a,b,d,e){if(O){for(var f=[],g=c.line,k=a.line+1;g i.undoDepth;)O.done.shift()}wb(c,a,b,d,e)}function Ab(){P&&(i.onBlur&&i.onBlur(K),P=!1,N.className=N.className.replace(" CodeMirror-focused",""));clearInterval(Za); 38 | setTimeout(function(){P||(T=null)},150)}function ua(){i.readOnly!="nocursor"&&(P||(i.onFocus&&i.onFocus(K),P=!0,N.className.search(/\bCodeMirror-focused\b/)==-1&&(N.className+=" CodeMirror-focused"),ya||Va()),Ga(),kb())}function Bb(c){O=null;var a={line:0,ch:0};cb(a,{line:h.length-1,ch:h[h.length-1].text.length},R(c),a,a);O=new Ta}var i={},fb=x.defaults,Aa;for(Aa in fb)fb.hasOwnProperty(Aa)&&(i[Aa]=(b&&b.hasOwnProperty(Aa)?b:fb)[Aa]);var ea=i.document,N=ea.createElement("div");N.className="CodeMirror"; 39 | N.innerHTML=' '; 40 | a.appendChild?a.appendChild(N):a(N);var Fa=N.firstChild,y=Fa.firstChild,t=N.lastChild,U=t.firstChild,W=U.firstChild,Ja=W.nextSibling,$=Ja.firstChild,Ka=$.firstChild,G=$.nextSibling.firstChild,ba=G.firstChild,H=ba.nextSibling;i.tabindex!=null&&(y.tabindex=i.tabindex);!i.gutter&&!i.lineNumbers&&($.style.display="none");var db=new wa,Sa=new wa,Za,D,h=[new xa("")],V,O=new Ta,P;aa();var g={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},T,fa,gb,Q,J,Wa,Z,ya,C=0,X=0,sb=0,Oa=null,E,Da,za="",sa;d(function(){Bb(i.value|| 41 | "");Q=!1})();r(t,"mousedown",d(function(c){function a(c){var b=ma(c,!0);if(b&&!z(b,g)){P||ua();g=b;qa(f,b);Q=!1;var e=ia();if(b.line>=e.to||b.line0&&/\w/.test(b.charAt(d-1));)--d;for(;e -1&&setTimeout(d(function(){pa(g.to.line,"smart")}),50)}b=a.keyCode;b==13?(i.readOnly||(Ea("\n","end"),i.enterMode!="flat"&&pa(g.from.line,i.enterMode=="keep"? 46 | "prev":"smart")),v(a)):!a.ctrlKey&&!a.altKey&&!a.metaKey&&b==9&&i.tabMode!="default"?v(a):ta(Oa)}}));r(y,"focus",ua);r(y,"blur",Ab);r(t,"dragenter",F);r(t,"dragover",F);r(t,"drop",d(function(a){a.preventDefault();var b=ma(a,!0),d=a.dataTransfer.files;if(b&&!i.readOnly)if(d&&d.length&&window.FileReader&&window.File)for(var a=function(a,c){var d=new FileReader;d.onload=function(){f[c]=d.result;++g==e&&da(f.join(""),A(b),A(b))};d.readAsText(a)},e=d.length,f=Array(e),g=0,h=0;h =0&&a e&&a.y>b.offsetHeight&&(f=a.y-b.offsetHeight);g+b.offsetWidth>i&&(g=i-b.offsetWidth)}b.style.top=f+G.offsetTop+"px";b.style.left=g+G.offsetLeft+"px";d&&ja(g,f,g+b.offsetWidth,f+b.offsetHeight)},lineCount:function(){return h.length},getCursor:function(a){a== 52 | null&&(a=g.inverted);return{line:(a?g.from:g.to).line,ch:(a?g.from:g.to).ch}},somethingSelected:function(){return!z(g.from,g.to)},setCursor:d(function(a,b){b==null&&typeof a.line=="number"?na(a.line,a.ch):na(a,b)}),setSelection:d(function(a,b){ra(A(a),A(b||a))}),getLine:function(a){if(a>=0&&a =0&&a =0&&a ",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},ib=0;e.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(a){function b(a){a={line:a,ch:0};d.pos={from:a,to:a};return d.atOccurrence=!1}for(var d=this, 54 | e=A(a?this.pos.from:this.pos.to);;){if(this.pos=this.matches(a,e))return this.atOccurrence=!0,this.pos.match||!0;if(a){if(!e.line)return b(0);e={line:e.line-1,ch:h[e.line-1].text.length}}else{if(e.line==h.length-1)return b(h.length);e={line:e.line+1,ch:0}}}},from:function(){if(this.atOccurrence)return{line:this.pos.from.line,ch:this.pos.from.ch}},to:function(){if(this.atOccurrence)return{line:this.pos.to.line,ch:this.pos.to.ch}},replace:function(a){var b=this;this.atOccurrence&&d(function(){b.pos.to= 55 | da(a,b.pos.from,b.pos.to)})()}};for(var Pa in Qa)Qa.propertyIsEnumerable(Pa)&&!K.propertyIsEnumerable(Pa)&&(K[Pa]=Qa[Pa]);return K}x.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:!1,tabMode:"classic",enterMode:"indent",electricChars:!0,onKeyEvent:null,lineNumbers:!1,gutter:!1,firstLineNumber:1,readOnly:!1,onChange:null,onCursorActivity:null,onGutterClick:null,onHighlightComplete:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:!1,workTime:100,workDelay:200,undoDepth:40, 56 | tabindex:null,document:window.document};var va={},aa={};x.defineMode=function(a,b){!x.defaults.mode&&a!="null"&&(x.defaults.mode=a);va[a]=b};x.defineMIME=function(a,b){aa[a]=b};x.getMode=function(a,b){typeof b=="string"&&aa.hasOwnProperty(b)&&(b=aa[b]);if(typeof b=="string")var e=b,d={};else if(b!=null)e=b.name,d=b;var f=va[e];if(!f)return window.console&&console.warn("No mode "+e+" found, falling back to plain text."),x.getMode(a,"text/plain");return f(a,d||{})};x.listModes=function(){var a=[],b; 57 | for(b in va)va.propertyIsEnumerable(b)&&a.push(b);return a};x.listMIMEs=function(){var a=[],b;for(b in aa)aa.propertyIsEnumerable(b)&&a.push(b);return a};var Qa={};x.defineExtension=function(a,b){Qa[a]=b};x.fromTextArea=function(a,b){function e(){a.value=n.getValue()}b||(b={});b.value=a.value;!b.tabindex&&a.tabindex&&(b.tabindex=a.tabindex);if(a.form){var d=r(a.form,"submit",e,!0);if(typeof a.form.submit=="function"){var f=a.form.submit,k=function(){e();a.form.submit=f;a.form.submit();a.form.submit= 58 | k};a.form.submit=k}}a.style.display="none";var n=x(function(b){a.parentNode.insertBefore(b,a.nextSibling)},b);n.save=e;n.toTextArea=function(){e();a.parentNode.removeChild(n.getWrapperElement());a.style.display="";a.form&&(d(),typeof a.form.submit=="function"&&(a.form.submit=f))};return n};x.startState=Ua;x.copyState=la;ka.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.pos< 59 | this.string.length)return this.string.charAt(this.pos++)},eat:function(a){var b=this.string.charAt(this.pos);if(typeof a=="string"?b==a:b&&(a.test?a.test(b):a(b)))return++this.pos,b},eatWhile:function(a){for(var b=this.start;this.eat(a););return this.pos>b},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){a=this.string.indexOf(a,this.pos);if(a>-1)return this.pos= 60 | a,!0},backUp:function(a){this.pos-=a},column:function(){return s(this.string,this.start)},indentation:function(){return s(this.string)},match:function(a,b,e){if(typeof a!="string")return(a=this.string.slice(this.pos).match(a))&&b!==!1&&(this.pos+=a[0].length),a;if((e?this.string.toLowerCase():this.string).indexOf(e?a.toLowerCase():a,this.pos)==this.pos)return b!==!1&&(this.pos+=a.length),!0},current:function(){return this.string.slice(this.start,this.pos)}};x.StringStream=ka;xa.prototype={replace:function(a, 61 | b,e){var d=[],f=this.marked;ja(0,a,this.styles,d);e&&d.push(e,null);ja(b,this.text.length,this.styles,d);this.styles=d;this.text=this.text.slice(0,a)+e+this.text.slice(b);this.stateAfter=null;if(f){a=e.length-(b-a);e=this.text.length;for(d=0;d =e?n=!0:(k.from=k.from<=Math.min(b,b+a)?k.from:k.from+a,k.to!=null&&(k.to=k.to<=Math.min(b,b+a)?k.to:k.to+a));if(n||k.from>=k.to)f.splice(d,1),d--}}},split:function(a,b){var e=[b,null];ja(a,this.text.length,this.styles,e); 62 | return new xa(b+this.text.slice(a),e)},addMark:function(a,b,e){a={from:a,to:b,style:e};this.marked==null&&(this.marked=[]);this.marked.push(a);this.marked.sort(function(a,b){return a.from-b.from});return a},removeMark:function(a){var b=this.marked;if(b)for(var e=0;e 5E3){d[f++]=this.text.slice(e.pos);d[f++]=null;break}}d.length!=f&&(d.length=f,k=!0);f&&d[f-2]!=j&&(k=!0);return k||d.length<5&&this.text.length<10},getTokenAt:function(a,b,e){for(var d=new ka(this.text);d.pos ',Y(a),""):k.push(Y(a)))}var k=[];e&&k.push(this.className?' ':"");var n=this.styles,j=this.text,p=this.marked;a==b&&(a=null);var q=j.length;d!=null&&(q=Math.min(d,q));if(!j&&d==null)f(" ",a!=null&&b==null?"CodeMirror-selected":null);else if(!p&&a==null)for(a=d=0;a");return k.join("")}};Ta.prototype={addChange:function(a, 66 | b,e){this.undone.length=0;var d=+new Date,f=this.done[this.done.length-1];if(d-this.time>400||!f||f.start>a+b||f.start+f.addedq&&(b=b.slice(0,q-a));a+=r;f(b,"cm-"+n[d+1])}else{var d=j=0,F="",x=-1,s=null,z=function(){p&&(x+=1,s= 65 | xj)v=a;else if(b==null||b>j)B=" CodeMirror-selected",b!=null&&(v=Math.min(v,b));for(;s&&s.to!=null&&s.to<=j;)z();for(s&&(s.from>j?v=Math.min(v,s.from):(B+=" "+s.style,s.to!=null&&(v=Math.min(v,s.to))));;){var M=j+F.length,R=r;B&&(R=r?r+B:B);f(M>v?F.slice(0,v-j):F,R);if(M>=v){F=F.slice(v-j);j=v;break}j=M;F=n[d++];r="cm-"+n[d++]}}a!=null&&b==null&&f(" ","CodeMirror-selected")}e&&k.push(" =0;--j)f.old.unshift(e[j]);f.added+=f.start-a;f.start=a}else f.start-1&&(La="\r\n")})();for(var Ba=8,hb=/Mac/.test(navigator.platform),Na={},ga=35;ga<=40;++ga)Na[ga]=Na["c"+ga]=!0;var ia=document.createElement("div");x.htmlEscape=Y;var R,Ma,oa;"\n\nb".split(/\n/).length!= 68 | 3?R=function(a){for(var b=0,e,d=[];(e=a.indexOf("\n",b))>-1;)d.push(a.slice(b,a.charAt(e-1)=="\r"?e-1:e)),b=e+1;d.push(a.slice(b));return d}:R=function(a){return a.split(/\r?\n/)};x.splitLines=R;window.getSelection?(Ma=function(a){try{return{start:a.selectionStart,end:a.selectionEnd}}catch(b){return null}},Db?oa=function(a,b,e){b==e?a.setSelectionRange(b,e):(a.setSelectionRange(b,e-1),window.getSelection().modify("extend","forward","character"))}:oa=function(a,b,e){try{a.setSelectionRange(b,e)}catch(d){}}): 69 | (Ma=function(a){try{var b=a.ownerDocument.selection.createRange()}catch(e){return null}if(!b||b.parentElement()!=a)return null;var d=a.value,f=d.length,k=a.createTextRange();k.moveToBookmark(b.getBookmark());var j=a.createTextRange();j.collapse(!1);if(k.compareEndPoints("StartToEnd",j)>-1)return{start:f,end:f};a=-k.moveStart("character",-f);for(b=d.indexOf("\r");b>-1&&b-1)return{start:a,end:f};f=-k.moveEnd("character",-f);for(b=d.indexOf("\r");b> 70 | -1&&b -1&&n-1&&n =2&&r==">"){q.tokenize=M;break}p=r=="-"?p+1:0}return s("comment","comment")}function z(j,q){for(var p=!1,r;(r=j.next())!=null;){if(p&&r=="/"){q.tokenize=M;break}p=r=="*"}return s("comment","comment")}function M(j,q){var p=j.next();if(p=="@")return j.eatWhile(/\w/), 72 | s("meta",j.current());if(p=="/"&&j.eat("*"))return q.tokenize=z,z(j,q);if(p=="<"&&j.eat("!"))return q.tokenize=B,B(j,q);if(p=="=")s(null,"compare");else{if(p!="~"&&p!="|"||!j.eat("=")){if(p=='"'||p=="'")return q.tokenize=Y(p),q.tokenize(j,q);if(p=="#")return j.eatWhile(/\w/),s("atom","hash");if(p=="!")return j.match(/^\s*\w*/),s("keyword","important");if(/\d/.test(p))return j.eatWhile(/[\w.%]/),s("number","unit");if(/[,.+>*\/]/.test(p))return s(null,"select-op");if(/[;{}:\[\]]/.test(p))return s(null, 73 | p);j.eatWhile(/[\w\\\-_]/);return s("variable","variable")}return s(null,"compare")}}function s(j,q){r=q;return j}var wa=ha.indentUnit,r;return{startState:function(j){return{tokenize:M,baseIndent:j||0,stack:[]}},token:function(j,q){if(j.eatSpace())return null;var p=q.tokenize(j,q),s=q.stack[q.stack.length-1];if(r=="hash"&&s=="rule")p="atom";else if(p=="variable")if(s=="rule")p="number";else if(!s||s=="@media{")p="tag";s=="rule"&&/^[\{\};]$/.test(r)&&q.stack.pop();r=="{"?s=="@media"?q.stack[q.stack.length- 74 | 1]="@media{":q.stack.push("{"):r=="}"?q.stack.pop():r=="@media"?q.stack.push("@media"):s=="{"&&r!="comment"&&q.stack.push("rule");return p},indent:function(j,q){var p=j.stack.length;/^\}/.test(q)&&(p-=j.stack[j.stack.length-1]=="rule"?2:1);return j.baseIndent+p*wa},electricChars:"}"}});CodeMirror.defineMIME("text/css","css"); -------------------------------------------------------------------------------- /document-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/document-code.png -------------------------------------------------------------------------------- /folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/folder.png -------------------------------------------------------------------------------- /icon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon-2.png -------------------------------------------------------------------------------- /icon-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon-3.png -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon.png -------------------------------------------------------------------------------- /icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon128.png -------------------------------------------------------------------------------- /icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon16.png -------------------------------------------------------------------------------- /icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon32.png -------------------------------------------------------------------------------- /icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/icon48.png -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (C) 2011 by Lim Chee Aun, http://cheeaun.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "__MSG_extName__", 3 | "version": "0.9", 4 | "description": "__MSG_extDesc__", 5 | "icons": { 6 | "16": "icon16.png", 7 | "48": "icon48.png", 8 | "128": "icon128.png" 9 | }, 10 | "browser_action": { 11 | "default_icon": "icon.png", 12 | "popup": "popup.html" 13 | }, 14 | "options_page": "options.html", 15 | "background_page": "background.html", 16 | "permissions": [ 17 | " ", "chrome://favicon/", "bookmarks", "tabs" 18 | ], 19 | "minimum_chrome_version": "9", 20 | "default_locale": "en", 21 | "omnibox": { 22 | "keyword" : "*" 23 | } 24 | } -------------------------------------------------------------------------------- /neat-bookmarks-header-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/neat-bookmarks-header-bg.png -------------------------------------------------------------------------------- /neat-bookmarks-options-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/neat-bookmarks-options-screenshot.png -------------------------------------------------------------------------------- /neat-bookmarks-promo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/neat-bookmarks-promo-large.png -------------------------------------------------------------------------------- /neat-bookmarks-promo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/neat-bookmarks-promo-small.png -------------------------------------------------------------------------------- /neat-bookmarks-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/neat-bookmarks-screenshot.png -------------------------------------------------------------------------------- /neat.css: -------------------------------------------------------------------------------- 1 | body{ 2 | direction: __MSG_@@bidi_dir__; 3 | font: menu; 4 | color: #000; 5 | background-color: #fff; 6 | margin: 0; 7 | padding: 0; 8 | cursor: default; 9 | -webkit-user-drag: none; 10 | -webkit-user-select: none; 11 | overflow: hidden; 12 | width: 320px; 13 | height: 530px; 14 | } 15 | body.linux{ 16 | font-size: 12px; 17 | } 18 | body.transitional{ 19 | -webkit-transition-property: height; 20 | } 21 | body[data-zoom='90']>*:not(menu), 22 | body[data-zoom='90'] menu[type=context] command{ 23 | zoom: .9; 24 | } 25 | body[data-zoom='90'] #drop-overlay.bookmark{ /* zooming out makes the line too hard to see */ 26 | border-top: 0; 27 | } 28 | body[data-zoom='110']>*:not(menu), 29 | body[data-zoom='110'] menu[type=context] command{ 30 | zoom: 1.1; 31 | } 32 | body[data-zoom='120']>*:not(menu), 33 | body[data-zoom='120'] menu[type=context] command{ 34 | zoom: 1.2; 35 | } 36 | body[data-zoom='130']>*:not(menu), 37 | body[data-zoom='130'] menu[type=context] command{ 38 | zoom: 1.3; 39 | } 40 | body[data-zoom='140']>*:not(menu), 41 | body[data-zoom='140'] menu[type=context] command{ 42 | zoom: 1.4; 43 | } 44 | body[data-zoom='150']>*:not(menu), 45 | body[data-zoom='150'] menu[type=context] command{ 46 | zoom: 1.5; 47 | } 48 | input{ 49 | -webkit-box-sizing: border-box; 50 | box-sizing: border-box; 51 | font: menu; 52 | } 53 | body.linux input{ 54 | font-size: 12px; 55 | } 56 | #container{ 57 | display: -webkit-box; 58 | -webkit-box-orient: vertical; 59 | display: box; 60 | box-orient: vertical; 61 | position: absolute; 62 | top: 0; 63 | right: 0; 64 | bottom: 0; 65 | left: 0; 66 | } 67 | #search{ 68 | padding: 0 2px 2px; 69 | } 70 | #search input{ 71 | width: 100%; 72 | margin: 2px 0; 73 | padding: 2px; 74 | } 75 | #results, 76 | #tree{ 77 | background-color: #eee; 78 | overflow: auto; 79 | outline: 0; 80 | padding: 3px 0; 81 | -webkit-box-shadow: inset 0 4px 4px -4px rgba(0,0,0,.1); 82 | -webkit-box-flex: 1; 83 | box-flex: 1; 84 | text-shadow: 0 1px #f6f6f6; 85 | position: relative; 86 | } 87 | #results ul, 88 | #results ul li, 89 | #tree ul, 90 | #tree ul li{ 91 | list-style: none; 92 | margin: 0; 93 | padding: 0; 94 | display: block; 95 | } 96 | #results ul li a, 97 | #tree ul li a, 98 | #tree ul li span{ 99 | display: block; 100 | line-height: 1.67em; 101 | padding: 0 4px; 102 | text-decoration: none; 103 | color: #000; 104 | outline: 0; 105 | white-space: nowrap; 106 | text-overflow: ellipsis; 107 | overflow: hidden; 108 | } 109 | #results ul li a *, 110 | #tree ul li a *, 111 | #tree ul li span *{ 112 | pointer-events: none; 113 | } 114 | #tree ul li span .twisty{ 115 | display: inline-block; 116 | position: relative; 117 | width: 0; 118 | height: 0; 119 | border-width: 4.5px 0 4.5px 8px; 120 | border-color: transparent transparent transparent #84919f; 121 | border-style: solid; 122 | margin: 0 4px; 123 | -webkit-transition: -webkit-transform .15s; 124 | -webkit-transform: scaleX(.99); 125 | } 126 | .chrome-536 #tree ul li span .twisty{ /* Chrome build 536 dev bug */ 127 | -webkit-transition-duration: 0s; 128 | } 129 | .rtl #tree ul li span .twisty{ 130 | -webkit-transform: scaleX(-1); 131 | } 132 | #tree ul li.open>span .twisty{ 133 | -webkit-transform: rotate(90deg); 134 | } 135 | .rtl #tree ul li.open>span .twisty{ 136 | -webkit-transform: scaleX(-1) rotate(90deg); 137 | } 138 | #results ul li a img, 139 | #results ul li span img, 140 | #tree ul li a img, 141 | #tree ul li span img{ 142 | margin-top: -2px; 143 | vertical-align: middle; 144 | margin-__MSG_@@bidi_end_edge__: 4px; 145 | } 146 | #results ul li a img, 147 | #tree ul li a img{ 148 | margin-__MSG_@@bidi_start_edge__: 16px; 149 | } 150 | #results ul li i, 151 | #tree ul li i{ 152 | font-style: normal; 153 | } 154 | #results ul li a:hover i, 155 | #tree ul li a:hover i{ 156 | text-decoration: underline; 157 | } 158 | #results ul li a:active, 159 | #results ul li a.active, 160 | #results ul li a:focus, 161 | #tree ul li a:active, 162 | #tree ul li span:active, 163 | #tree ul li a.active, 164 | #tree ul li span.active, 165 | #tree ul li a:focus, 166 | #tree ul li span:focus, 167 | menu[type=context] command:focus{ 168 | color: #fff; 169 | background-color: #4687cb; 170 | background-image: -webkit-gradient(linear, left top, left bottom, from(#6fa6de), to(#1e6cbb)); 171 | -webkit-box-shadow: 0 -1px #5594d2; 172 | text-shadow: 0 0 rgba(255,255,255,.5), 0 1px rgba(0,0,0,.5); 173 | outline: 0; 174 | } 175 | .searchFocus #results ul>li:first-child a{ 176 | background-color: rgba(43,93,205,.2); 177 | } 178 | #tree ul li span:active .twisty, 179 | #tree ul li span.active .twisty, 180 | #tree ul li span:focus .twisty{ 181 | border-color: transparent transparent transparent #e5eef8; 182 | } 183 | #tree ul ul{ 184 | height: 0; 185 | overflow: hidden; 186 | } 187 | #tree .open>ul{ 188 | height: auto; 189 | } 190 | @-webkit-keyframes blueFade { 191 | 0% { 192 | background-color: transparent; 193 | } 194 | 10%{ 195 | background-color: rgba(43,93,205,.2); 196 | } 197 | 100% { 198 | background-color: transparent; 199 | } 200 | } 201 | #tree ul li a.focus, 202 | #tree ul li span.focus{ 203 | -webkit-animation-name: blueFade; 204 | -webkit-animation-duration: 3s; 205 | } 206 | 207 | #bookmark-clone{ 208 | position: absolute; 209 | left: -999px; 210 | margin: -1em 0 0 -24px; 211 | white-space: nowrap; 212 | line-height: 1em; 213 | padding: .3em; 214 | padding-__MSG_@@bidi_end_edge__: .5em; 215 | -webkit-mask-image: -webkit-gradient(linear, left top, 320 top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); 216 | pointer-events: none; 217 | cursor: default; 218 | } 219 | .rtl #bookmark-clone{ 220 | margin-left: 24px; 221 | -webkit-mask-image: -webkit-gradient(linear, right top, -320 top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); 222 | } 223 | #bookmark-clone img{ 224 | vertical-align: text-top; 225 | margin-__MSG_@@bidi_end_edge__: 4px; 226 | } 227 | #bookmark-clone i{ 228 | font-style: normal; 229 | } 230 | #drop-overlay{ 231 | display: block; 232 | width: 100%; 233 | position: absolute; 234 | left: -999px; 235 | pointer-events: none; 236 | margin: -1px 0 0; 237 | -webkit-box-sizing: border-box; 238 | -box-sizing: border-box; 239 | } 240 | #drop-overlay.bookmark{ 241 | margin-__MSG_@@bidi_start_edge__: -3px; 242 | height: 3px; 243 | background-color: #000; 244 | border: 1px solid #fff; 245 | } 246 | #drop-overlay.folder{ 247 | background-color: rgba(43,93,205,.2); 248 | border: 1px solid #5594d2; 249 | border-radius: 2px; 250 | } 251 | 252 | menu[type=context]{ 253 | -webkit-transition: opacity .3s; 254 | opacity: 0; 255 | margin: 0; 256 | padding: 5px 0; 257 | list-style: none; 258 | position: absolute; 259 | left: -999px; 260 | border: 1px solid #bbb; 261 | border-radius: 5px; 262 | background-color: rgba(255,255,255,.96); 263 | box-shadow: 0 2px 6px rgba(0,0,0,.2); 264 | -webkit-box-shadow: 0 2px 6px rgba(0,0,0,.2); 265 | outline: 0; 266 | max-width: 100%; 267 | } 268 | menu[type=context] command{ 269 | display: block; 270 | padding: 0 10px; 271 | line-height: 20px; 272 | text-shadow: none; 273 | overflow: hidden; 274 | white-space: nowrap; 275 | text-overflow: ellipsis; 276 | } 277 | /* convert title-style to sentence-style capitalization, for Windows */ 278 | .win menu[type=context] command{ 279 | text-transform: lowercase; 280 | } 281 | .win menu[type=context] command:first-letter{ 282 | text-transform: uppercase; 283 | } 284 | menu[type=context] hr{ 285 | border: 0; 286 | padding: 0; 287 | height: 1px; 288 | margin: 2px 0; 289 | background-color: #eee; 290 | pointer-events: none; 291 | } 292 | 293 | menu[type=context].hide-editables hr, 294 | menu[type=context].hide-editables #folder-edit, 295 | menu[type=context].hide-editables #folder-delete{ 296 | display: none; 297 | } 298 | 299 | #resizer{ 300 | position: absolute; 301 | width: 4px; 302 | height: 100%; 303 | __MSG_@@bidi_start_edge__: 0; 304 | top: 0; 305 | cursor: col-resize; 306 | } 307 | 308 | #cover{ 309 | position: absolute; 310 | top: 0; 311 | left: -100%; 312 | bottom: 0; 313 | width: 100%; 314 | opacity: 0; 315 | background-color: rgba(255,255,255,.5); 316 | } 317 | .transitional #cover{ 318 | -webkit-transition: opacity .3s; 319 | } 320 | .needAlert #cover, 321 | .needConfirm #cover, 322 | .needEdit #cover{ 323 | left: 0; 324 | opacity: 1; 325 | } 326 | 327 | .dialog{ 328 | position: absolute; 329 | top: -150px; 330 | left: 0; 331 | right: 0; 332 | opacity: 0; 333 | background-color: #fff; 334 | padding: 1em; 335 | border-bottom: 1px solid #e0e0e0; 336 | -webkit-box-shadow: 0 0 100px rgba(0,0,0,.1); 337 | box-shadow: 0 0 100px rgba(0,0,0,.1); 338 | } 339 | .transitional .dialog{ 340 | -webkit-transition-property: opacity, top; 341 | -webkit-transition-duration: .3s; 342 | } 343 | .dialog-text{ 344 | padding: 0; 345 | margin: 0; 346 | line-height: 1.4em; 347 | font-size: 110%; 348 | } 349 | .dialog .buttons{ 350 | margin: 1em 0 0; 351 | text-align: __MSG_@@bidi_end_edge__; 352 | } 353 | .dialog .buttons button{ 354 | padding: .3em 1.5em; 355 | } 356 | .dialog pre{ 357 | white-space: pre-line; 358 | margin: 0; 359 | padding: 5px; 360 | line-height: 1.1em; 361 | -webkit-user-select: text; 362 | cursor: text; 363 | background-color: #fafafa; 364 | text-shadow: none; 365 | } 366 | 367 | #edit-dialog .dialog-text{ 368 | margin: 0; 369 | font-weight: bold; 370 | } 371 | #edit-dialog input{ 372 | width: 100%; 373 | padding: 2px; 374 | } 375 | #edit-dialog input:invalid{ 376 | outline-color: red; 377 | } 378 | #edit-dialog .buttons{ 379 | margin: 0; 380 | } 381 | #edit-dialog .buttons button{ 382 | font-weight: bold; 383 | } 384 | 385 | .needAlert #alert-dialog, 386 | .needConfirm #confirm-dialog, 387 | .needEdit #edit-dialog{ 388 | top: 0; 389 | opacity: 1; 390 | } -------------------------------------------------------------------------------- /neat.js: -------------------------------------------------------------------------------- 1 | (function(window){ 2 | var document = window.document; 3 | var chrome = window.chrome; 4 | var localStorage = window.localStorage; 5 | var navigator = window.navigator; 6 | var body = document.body; 7 | var _m = chrome.i18n.getMessage; 8 | 9 | // Error alert 10 | var AlertDialog = { 11 | open: function(dialog){ 12 | if (!dialog) return; 13 | $('alert-dialog-text').innerHTML = dialog; 14 | body.addClass('needAlert'); 15 | }, 16 | close: function(){ 17 | body.removeClass('needAlert'); 18 | } 19 | }; 20 | window.addEventListener('error', function(){ 21 | AlertDialog.open('' + _m('errorOccured') + '
' + _m('reportedToDeveloper')); 22 | }, false); 23 | 24 | // Platform detection 25 | var os = (navigator.platform.toLowerCase().match(/mac|win|linux/i) || ['other'])[0]; 26 | body.addClass(os); 27 | 28 | // Chrome version detection 29 | var version = (function(){ 30 | var v = {}; 31 | var keys = ['major', 'minor', 'build', 'patch']; 32 | var matches = navigator.userAgent.match(/chrome\/([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)/i); 33 | if (!matches) return null; 34 | matches.slice(1).forEach(function(m, i){ 35 | v[keys[i]] = m.toInt(); 36 | }); 37 | return v; 38 | })(); 39 | 40 | // Some i18n 41 | $('search-input').placeholder = _m('searchBookmarks'); 42 | $('edit-dialog-name').placeholder = _m('name'); 43 | $('edit-dialog-url').placeholder = _m('url'); 44 | $each({ 45 | 'bookmark-new-tab': 'openNewTab', 46 | 'bookmark-new-window': 'openNewWindow', 47 | 'bookmark-new-incognito-window': 'openIncognitoWindow', 48 | 'bookmark-edit': 'edit', 49 | 'bookmark-delete': 'delete', 50 | 'folder-window': 'openBookmarks', 51 | 'folder-new-window': 'openBookmarksNewWindow', 52 | 'folder-new-incognito-window': 'openBookmarksIncognitoWindow', 53 | 'folder-edit': 'edit', 54 | 'folder-delete': 'deleteEllipsis', 55 | 'edit-dialog-button': 'save' 56 | }, function(msg, id){ 57 | var el = $(id), m = _m(msg); 58 | if (el.tagName == 'COMMAND') el.label = m; 59 | el.textContent = m; 60 | }); 61 | 62 | // RTL indicator 63 | var rtl = (body.getComputedStyle('direction') == 'rtl'); 64 | if (rtl) body.addClass('rtl'); 65 | 66 | // Init some variables 67 | var opens = localStorage.opens ? JSON.parse(localStorage.opens) : []; 68 | var rememberState = !localStorage.dontRememberState; 69 | var a = document.createElement('a'); 70 | var httpsPattern = /^https?:\/\//i; 71 | 72 | // Adaptive bookmark tooltips 73 | var adaptBookmarkTooltips = function(){ 74 | var bookmarks = document.querySelectorAll('li.child a'); 75 | for (var i=0, l=bookmarks.length; ibookmark.offsetWidth){ 83 | var text = bookmark.querySelector('i').textContent; 84 | var title = bookmark.title; 85 | if (text != title){ 86 | bookmark.title = text + '\n' + title; 87 | bookmark.addClass('titled'); 88 | } 89 | } 90 | } 91 | }; 92 | 93 | var generateBookmarkHTML = function(title, url, extras){ 94 | if (!extras) extras = ''; 95 | var u = url.htmlspecialchars(); 96 | var favicon = 'chrome://favicon/' + u; 97 | var tooltipURL = url; 98 | if (/^javascript:/i.test(url)){ 99 | if (url.length > 140) tooltipURL = url.slice(0, 140) + '...'; 100 | favicon = 'document-code.png'; 101 | } 102 | tooltipURL = tooltipURL.htmlspecialchars(); 103 | var name = title.htmlspecialchars() || (httpsPattern.test(url) ? url.replace(httpsPattern, '') : _m('noTitle')); 104 | return '' 105 | + ' ' + name + '' 106 | + ''; 107 | }; 108 | 109 | var generateHTML = function(data, level){ 110 | if (!level) level = 0; 111 | var paddingStart = 14*level; 112 | var group = (level == 0) ? 'tree' : 'group'; 113 | var html = '
'; 114 | 115 | for (var i=0, l=data.length; i
'; 158 | return html; 159 | }; 160 | 161 | var $tree = $('tree'); 162 | chrome.bookmarks.getTree(function(tree){ 163 | var html = generateHTML(tree[0].children); 164 | $tree.innerHTML = html; 165 | 166 | if (rememberState) $tree.scrollTop = localStorage.scrollTop || 0; 167 | 168 | var focusID = localStorage.focusID; 169 | if (typeof focusID != 'undefined' && focusID != null){ 170 | var focusEl = $('neat-tree-item-' + focusID); 171 | if (focusEl){ 172 | var oriOverflow = $tree.style.overflow; 173 | $tree.style.overflow = 'hidden'; 174 | focusEl.style.width = '100%'; 175 | focusEl.firstElementChild.addClass('focus'); 176 | setTimeout(function(){ 177 | $tree.style.overflow = oriOverflow; 178 | }, 1); 179 | setTimeout(function(){ 180 | localStorage.removeItem('focusID'); 181 | }, 4000); 182 | } 183 | } 184 | 185 | setTimeout(adaptBookmarkTooltips, 100); 186 | 187 | tree = null; 188 | }); 189 | 190 | // Events for the tree 191 | $tree.addEventListener('scroll', function(){ 192 | localStorage.scrollTop = $tree.scrollTop; 193 | }); 194 | $tree.addEventListener('focus', function(e){ 195 | var el = e.target; 196 | var tagName = el.tagName; 197 | var focusEl = $tree.querySelector('.focus'); 198 | if (focusEl) focusEl.removeClass('focus'); 199 | if (tagName == 'A' || tagName == 'SPAN'){ 200 | var id = el.parentNode.id.replace('neat-tree-item-', ''); 201 | localStorage.focusID = id; 202 | } else { 203 | localStorage.focusID = null; 204 | } 205 | }, true); 206 | var closeUnusedFolders = localStorage.closeUnusedFolders; 207 | $tree.addEventListener('click', function(e){ 208 | if (e.button != 0) return; 209 | var el = e.target; 210 | var tagName = el.tagName; 211 | if (tagName != 'SPAN') return; 212 | if (e.shiftKey || e.ctrlKey) return; 213 | var parent = el.parentNode; 214 | parent.toggleClass('open'); 215 | var expanded = parent.hasClass('open'); 216 | parent.setAttribute('aria-expanded', expanded); 217 | var children = parent.querySelector('ul'); 218 | if (!children){ 219 | var id = parent.id.replace('neat-tree-item-', ''); 220 | chrome.bookmarks.getChildren(id, function(children){ 221 | var html = generateHTML(children, parseInt(parent.parentNode.dataset.level)+1); 222 | var div = document.createElement('div'); 223 | div.innerHTML = html; 224 | var ul = div.querySelector('ul'); 225 | ul.inject(parent); 226 | div.destroy(); 227 | setTimeout(adaptBookmarkTooltips, 100); 228 | }); 229 | } 230 | if (closeUnusedFolders && expanded){ 231 | var siblings = parent.getSiblings('li'); 232 | for (var i=0, l=siblings.length; i' 132 | + '' 133 | + ' ' + (title || _m('noTitle')) + '' 134 | + ''; 135 | if (isOpen){ 136 | if (children){ 137 | html += generateHTML(children, level+1); 138 | } else { 139 | (function(_id){ 140 | chrome.bookmarks.getChildren(_id, function(children){ 141 | var html = generateHTML(children, level+1); 142 | var div = document.createElement('div'); 143 | div.innerHTML = html; 144 | var ul = div.querySelector('ul'); 145 | ul.inject($('neat-tree-item-' + _id)); 146 | div.destroy(); 147 | }); 148 | })(id); 149 | } 150 | } 151 | } else { 152 | html += '
- ' 153 | + generateBookmarkHTML(title, url, 'style="-webkit-padding-start: ' + paddingStart + 'px"'); 154 | } 155 | html += '
'; 156 | } 157 | html += '1){ 277 | results.sort(function(a, b){ 278 | var aTitle = a.title; 279 | var bTitle = b.title; 280 | var aIndexTitle = aTitle.toLowerCase().indexOf(v); 281 | var bIndexTitle = bTitle.toLowerCase().indexOf(v); 282 | if (aIndexTitle >= 0 || bIndexTitle >= 0){ 283 | if (aIndexTitle < 0) aIndexTitle = Infinity; 284 | if (bIndexTitle < 0) bIndexTitle = Infinity; 285 | return aIndexTitle - bIndexTitle; 286 | } 287 | var aTestTitle = vPattern.test(aTitle); 288 | var bTestTitle = vPattern.test(bTitle); 289 | if (aTestTitle && !bTestTitle) return -1; 290 | if (!aTestTitle && bTestTitle) return 1; 291 | return b.dateAdded - a.dateAdded; 292 | }); 293 | results = results.slice(0, 100); // 100 is enough 294 | } 295 | var html = ' '; 296 | for (var i=0, l=results.length; i
'; 303 | $tree.style.display = 'none'; 304 | $results.innerHTML = html; 305 | $results.style.display = 'block'; 306 | 307 | var lis = $results.querySelectorAll('li'); 308 | Array.forEach(function(li){ 309 | var parentId = li.dataset.parentid; 310 | chrome.bookmarks.get(parentId, function(node){ 311 | if (!node || !node.length) return; 312 | var a = li.querySelector('a'); 313 | a.title = _m('parentFolder', node[0].title) + '\n' + a.title; 314 | }); 315 | }, lis); 316 | 317 | results = null; 318 | vPattern = null; 319 | lis = null; 320 | }); 321 | }; 322 | searchInput.addEventListener('input', search); 323 | 324 | searchInput.addEventListener('keydown', function(e){ 325 | var key = e.keyCode; 326 | var focusID = localStorage.focusID; 327 | if (key == 40 && searchInput.value.length == searchInput.selectionEnd){ // down 328 | e.preventDefault(); 329 | if (searchMode){ 330 | $results.querySelector('ul>li:first-child a').focus(); 331 | } else { 332 | $tree.querySelector('ul>li:first-child').querySelector('span, a').focus(); 333 | } 334 | } else if (key == 13 && searchInput.value.length){ // enter 335 | var item = $results.querySelector('ul>li:first-child a'); 336 | item.focus(); 337 | setTimeout(function(){ 338 | var event = document.createEvent('MouseEvents'); 339 | event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 340 | item.dispatchEvent(event); 341 | }, 30); 342 | } else if (key == 9 && !searchMode){ // tab 343 | if (typeof focusID != 'undefined' && focusID != null){ 344 | var focusEl = $('neat-tree-item-' + focusID); 345 | if (focusEl){ 346 | e.preventDefault(); 347 | focusEl.firstElementChild.focus(); 348 | } 349 | } else { 350 | var bound = $tree.scrollTop; 351 | var items = $tree.querySelectorAll('a, span'); 352 | var firstItem = Array.filter(function(item){ 353 | return !!item.parentElement.offsetHeight && ((item.offsetTop + item.offsetHeight) > bound); 354 | }, items)[0]; 355 | if (firstItem) firstItem.focus(); 356 | } 357 | // Pressing esc shouldn't close the popup when search field has value 358 | } else if (e.keyCode == 27 && searchInput.value){ // esc 359 | e.preventDefault(); 360 | searchInput.value = ''; 361 | search(); 362 | } 363 | }); 364 | 365 | searchInput.addEventListener('focus', function(){ 366 | body.addClass('searchFocus'); 367 | }); 368 | searchInput.addEventListener('blur', function(){ 369 | body.removeClass('searchFocus'); 370 | }); 371 | 372 | // Saved search query 373 | if (rememberState && localStorage.searchQuery){ 374 | searchInput.value = localStorage.searchQuery; 375 | search(); 376 | searchInput.select(); 377 | searchInput.scrollLeft = 0; 378 | } 379 | 380 | // Popup auto-height 381 | var resetHeight = function(){ 382 | var zoomLevel = localStorage.zoom ? localStorage.zoom.toInt()/100 : 1; 383 | setTimeout(function(){ 384 | var neatTree = $tree.firstElementChild; 385 | var fullHeight = (neatTree.offsetHeight + $tree.offsetTop + 16)*zoomLevel; 386 | // Slide up faster than down 387 | body.style.webkitTransitionDuration = (fullHeight < window.innerHeight) ? '.3s' : '.1s'; 388 | var maxHeight = screen.height - window.screenY - 50; 389 | var height = Math.max(200, Math.min(fullHeight, maxHeight)); 390 | body.style.height = height + 'px'; 391 | localStorage.popupHeight = height; 392 | }, 100); 393 | }; 394 | if (!searchMode) resetHeight(); 395 | $tree.addEventListener('click', resetHeight); 396 | $tree.addEventListener('keyup', resetHeight); 397 | 398 | // Confirm dialog 399 | var ConfirmDialog = { 400 | open: function(opts){ 401 | if (!opts) return; 402 | $('confirm-dialog-text').innerHTML = opts.dialog.widont(); 403 | $('confirm-dialog-button-1').innerHTML = opts.button1; 404 | $('confirm-dialog-button-2').innerHTML = opts.button2; 405 | if (opts.fn1) ConfirmDialog.fn1 = opts.fn1; 406 | if (opts.fn2) ConfirmDialog.fn2 = opts.fn2; 407 | $('confirm-dialog-button-' + (opts.focusButton || 1)).focus(); 408 | document.body.addClass('needConfirm'); 409 | }, 410 | close: function(){ 411 | document.body.removeClass('needConfirm'); 412 | }, 413 | fn1: function(){}, 414 | fn2: function(){} 415 | }; 416 | 417 | // Edit dialog 418 | var EditDialog = window.EditDialog = { 419 | open: function(opts){ 420 | if (!opts) return; 421 | $('edit-dialog-text').innerHTML = opts.dialog.widont(); 422 | if (opts.fn) EditDialog.fn = opts.fn; 423 | var type = opts.type || 'bookmark'; 424 | var name = $('edit-dialog-name'); 425 | name.value = opts.name; 426 | name.focus(); 427 | name.select(); 428 | name.scrollLeft = 0; // very delicate, show first few words instead of last 429 | var url = $('edit-dialog-url'); 430 | if (type == 'bookmark'){ 431 | url.style.display = ''; 432 | url.disabled = false; 433 | url.value = opts.url; 434 | } else { 435 | url.style.display = 'none'; 436 | url.disabled = true; 437 | url.value = ''; 438 | } 439 | body.addClass('needEdit'); 440 | }, 441 | close: function(){ 442 | var urlInput = $('edit-dialog-url'); 443 | var url = urlInput.value; 444 | if (!urlInput.validity.valid){ 445 | urlInput.value = 'http://' + url; 446 | if (!urlInput.validity.valid) url = ''; // if still invalid, fuck it. 447 | url = 'http://' + url; 448 | } 449 | EditDialog.fn($('edit-dialog-name').value, url); 450 | body.removeClass('needEdit'); 451 | }, 452 | fn: function(){} 453 | }; 454 | 455 | // Bookmark handling 456 | var dontConfirmOpenFolder = !!localStorage.dontConfirmOpenFolder; 457 | var bookmarkClickStayOpen = !!localStorage.bookmarkClickStayOpen; 458 | var openBookmarksLimit = 10; 459 | var actions = { 460 | 461 | openBookmark: function(url){ 462 | chrome.tabs.getSelected(null, function(tab){ 463 | chrome.tabs.update(tab.id, { 464 | url: decodeURIComponent(url) 465 | }); 466 | if (!bookmarkClickStayOpen) setTimeout(window.close, 200); 467 | }); 468 | }, 469 | 470 | openBookmarkNewTab: function(url, selected, blankTabCheck){ 471 | var open = function(){ 472 | chrome.tabs.create({ 473 | url: url, 474 | selected: selected 475 | }); 476 | }; 477 | if (blankTabCheck){ 478 | chrome.tabs.getSelected(null, function(tab){ 479 | if (/^chrome:\/\/newtab/i.test(tab.url)){ 480 | chrome.tabs.update(tab.id, { 481 | url: url 482 | }); 483 | if (!bookmarkClickStayOpen) setTimeout(window.close, 200); 484 | } else { 485 | open(); 486 | } 487 | }); 488 | } else { 489 | open(); 490 | } 491 | }, 492 | 493 | openBookmarkNewWindow: function(url, incognito){ 494 | chrome.windows.create({ 495 | url: url, 496 | incognito: incognito 497 | }); 498 | }, 499 | 500 | openBookmarks: function(urls, selected){ 501 | var urlsLen = urls.length; 502 | var open = function(){ 503 | chrome.tabs.create({ 504 | url: urls.shift(), 505 | selected: selected // first tab will be selected 506 | }); 507 | for (var i=0, l=urls.length; i' 300 | + generateBookmarkHTML(result.title, result.url); 301 | } 302 | html += ' openBookmarksLimit){ 515 | ConfirmDialog.open({ 516 | dialog: _m('confirmOpenBookmarks', ''+urlsLen), 517 | button1: '' + _m('open') + '', 518 | button2: _m('nope'), 519 | fn1: open 520 | }); 521 | } else { 522 | open(); 523 | } 524 | }, 525 | 526 | openBookmarksNewWindow: function(urls, incognito){ 527 | var urlsLen = urls.length; 528 | var open = function(){ 529 | chrome.windows.create({ 530 | url: urls, 531 | incognito: incognito 532 | }); 533 | }; 534 | if (!dontConfirmOpenFolder && urlsLen > openBookmarksLimit){ 535 | var dialog = incognito ? _m('confirmOpenBookmarksNewIncognitoWindow', ''+urlsLen) : _m('confirmOpenBookmarksNewWindow', ''+urlsLen); 536 | ConfirmDialog.open({ 537 | dialog: dialog, 538 | button1: '' + _m('open') + '', 539 | button2: _m('nope'), 540 | fn1: open 541 | }); 542 | } else { 543 | open(); 544 | } 545 | }, 546 | 547 | editBookmarkFolder: function(id){ 548 | chrome.bookmarks.get(id, function(nodeList){ 549 | if (!nodeList.length) return; 550 | var node = nodeList[0]; 551 | var url = node.url; 552 | var isBookmark = !!url; 553 | var type = isBookmark ? 'bookmark' : 'folder'; 554 | var dialog = isBookmark ? _m('editBookmark') : _m('editFolder'); 555 | EditDialog.open({ 556 | dialog: dialog, 557 | type: type, 558 | name: node.title, 559 | url: decodeURIComponent(url), 560 | fn: function(name, url){ 561 | chrome.bookmarks.update(id, { 562 | title: name, 563 | url: isBookmark ? url : '' 564 | }, function(n){ 565 | var title = n.title; 566 | var url = n.url; 567 | var li = $('neat-tree-item-' + id); 568 | if (li){ 569 | if (isBookmark){ 570 | var css = li.querySelector('a').style.cssText; 571 | li.innerHTML = generateBookmarkHTML(title, url, 'style="' + css + '"'); 572 | } else { 573 | var i = li.querySelector('i'); 574 | var name = title || (httpsPattern.test(url) ? url.replace(httpsPattern, '') : _m('noTitle')); 575 | i.textContent = name; 576 | } 577 | } 578 | if (searchMode){ 579 | li = $('results-item-' + id); 580 | li.innerHTML = generateBookmarkHTML(title, url); 581 | } 582 | li.firstElementChild.focus(); 583 | }); 584 | } 585 | }); 586 | }); 587 | }, 588 | 589 | deleteBookmark: function(id){ 590 | var li1 = $('neat-tree-item-' + id); 591 | var li2 = $('results-item-' + id); 592 | chrome.bookmarks.remove(id, function(){ 593 | if (li1){ 594 | var nearLi1 = li1.nextElementSibling || li1.previousElementSibling; 595 | li1.destroy(); 596 | if (!searchMode && nearLi1) nearLi1.querySelector('a, span').focus(); 597 | } 598 | if (li2){ 599 | var nearLi2 = li2.nextElementSibling || li2.previousElementSibling; 600 | li2.destroy(); 601 | if (searchMode && nearLi2) nearLi2.querySelector('a, span').focus(); 602 | } 603 | }); 604 | }, 605 | 606 | deleteBookmarks: function(id, bookmarkCount, folderCount){ 607 | var li = $('neat-tree-item-' + id); 608 | var item = li.querySelector('span'); 609 | if (bookmarkCount || folderCount){ 610 | var dialog = ''; 611 | var folderName = '' + item.textContent.trim() + ''; 612 | if (bookmarkCount && folderCount){ 613 | dialog = _m('confirmDeleteFolderSubfoldersBookmarks', [folderName, folderCount, bookmarkCount]); 614 | } else if (bookmarkCount){ 615 | dialog = _m('confirmDeleteFolderBookmarks', [folderName, bookmarkCount]); 616 | } else { 617 | dialog = _m('confirmDeleteFolderSubfolders', [folderName, folderCount]); 618 | } 619 | ConfirmDialog.open({ 620 | dialog: dialog, 621 | button1: '' + _m('delete') + '', 622 | button2: _m('nope'), 623 | fn1: function(){ 624 | chrome.bookmarks.removeTree(id, function(){ 625 | li.destroy(); 626 | }); 627 | var nearLi = li.nextElementSibling || li.previousElementSibling; 628 | if (nearLi) nearLi.querySelector('a, span').focus(); 629 | }, 630 | fn2: function(){ 631 | li.querySelector('a, span').focus(); 632 | } 633 | }); 634 | } else { 635 | chrome.bookmarks.removeTree(id, function(){ 636 | li.destroy(); 637 | }); 638 | var nearLi = li.nextElementSibling || li.previousElementSibling; 639 | if (nearLi) nearLi.querySelector('a, span').focus(); 640 | } 641 | } 642 | 643 | }; 644 | 645 | var middleClickBgTab = !!localStorage.middleClickBgTab; 646 | var leftClickNewTab = !!localStorage.leftClickNewTab; 647 | var noOpenBookmark = false; 648 | var bookmarkHandler = function(e){ 649 | e.preventDefault(); 650 | if (e.button != 0) return; // force left-click 651 | if (noOpenBookmark){ // flag that disables opening bookmark 652 | noOpenBookmark = false; 653 | return; 654 | } 655 | var el = e.target; 656 | var ctrlMeta = (e.ctrlKey || e.metaKey); 657 | var shift = e.shiftKey; 658 | if (el.tagName == 'A'){ 659 | var url = el.href; 660 | if (ctrlMeta){ // ctrl/meta click 661 | actions.openBookmarkNewTab(url, middleClickBgTab ? shift : !shift); 662 | } else { // click 663 | if (shift){ 664 | actions.openBookmarkNewWindow(url); 665 | } else { 666 | leftClickNewTab ? actions.openBookmarkNewTab(url, true, true) : actions.openBookmark(url); 667 | } 668 | } 669 | } else if (el.tagName == 'SPAN'){ 670 | var li = el.parentNode; 671 | var id = li.id.replace('neat-tree-item-', ''); 672 | chrome.bookmarks.getChildren(id, function(children){ 673 | var urls = Array.map(function(c){ 674 | return c.url; 675 | }, children).clean(); 676 | var urlsLen = urls.length; 677 | if (!urlsLen) return; 678 | if (ctrlMeta){ // ctrl/meta click 679 | actions.openBookmarks(urls, middleClickBgTab ? shift : !shift); 680 | } else if (shift){ // shift click 681 | actions.openBookmarksNewWindow(urls); 682 | } 683 | }); 684 | } 685 | }; 686 | $tree.addEventListener('click', bookmarkHandler); 687 | $results.addEventListener('click', bookmarkHandler); 688 | var bookmarkHandlerMiddle = function(e){ 689 | if (e.button != 1) return; // force middle-click 690 | var event = document.createEvent('MouseEvents'); 691 | event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, true, false, e.shiftKey, true, 0, null); 692 | e.target.dispatchEvent(event); 693 | }; 694 | $tree.addEventListener('mouseup', bookmarkHandlerMiddle); 695 | $results.addEventListener('mouseup', bookmarkHandlerMiddle); 696 | 697 | // Disable Chrome auto-scroll feature 698 | window.addEventListener('mousedown', function(e){ 699 | if (e.button == 1) e.preventDefault(); 700 | }); 701 | 702 | // Context menu 703 | var $bookmarkContextMenu = $('bookmark-context-menu'); 704 | var $folderContextMenu = $('folder-context-menu'); 705 | 706 | var clearMenu = function(e){ 707 | currentContext = null; 708 | var active = body.querySelector('.active'); 709 | if (active){ 710 | active.removeClass('active'); 711 | // This is kinda hacky. Oh well. 712 | if (e){ 713 | var el = e.target; 714 | if (el == $tree || el == $results) active.focus(); 715 | } 716 | } 717 | $bookmarkContextMenu.style.left = '-999px'; 718 | $bookmarkContextMenu.style.opacity = 0; 719 | $folderContextMenu.style.left = '-999px'; 720 | $folderContextMenu.style.opacity = 0; 721 | }; 722 | 723 | body.addEventListener('click', clearMenu); 724 | $tree.addEventListener('scroll', clearMenu); 725 | $results.addEventListener('scroll', clearMenu); 726 | $tree.addEventListener('focus', clearMenu, true); 727 | $results.addEventListener('focus', clearMenu, true); 728 | 729 | var currentContext = null; 730 | var macCloseContextMenu = false; 731 | body.addEventListener('contextmenu', function(e){ 732 | e.preventDefault(); 733 | clearMenu(); 734 | if (os == 'mac'){ 735 | macCloseContextMenu = false; 736 | setTimeout(function(){ macCloseContextMenu = true; }, 500); 737 | } 738 | var el = e.target; 739 | if (el.tagName == 'A'){ 740 | currentContext = el; 741 | var active = body.querySelector('.active'); 742 | if (active) active.removeClass('active'); 743 | el.addClass('active'); 744 | var bookmarkMenuWidth = $bookmarkContextMenu.offsetWidth; 745 | var bookmarkMenuHeight = $bookmarkContextMenu.offsetHeight; 746 | var pageX = rtl ? Math.max(0, e.pageX - bookmarkMenuWidth) : Math.min(e.pageX, body.offsetWidth - bookmarkMenuWidth); 747 | var pageY = e.pageY; 748 | var boundY = window.innerHeight - bookmarkMenuHeight; 749 | if (pageY > boundY) pageY -= bookmarkMenuHeight; 750 | if (pageY < 0) pageY = boundY; 751 | pageY = Math.max(0, pageY); 752 | $bookmarkContextMenu.style.left = pageX + 'px'; 753 | $bookmarkContextMenu.style.top = pageY + 'px'; 754 | $bookmarkContextMenu.style.opacity = 1; 755 | $bookmarkContextMenu.focus(); 756 | } else if (el.tagName == 'SPAN'){ 757 | currentContext = el; 758 | var active = body.querySelector('.active'); 759 | if (active) active.removeClass('active'); 760 | el.addClass('active'); 761 | if (el.parentNode.dataset.parentid == '0'){ 762 | $folderContextMenu.addClass('hide-editables'); 763 | } else { 764 | $folderContextMenu.removeClass('hide-editables'); 765 | } 766 | var folderMenuWidth = $folderContextMenu.offsetWidth; 767 | var folderMenuHeight = $folderContextMenu.offsetHeight; 768 | var pageX = rtl ? Math.max(0, e.pageX - folderMenuWidth) : Math.min(e.pageX, body.offsetWidth - folderMenuWidth); 769 | var pageY = e.pageY; 770 | var boundY = window.innerHeight - folderMenuHeight; 771 | if (pageY > boundY) pageY -= folderMenuHeight; 772 | if (pageY < 0) pageY = boundY; 773 | $folderContextMenu.style.left = pageX + 'px'; 774 | $folderContextMenu.style.top = pageY + 'px'; 775 | $folderContextMenu.style.opacity = 1; 776 | $folderContextMenu.focus(); 777 | } 778 | }); 779 | // on Mac, holding down right-click for a period of time closes the context menu 780 | // Not a complete implementation, but it works :) 781 | if (os == 'mac') body.addEventListener('mouseup', function(e){ 782 | if (e.button == 2 && macCloseContextMenu){ 783 | macCloseContextMenu = false; 784 | clearMenu(); 785 | } 786 | }); 787 | 788 | var bookmarkContextHandler = function(e){ 789 | e.stopPropagation(); 790 | if (!currentContext) return; 791 | var el = e.target; 792 | if (el.tagName != 'COMMAND') return; 793 | var url = currentContext.href; 794 | switch (el.id){ 795 | case 'bookmark-new-tab': 796 | actions.openBookmarkNewTab(url); 797 | break; 798 | case 'bookmark-new-window': 799 | actions.openBookmarkNewWindow(url); 800 | break; 801 | case 'bookmark-new-incognito-window': 802 | actions.openBookmarkNewWindow(url, true); 803 | break; 804 | case 'bookmark-edit': 805 | var li = currentContext.parentNode; 806 | var id = li.id.replace(/(neat\-tree|results)\-item\-/, ''); 807 | actions.editBookmarkFolder(id); 808 | break; 809 | case 'bookmark-delete': 810 | var li = currentContext.parentNode; 811 | var id = li.id.replace(/(neat\-tree|results)\-item\-/, ''); 812 | actions.deleteBookmark(id); 813 | break; 814 | } 815 | clearMenu(); 816 | }; 817 | // On Mac, all three mouse clicks work; on Windows, middle-click doesn't work 818 | $bookmarkContextMenu.addEventListener('mouseup', function(e){ 819 | e.stopPropagation(); 820 | if (e.button == 0 || (os == 'mac' && e.button == 1)) bookmarkContextHandler(e); 821 | }); 822 | $bookmarkContextMenu.addEventListener('contextmenu', bookmarkContextHandler); 823 | $bookmarkContextMenu.addEventListener('click', function(e){ 824 | e.stopPropagation(); 825 | }); 826 | 827 | var folderContextHandler = function(e){ 828 | if (!currentContext) return; 829 | var el = e.target; 830 | if (el.tagName != 'COMMAND') return; 831 | var li = currentContext.parentNode; 832 | var id = li.id.replace('neat-tree-item-', ''); 833 | chrome.bookmarks.getChildren(id, function(children){ 834 | var urls = Array.map(function(c){ 835 | return c.url; 836 | }, children).clean(); 837 | var urlsLen = urls.length; 838 | var noURLS = !urlsLen; 839 | switch (el.id){ 840 | case 'folder-window': 841 | if (noURLS) return; 842 | actions.openBookmarks(urls); 843 | break; 844 | case 'folder-new-window': 845 | if (noURLS) return; 846 | actions.openBookmarksNewWindow(urls); 847 | break; 848 | case 'folder-new-incognito-window': 849 | if (noURLS) return; 850 | actions.openBookmarksNewWindow(urls, true); 851 | break; 852 | case 'folder-edit': 853 | actions.editBookmarkFolder(id); 854 | break; 855 | case 'folder-delete': 856 | actions.deleteBookmarks(id, urlsLen, children.length-urlsLen); 857 | break; 858 | } 859 | }); 860 | clearMenu(); 861 | }; 862 | $folderContextMenu.addEventListener('mouseup', function(e){ 863 | e.stopPropagation(); 864 | if (e.button == 0 || (os == 'mac' && e.button == 1)) folderContextHandler(e); 865 | }); 866 | $folderContextMenu.addEventListener('contextmenu', folderContextHandler); 867 | $folderContextMenu.addEventListener('click', function(e){ 868 | e.stopPropagation(); 869 | }); 870 | 871 | // Keyboard navigation 872 | var keyBuffer = '', keyBufferTimer; 873 | var treeKeyDown = function(e){ 874 | var item = document.activeElement; 875 | if (!/^(a|span)$/i.test(item.tagName)) item = $tree.querySelector('.focus') || $tree.querySelector('li:first-child>span'); 876 | var li = item.parentNode; 877 | var keyCode = e.keyCode; 878 | var metaKey = e.metaKey; 879 | if (keyCode == 40 && metaKey) keyCode = 35; // cmd + down (Mac) 880 | if (keyCode == 38 && metaKey) keyCode = 36; // cmd + up (Mac) 881 | switch (keyCode){ 882 | case 40: // down 883 | e.preventDefault(); 884 | var liChild = li.querySelector('ul>li:first-child'); 885 | if (li.hasClass('open') && liChild){ 886 | liChild.querySelector('a, span').focus(); 887 | } else { 888 | var nextLi = li.nextElementSibling; 889 | if (nextLi){ 890 | nextLi.querySelector('a, span').focus(); 891 | } else { 892 | var nextLi; 893 | do { 894 | li = li.parentNode.parentNode; 895 | if (li) nextLi = li.nextElementSibling; 896 | if (nextLi) nextLi.querySelector('a, span').focus(); 897 | } while (li && !nextLi); 898 | } 899 | } 900 | break; 901 | case 38: // up 902 | e.preventDefault(); 903 | var prevLi = li.previousElementSibling; 904 | if (prevLi){ 905 | while (prevLi.hasClass('open') && prevLi.querySelector('ul>li:last-child')){ 906 | var lis = prevLi.querySelectorAll('ul>li:last-child'); 907 | prevLi = Array.filter(function(li){ 908 | return !!li.parentNode.offsetHeight; 909 | }, lis).getLast(); 910 | }; 911 | prevLi.querySelector('a, span').focus(); 912 | } else { 913 | var parentPrevLi = li.parentNode.parentNode; 914 | if (parentPrevLi && parentPrevLi.tagName == 'LI'){ 915 | parentPrevLi.querySelector('a, span').focus(); 916 | } else { 917 | searchInput.focus(); 918 | } 919 | } 920 | break; 921 | case 39: // right (left for RTL) 922 | e.preventDefault(); 923 | if (li.hasClass('parent') && ((!rtl && !li.hasClass('open')) || (rtl && li.hasClass('open')))){ 924 | var event = document.createEvent('MouseEvents'); 925 | event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 926 | li.firstElementChild.dispatchEvent(event); 927 | } else if (rtl){ 928 | var parentID = li.dataset.parentid; 929 | if (parentID == '0') return; 930 | $('neat-tree-item-' + parentID).querySelector('span').focus(); 931 | } 932 | break; 933 | case 37: // left (right for RTL) 934 | e.preventDefault(); 935 | if (li.hasClass('parent') && ((!rtl && li.hasClass('open')) || (rtl && !li.hasClass('open')))){ 936 | var event = document.createEvent('MouseEvents'); 937 | event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 938 | li.firstElementChild.dispatchEvent(event); 939 | } else if (!rtl){ 940 | var parentID = li.dataset.parentid; 941 | if (parentID == '0') return; 942 | $('neat-tree-item-' + parentID).querySelector('span').focus(); 943 | } 944 | break; 945 | case 32: // space 946 | case 13: // enter 947 | e.preventDefault(); 948 | var event = document.createEvent('MouseEvents'); 949 | event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, e.ctrlKey, false, e.shiftKey, e.metaKey, 0, null); 950 | li.firstElementChild.dispatchEvent(event); 951 | break; 952 | case 35: // end 953 | if (searchMode){ 954 | this.querySelector('li:last-child a').focus(); 955 | } else { 956 | var lis = this.querySelectorAll('ul>li:last-child'); 957 | var li = Array.filter(function(li){ 958 | return !!li.parentNode.offsetHeight; 959 | }, lis).getLast(); 960 | li.querySelector('span, a').focus(); 961 | } 962 | break; 963 | case 36: // home 964 | if (searchMode){ 965 | this.querySelector('ul>li:first-child a').focus(); 966 | } else { 967 | this.querySelector('ul>li:first-child').querySelector('span, a').focus(); 968 | } 969 | break; 970 | case 34: // page down 971 | var self = this; 972 | var getLastItem = function(){ 973 | var bound = self.offsetHeight + self.scrollTop; 974 | var items = self.querySelectorAll('a, span'); 975 | return Array.filter(function(item){ 976 | return !!item.parentElement.offsetHeight && item.offsetTop < bound; 977 | }, items).getLast(); 978 | }; 979 | var item = getLastItem(); 980 | if (item != document.activeElement){ 981 | e.preventDefault(); 982 | item.focus(); 983 | } else { 984 | setTimeout(function(){ 985 | getLastItem().focus(); 986 | }, 0); 987 | } 988 | break; 989 | case 33: // page up 990 | var self = this; 991 | var getFirstItem = function(){ 992 | var bound = self.scrollTop; 993 | var items = self.querySelectorAll('a, span'); 994 | return Array.filter(function(item){ 995 | return !!item.parentElement.offsetHeight && ((item.offsetTop + item.offsetHeight) > bound); 996 | }, items)[0]; 997 | }; 998 | var item = getFirstItem(); 999 | if (item != document.activeElement){ 1000 | e.preventDefault(); 1001 | item.focus(); 1002 | } else { 1003 | setTimeout(function(){ 1004 | getFirstItem().focus(); 1005 | }, 0); 1006 | } 1007 | break; 1008 | case 113: // F2, not for Mac 1009 | if (os == 'mac') break; 1010 | var id = li.id.replace(/(neat\-tree|results)\-item\-/, ''); 1011 | actions.editBookmarkFolder(id); 1012 | break; 1013 | case 46: // delete 1014 | break; // don't run 'default' 1015 | default: 1016 | var key = String.fromCharCode(keyCode).trim(); 1017 | if (!key) return; 1018 | if (key != keyBuffer) keyBuffer += key; 1019 | clearTimeout(keyBufferTimer); 1020 | keyBufferTimer = setTimeout(function(){ keyBuffer = ''; }, 500); 1021 | var lis = this.querySelectorAll('ul>li'); 1022 | var items = []; 1023 | for (var i=0, l=lis.length; i span'); 1063 | var li = item.parentNode; 1064 | switch (e.keyCode){ 1065 | case 8: // backspace 1066 | if (os != 'mac') break; // somehow delete button on mac gives backspace 1067 | case 46: // delete 1068 | e.preventDefault(); 1069 | var id = li.id.replace(/(neat\-tree|results)\-item\-/, ''); 1070 | if (li.hasClass('parent')){ 1071 | chrome.bookmarks.getChildren(id, function(children){ 1072 | var urlsLen = Array.map(function(c){ 1073 | return c.url; 1074 | }, children).clean().length; 1075 | actions.deleteBookmarks(id, urlsLen, children.length-urlsLen); 1076 | }); 1077 | } else { 1078 | actions.deleteBookmark(id); 1079 | } 1080 | break; 1081 | } 1082 | }; 1083 | $tree.addEventListener('keyup', treeKeyUp); 1084 | $results.addEventListener('keyup', treeKeyUp); 1085 | 1086 | var contextKeyDown = function(e){ 1087 | var menu = this; 1088 | var item = document.activeElement; 1089 | var metaKey = e.metaKey; 1090 | switch (e.keyCode){ 1091 | case 40: // down 1092 | e.preventDefault(); 1093 | if (metaKey){ // cmd + down (Mac) 1094 | menu.lastElementChild.focus(); 1095 | } else { 1096 | if (item.tagName == 'COMMAND'){ 1097 | var nextItem = item.nextElementSibling; 1098 | if (nextItem && nextItem.tagName == 'HR') nextItem = nextItem.nextElementSibling; 1099 | if (nextItem){ 1100 | nextItem.focus(); 1101 | } else if (os != 'mac'){ 1102 | menu.firstElementChild.focus(); 1103 | } 1104 | } else { 1105 | item.firstElementChild.focus(); 1106 | } 1107 | } 1108 | break; 1109 | case 38: // up 1110 | e.preventDefault(); 1111 | if (metaKey){ // cmd + up (Mac) 1112 | menu.firstElementChild.focus(); 1113 | } else { 1114 | if (item.tagName == 'COMMAND'){ 1115 | var prevItem = item.previousElementSibling; 1116 | if (prevItem && prevItem.tagName == 'HR') prevItem = prevItem.previousElementSibling; 1117 | if (prevItem){ 1118 | prevItem.focus(); 1119 | } else if (os != 'mac'){ 1120 | menu.lastElementChild.focus(); 1121 | } 1122 | } else { 1123 | item.lastElementChild.focus(); 1124 | } 1125 | } 1126 | break; 1127 | case 32: // space 1128 | if (os != 'mac') break; 1129 | case 13: // enter 1130 | e.preventDefault(); 1131 | var event = document.createEvent('MouseEvents'); 1132 | event.initMouseEvent('mouseup', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 1133 | item.dispatchEvent(event); 1134 | case 27: // esc 1135 | e.preventDefault(); 1136 | var active = body.querySelector('.active'); 1137 | if (active) active.removeClass('active').focus(); 1138 | clearMenu(); 1139 | } 1140 | }; 1141 | $bookmarkContextMenu.addEventListener('keydown', contextKeyDown); 1142 | $folderContextMenu.addEventListener('keydown', contextKeyDown); 1143 | 1144 | var contextMouseMove = function(e){ 1145 | e.target.focus(); 1146 | }; 1147 | $bookmarkContextMenu.addEventListener('mousemove', contextMouseMove); 1148 | $folderContextMenu.addEventListener('mousemove', contextMouseMove); 1149 | 1150 | var contextMouseOut = function(){ 1151 | if (this.style.opacity.toInt()) this.focus(); 1152 | }; 1153 | $bookmarkContextMenu.addEventListener('mouseout', contextMouseOut); 1154 | $folderContextMenu.addEventListener('mouseout', contextMouseOut); 1155 | 1156 | // Drag and drop, baby 1157 | var draggedBookmark = null; 1158 | var draggedOut = false; 1159 | var canDrop = false; 1160 | var zoomLevel = 1; 1161 | var bookmarkClone = $('bookmark-clone'); 1162 | var dropOverlay = $('drop-overlay'); 1163 | $tree.addEventListener('mousedown', function(e){ 1164 | if (e.button != 0) return; 1165 | var el = e.target; 1166 | var elParent = el.parentNode; 1167 | // can move any bookmarks/folders except the default root folders 1168 | if ((el.tagName == 'A' && elParent.hasClass('child')) || (el.tagName == 'SPAN' && elParent.hasClass('parent') && elParent.dataset.parentid != '0')){ 1169 | e.preventDefault(); 1170 | draggedOut = false; 1171 | draggedBookmark = el; 1172 | if (localStorage.zoom) zoomLevel = localStorage.zoom.toInt()/100; 1173 | bookmarkClone.innerHTML = el.innerHTML; 1174 | el.focus(); 1175 | } 1176 | }); 1177 | var scrollTree, scrollTreeInterval = 100, scrollTreeSpot = 10; 1178 | var stopScrollTree = function(){ 1179 | clearInterval(scrollTree); 1180 | scrollTree = null; 1181 | }; 1182 | document.addEventListener('mousemove', function(e){ 1183 | if (e.button != 0) return; 1184 | if (!draggedBookmark) return; 1185 | e.preventDefault(); 1186 | var el = e.target; 1187 | var clientX = e.clientX; 1188 | var clientY = e.clientY; 1189 | if (el == draggedBookmark){ 1190 | bookmarkClone.style.left = '-999px'; 1191 | dropOverlay.style.left = '-999px'; 1192 | canDrop = false; 1193 | return; 1194 | } 1195 | draggedOut = true; 1196 | // if hovering over the dragged element itself or cursor move outside the tree 1197 | var treeTop = $tree.offsetTop, treeBottom = window.innerHeight; 1198 | if (clientX < 0 || clientY < treeTop || clientX > $tree.offsetWidth || clientY > treeBottom){ 1199 | bookmarkClone.style.left = '-999px'; 1200 | dropOverlay.style.left = '-999px'; 1201 | canDrop = false; 1202 | } 1203 | // if hovering over the top or bottom edges of the tree, scroll the tree 1204 | var treeScrollHeight = $tree.scrollHeight, treeOffsetHeight = $tree.offsetHeight; 1205 | if (treeScrollHeight > treeOffsetHeight){ // only scroll when it's scrollable 1206 | var treeScrollTop = $tree.scrollTop; 1207 | if (clientY <= treeTop+scrollTreeSpot){ 1208 | if (treeScrollTop == 0){ 1209 | stopScrollTree(); 1210 | } else if (!scrollTree) scrollTree = setInterval(function(){ 1211 | $tree.scrollByLines(-1); 1212 | dropOverlay.style.left = '-999px'; 1213 | }, scrollTreeInterval); 1214 | } else if (clientY >= treeBottom-scrollTreeSpot){ 1215 | if (treeScrollTop == (treeScrollHeight - treeOffsetHeight)){ 1216 | stopScrollTree(); 1217 | } else if (!scrollTree) scrollTree = setInterval(function(){ 1218 | $tree.scrollByLines(1); 1219 | dropOverlay.style.left = '-999px'; 1220 | }, scrollTreeInterval); 1221 | } else { 1222 | stopScrollTree(); 1223 | } 1224 | } 1225 | // collapse the folder before moving it 1226 | var draggedBookmarkParent = draggedBookmark.parentNode; 1227 | if (draggedBookmark.tagName == 'SPAN' && draggedBookmarkParent.hasClass('open')){ 1228 | draggedBookmarkParent.removeClass('open').setAttribute('aria-expanded', false); 1229 | } 1230 | clientX /= zoomLevel; 1231 | clientY /= zoomLevel; 1232 | if (el.tagName == 'A'){ 1233 | canDrop = true; 1234 | bookmarkClone.style.top = clientY + 'px'; 1235 | bookmarkClone.style.left = (rtl ? (clientX-bookmarkClone.offsetWidth) : clientX) + 'px'; 1236 | var elRect = el.getBoundingClientRect(); 1237 | var top = (clientY >= elRect.top+elRect.height/2) ? elRect.bottom : elRect.top; 1238 | dropOverlay.className = 'bookmark'; 1239 | dropOverlay.style.top = top + 'px'; 1240 | dropOverlay.style.left = rtl ? '0px' : el.style.webkitPaddingStart.toInt() + 16 + 'px'; 1241 | dropOverlay.style.width = (el.getComputedStyle('width').toInt() - 12) + 'px'; 1242 | dropOverlay.style.height = null; 1243 | } else if (el.tagName == 'SPAN'){ 1244 | canDrop = true; 1245 | bookmarkClone.style.top = clientY + 'px'; 1246 | bookmarkClone.style.left = clientX + 'px'; 1247 | var elRect = el.getBoundingClientRect(); 1248 | var top = null; 1249 | var elRectTop = elRect.top, elRectHeight = elRect.height; 1250 | var elParent = el.parentNode; 1251 | if (elParent.dataset.parentid != '0'){ 1252 | if (clientY < elRectTop+elRectHeight*.3){ 1253 | top = elRect.top; 1254 | } else if (clientY > elRectTop+elRectHeight*.7 && !elParent.hasClass('open')){ 1255 | top = elRect.bottom; 1256 | } 1257 | } 1258 | if (top == null){ 1259 | dropOverlay.className = 'folder'; 1260 | dropOverlay.style.top = elRect.top + 'px'; 1261 | dropOverlay.style.left = '0px'; 1262 | dropOverlay.style.width = elRect.width + 'px'; 1263 | dropOverlay.style.height = elRect.height + 'px'; 1264 | } else { 1265 | dropOverlay.className = 'bookmark'; 1266 | dropOverlay.style.top = top + 'px'; 1267 | dropOverlay.style.left = el.style.webkitPaddingStart.toInt() + 16 + 'px'; 1268 | dropOverlay.style.width = (el.getComputedStyle('width').toInt() - 12) + 'px'; 1269 | dropOverlay.style.height = null; 1270 | } 1271 | } 1272 | }); 1273 | var onDrop = function(){ 1274 | draggedBookmark = null; 1275 | bookmarkClone.style.left = '-999px'; 1276 | dropOverlay.style.left = '-999px'; 1277 | canDrop = false; 1278 | }; 1279 | document.addEventListener('mouseup', function(e){ 1280 | if (e.button != 0) return; 1281 | if (!draggedBookmark) return; 1282 | stopScrollTree(); 1283 | if (!canDrop){ 1284 | if (draggedOut) noOpenBookmark = true; 1285 | draggedOut = false; 1286 | onDrop(); 1287 | return; 1288 | }; 1289 | var el = e.target; 1290 | var elParent = el.parentNode; 1291 | var id = elParent.id.replace('neat-tree-item-', ''); 1292 | if (!id){ 1293 | onDrop(); 1294 | return; 1295 | } 1296 | var draggedBookmarkParent = draggedBookmark.parentNode; 1297 | var draggedID = draggedBookmarkParent.id.replace('neat-tree-item-', ''); 1298 | var clientY = e.clientY/zoomLevel; 1299 | if (el.tagName == 'A'){ 1300 | var elRect = el.getBoundingClientRect(); 1301 | var moveBottom = (clientY >= elRect.top+elRect.height/2); 1302 | chrome.bookmarks.get(id, function(node){ 1303 | if (!node || !node.length) return; 1304 | node = node[0]; 1305 | var index = node.index; 1306 | var parentId = node.parentId; 1307 | chrome.bookmarks.move(draggedID, { 1308 | parentId: parentId, 1309 | index: moveBottom ? ++index : index 1310 | }, function(){ 1311 | draggedBookmarkParent.inject(elParent, moveBottom ? 'after' : 'before'); 1312 | draggedBookmark.style.webkitPaddingStart = el.style.webkitPaddingStart; 1313 | draggedBookmark.focus(); 1314 | onDrop(); 1315 | }); 1316 | }); 1317 | } else if (el.tagName == 'SPAN'){ 1318 | var elRect = el.getBoundingClientRect(); 1319 | var move = 0; // 0 = middle, 1 = top, 2 = bottom 1320 | var elRectTop = elRect.top, elRectHeight = elRect.height; 1321 | var elParent = el.parentNode; 1322 | if (elParent.dataset.parentid != '0'){ 1323 | if (clientY < elRectTop+elRectHeight*.3){ 1324 | move = 1; 1325 | } else if (clientY > elRectTop+elRectHeight*.7 && !elParent.hasClass('open')){ 1326 | move = 2; 1327 | } 1328 | } 1329 | if (move > 0){ 1330 | var moveBottom = (move == 2); 1331 | chrome.bookmarks.get(id, function(node){ 1332 | if (!node || !node.length) return; 1333 | node = node[0]; 1334 | var index = node.index; 1335 | var parentId = node.parentId; 1336 | chrome.bookmarks.move(draggedID, { 1337 | parentId: parentId, 1338 | index: moveBottom ? ++index : index 1339 | }, function(){ 1340 | draggedBookmarkParent.inject(elParent, moveBottom ? 'after' : 'before'); 1341 | draggedBookmark.style.webkitPaddingStart = el.style.webkitPaddingStart; 1342 | draggedBookmark.focus(); 1343 | onDrop(); 1344 | }); 1345 | }); 1346 | } else { 1347 | chrome.bookmarks.move(draggedID, { 1348 | parentId: id 1349 | }, function(){ 1350 | var ul = elParent.querySelector('ul'); 1351 | var level = parseInt(elParent.parentNode.dataset.level)+1; 1352 | draggedBookmark.style.webkitPaddingStart = (14*level) + 'px'; 1353 | if (ul){ 1354 | draggedBookmarkParent.inject(ul); 1355 | } else { 1356 | draggedBookmarkParent.destroy(); 1357 | } 1358 | el.focus(); 1359 | onDrop(); 1360 | }); 1361 | } 1362 | } else { 1363 | onDrop(); 1364 | } 1365 | }); 1366 | 1367 | // Resizer 1368 | var $resizer = $('resizer'); 1369 | var resizerDown = false; 1370 | var bodyWidth, screenX; 1371 | $resizer.addEventListener('mousedown', function(e){ 1372 | e.preventDefault(); 1373 | e.stopPropagation(); 1374 | resizerDown = true; 1375 | bodyWidth = body.offsetWidth; 1376 | screenX = e.screenX; 1377 | }); 1378 | document.addEventListener('mousemove', function(e){ 1379 | if (!resizerDown) return; 1380 | e.preventDefault(); 1381 | var changedWidth = rtl ? (e.screenX - screenX) : (screenX - e.screenX); 1382 | var width = bodyWidth + changedWidth; 1383 | width = Math.min(640, Math.max(320, width)); 1384 | body.style.width = width + 'px'; 1385 | localStorage.popupWidth = width; 1386 | clearMenu(); // messes the context menu 1387 | }); 1388 | document.addEventListener('mouseup', function(e){ 1389 | if (!resizerDown) return; 1390 | e.preventDefault(); 1391 | resizerDown = false; 1392 | adaptBookmarkTooltips(); 1393 | }); 1394 | setTimeout(function(){ // delaying execution due to stupid Chrome Linux bug 1395 | window.addEventListener('resize', function(){ // in case there's a resizer *outside* the popup page 1396 | if (resizerDown) return; 1397 | var width = window.innerWidth; 1398 | body.style.width = width + 'px'; 1399 | localStorage.popupWidth = width; 1400 | clearMenu(); 1401 | }); 1402 | }, 1000); 1403 | 1404 | // Closing dialogs on escape 1405 | var closeDialogs = function(){ 1406 | if (body.hasClass('needConfirm')) ConfirmDialog.fn2(); ConfirmDialog.close(); 1407 | if (body.hasClass('needEdit')) EditDialog.close(); 1408 | if (body.hasClass('needAlert')) AlertDialog.close(); 1409 | }; 1410 | document.addEventListener('keydown', function(e){ 1411 | if (e.keyCode == 27 && (body.hasClass('needConfirm') || body.hasClass('needEdit') || body.hasClass('needAlert'))){ // esc 1412 | e.preventDefault(); 1413 | closeDialogs(); 1414 | } else if ((e.metaKey || e.ctrlKey) && e.keyCode == 70){ // cmd/ctrl + f 1415 | searchInput.focus(); 1416 | searchInput.select(); 1417 | } 1418 | }); 1419 | $('cover').addEventListener('click', closeDialogs); 1420 | 1421 | // Make webkit transitions work only after elements are settled down 1422 | setTimeout(function(){ 1423 | body.addClass('transitional'); 1424 | }, 10); 1425 | 1426 | // Zoom 1427 | if (localStorage.zoom){ 1428 | body.dataset.zoom = localStorage.zoom; 1429 | } 1430 | var zoom = function(val){ 1431 | if (draggedBookmark) return; // prevent zooming when drag-n-droppping 1432 | var dataZoom = body.dataset.zoom; 1433 | var currentZoom = dataZoom ? dataZoom.toInt() : 100; 1434 | if (val == 0){ 1435 | delete body.dataset.zoom; 1436 | localStorage.removeItem('zoom'); 1437 | } else { 1438 | var z = (val>0) ? currentZoom+10 : currentZoom-10; 1439 | z = Math.min(150, Math.max(90, z)); 1440 | body.dataset.zoom = z; 1441 | localStorage.zoom = z; 1442 | } 1443 | body.addClass('dummy').removeClass('dummy'); // force redraw 1444 | resetHeight(); 1445 | }; 1446 | document.addEventListener('mousewheel', function(e){ 1447 | if (!e.metaKey && !e.ctrlKey) return; 1448 | e.preventDefault(); 1449 | zoom(e.wheelDelta); 1450 | }); 1451 | document.addEventListener('keydown', function(e){ 1452 | if (!e.metaKey && !e.ctrlKey) return; 1453 | switch (e.keyCode){ 1454 | case 187: // + (plus) 1455 | e.preventDefault(); 1456 | zoom(1); 1457 | break; 1458 | case 189: // - (minus) 1459 | e.preventDefault(); 1460 | zoom(-1); 1461 | break; 1462 | case 48: // 0 (zero) 1463 | e.preventDefault(); 1464 | zoom(0); 1465 | break; 1466 | } 1467 | }); 1468 | 1469 | // Fix stupid Chrome build 536 bug 1470 | if (version.build >= 536) body.addClass('chrome-536'); 1471 | 1472 | // Fix stupid wrong offset of the page, on Chrome Mac 1473 | setTimeout(function(){ 1474 | var top = body.scrollTop; 1475 | if (top != 0) body.scrollTop = 0; 1476 | }, 1500); 1477 | 1478 | if (localStorage.userstyle){ 1479 | var style = document.createElement('style'); 1480 | style.textContent = localStorage.userstyle; 1481 | style.inject(document.body); 1482 | } 1483 | })(window); -------------------------------------------------------------------------------- /neat.xar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cheeaun/neat-bookmarks/56bf0be3424c725e5e6fd65745a186d80638cfd4/neat.xar -------------------------------------------------------------------------------- /neatools.js: -------------------------------------------------------------------------------- 1 | /* 2 | Neatools: a nano JavaScript framework made just for Neat Bookmarks and nothing else. 3 | Heavily inspired by MooTools (http://mootools.net/). 4 | Works for Chrome 8 and above. 5 | */ 6 | 7 | var $ = function(id){ 8 | return document.getElementById(id); 9 | }; 10 | 11 | function $extend(original, extended){ 12 | for (var key in (extended || {})) original[key] = extended[key]; 13 | return original; 14 | }; 15 | 16 | function $each(obj, fn, bind){ 17 | for (var key in obj){ 18 | if (obj.hasOwnProperty(key)) fn.call(bind, obj[key], key, obj); 19 | } 20 | } 21 | 22 | var $slice = Array.prototype.slice; 23 | 24 | $extend(String.prototype, { 25 | widont: function(){ 26 | return this.replace(/\s([^\s]+)$/i, ' $1'); 27 | }, 28 | toInt: function(base){ 29 | return parseInt(this, base || 10); 30 | }, 31 | hyphenate: function(){ 32 | return this.replace(/[A-Z]/g, function(match){ 33 | return ('-' + match.charAt(0).toLowerCase()); 34 | }); 35 | }, 36 | htmlspecialchars: function(){ 37 | return this.replace(/>/g, '>').replace(/