├── .gitignore ├── README.md ├── images └── icon.png ├── jsconfig.json ├── promos ├── screenshots │ ├── main.png │ ├── organize.png │ └── sync.png └── tiles │ ├── large-tile.png │ ├── promo-440.svg │ ├── promo-920.svg │ └── small-tile.png ├── src ├── _locales │ ├── de │ │ └── messages.json │ ├── en │ │ └── messages.json │ └── pl │ │ └── messages.json ├── analytics.js ├── background.js ├── constants.js ├── contentscript.js ├── css │ ├── material-icons.css │ ├── materialize.min.css │ ├── options.css │ ├── popup.css │ └── translators.css ├── fonts │ ├── Material-Icons.woff2 │ └── roboto │ │ ├── Roboto-Bold.eot │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.eot │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.eot │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.eot │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.eot │ │ ├── Roboto-Thin.ttf │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 ├── img │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-19.png │ ├── icon-38.png │ ├── icon.svg │ └── icons │ │ ├── ic_folder_1x.png │ │ ├── ic_folder_2x.png │ │ ├── ic_help_1x.png │ │ ├── ic_help_2x.png │ │ ├── ic_navigate_before_1x.png │ │ └── ic_navigate_before_2x.png ├── jquery-ui │ ├── AUTHORS.txt │ ├── LICENSE.txt │ ├── external │ │ └── jquery │ │ │ └── jquery.js │ ├── images │ │ ├── ui-icons_444444_256x240.png │ │ ├── ui-icons_555555_256x240.png │ │ ├── ui-icons_777620_256x240.png │ │ ├── ui-icons_777777_256x240.png │ │ ├── ui-icons_cc0000_256x240.png │ │ └── ui-icons_ffffff_256x240.png │ ├── index.html │ ├── jquery-ui.css │ ├── jquery-ui.js │ ├── jquery-ui.min.css │ ├── jquery-ui.min.js │ ├── jquery-ui.structure.css │ ├── jquery-ui.structure.min.css │ ├── jquery-ui.theme.css │ ├── jquery-ui.theme.min.css │ └── package.json ├── js │ ├── analytics.js │ ├── i18n.js │ ├── materialize.min.js │ └── translators.js ├── manifest.json ├── options.html ├── options.js ├── permissions.html ├── permissions.js ├── popup.html ├── popup.js ├── storage.js └── translators.html └── tests └── storage.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | node_modules 4 | tests/localStorage 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | # Permanent Clipboard 4 | 5 | Permanent Clipboard is Google Chrome™ browser extension that improves the clipboard by allowing users to store multiple entries just a click away. 6 | 7 | Do you want quick access your response templates? Or maybe you often fill forms that aren't standard and the browser doesn't support it? Then Permanent Clipboard is the extension for you. 8 | 9 | ### Main features 10 | 11 | ##### Directories 12 | 13 | For convenience, entries can be categorized in directories for logical structure, so you won't mix business with pleasure. 14 | Directories can also be nested so the structure you create can reflect any complicated work flow you face each day. 15 | 16 | ##### Cross computers synchronization 17 | 18 | Permanent Clipboard can synchronize between your Google Chrome™ instances, as long as you are logged in into your Google Account. 19 | But this feature is not obligatory, and you can easy opt out from it if you store confidential information in your clipboard. 20 | 21 | ##### Backups 22 | 23 | When you are not using synchronized storage it is important not to lose your work, this is why Permanent Clipboard lets you create a backup of all your entries and restore then at any point, so you are safe from any data loss. 24 | 25 | ### Help 26 | 27 | Permanent Clipboard is free and open source software and I would like to keep it that way. So if you enjoy the 28 | extension I would appreciate if you help me reach wider audience by rating the extension on [Chrome Web Store](https://chrome.google.com/webstore/detail/permanent-clipboard/hilkjcfodmbdgpadbpehimibheopoccb) or telling your friends about it. 29 | 30 | You can also support the growth of Permanent Clipboard by donating via PayPal. Donations allows me to spend more time developing the extension, fixing bugs, adding features and improving the extension overall. 31 | 32 | [![Donate](https://www.paypalobjects.com/en_US/GB/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=X4LEC9EWL4V24) 33 | -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/images/icon.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonJS", 4 | "target": "es2019" 5 | }, 6 | "typeAcquisition": {"include": ["chrome"]}, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /promos/screenshots/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/promos/screenshots/main.png -------------------------------------------------------------------------------- /promos/screenshots/organize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/promos/screenshots/organize.png -------------------------------------------------------------------------------- /promos/screenshots/sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/promos/screenshots/sync.png -------------------------------------------------------------------------------- /promos/tiles/large-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/promos/tiles/large-tile.png -------------------------------------------------------------------------------- /promos/tiles/promo-440.svg: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 23 | 25 | image/svg+xml 26 | 28 | 29 | 30 | 31 | 32 | 34 | 37 | 41 | 45 | 46 | 50 | 55 | 61 | 66 | 71 | 77 | 78 | 82 | 87 | 93 | 98 | 103 | 109 | 110 | 121 | 127 | 131 | 136 | 144 | 149 | 150 | 151 | 171 | 181 | 188 | 192 | 194 | 204 | 216 | 223 | 224 | 225 |   PermanentClipboard 252 | 260 | 261 | -------------------------------------------------------------------------------- /promos/tiles/promo-920.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 24 | image/svg+xml 25 | 27 | 28 | 29 | 30 | 31 | 33 | 37 | 42 | 48 | 53 | 58 | 64 | 65 | 69 | 74 | 80 | 85 | 90 | 96 | 97 | 103 | 107 | 112 | 122 | 127 | 128 | 129 | 149 | 153 | 155 | 165 | 177 | 184 | 185 | 186 |   PermanentClipboard 215 | 223 | 224 | -------------------------------------------------------------------------------- /promos/tiles/small-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/promos/tiles/small-tile.png -------------------------------------------------------------------------------- /src/_locales/de/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "optionsSave" : { 3 | "message" : "Speichern" 4 | }, 5 | "optionSwapText" : { 6 | "message" : "Plätze wechseln" 7 | }, 8 | "optionsSavedToastText" : { 9 | "message" : "Einstellungen wurden gespeichert" 10 | }, 11 | "insertFromExtension" : { 12 | "message" : "Aus Permanent Clipboard einfügen" 13 | }, 14 | "optionsStorageSizeHelp" : { 15 | "message" : "Speicherplatz synchronisierter Permanent Clipboard ist von Google begrenzt und kann nicht vergrößert werden. Wenn der Speicherplatz voll wird, empfiehlt man, synchronisierte Permanent Clipboard zu nutzen. Denk jedoch daran, den Inhalt zu übertragen." 16 | }, 17 | "optionsText" : { 18 | "message" : "Einstellungen" 19 | }, 20 | "showAddFormText" : { 21 | "message" : "Neuen Eintrag anlegen" 22 | }, 23 | "addBtnText" : { 24 | "message" : "Hinzufügen" 25 | }, 26 | "popupHintText_2" : { 27 | "message" : "Gefällt dir Permanent Clipboard? Bewerte sie!<\/a>" 28 | }, 29 | "extensionDescription" : { 30 | "message" : "Es lässt die Elemente in der Zwischenablage aufbewahren und macht sie zugänglich." 31 | }, 32 | "popupBack" : { 33 | "message" : "Zurück" 34 | }, 35 | "optionsSwapStoragesHelp" : { 36 | "message" : "Speicherplatz synchronisierter Zwischenablage ist von Google begrenzt und kann nicht vergrößert werden. Wenn der Speicherplatz voll wird, empfiehlt man, synchronisierte Zwischenablage zu nutzen. Denk jedoch daran, den Inhalt zu übertragen." 37 | }, 38 | "optionStorageCardTitle" : { 39 | "message" : "Speicher" 40 | }, 41 | "commonCancel" : { 42 | "message" : "Abbrechen" 43 | }, 44 | "localStorageUsed" : { 45 | "message" : "Lokaler Speicher wird genutzt" 46 | }, 47 | "popupNewElement" : { 48 | "message" : "Aus Systemzwischenablage einfügen" 49 | }, 50 | "deleteEntryIconTitle" : { 51 | "message" : "Löschen" 52 | }, 53 | "storageSwappingFailedMessage" : { 54 | "message" : "Der Inhalt wurde nicht geändert: " 55 | }, 56 | "donateWithPaypal" : { 57 | "message" : "Via PayPal dotieren" 58 | }, 59 | "addToExtensionDB" : { 60 | "message" : "In die Permanent Clipboard einfügen" 61 | }, 62 | "optionsSuccess" : { 63 | "message" : "Geändert" 64 | }, 65 | "popupHintText_1" : { 66 | "message" : "Klicke auf den Link in Optionen um Permanent Clipboard zu dotieren" 67 | }, 68 | "optionStorageUsage" : { 69 | "message" : "Synchronisierter Speicherplatzverbrauch " 70 | }, 71 | "editEntryIconTitle" : { 72 | "message" : "Bearbeiten" 73 | }, 74 | "optionSwapStorageText" : { 75 | "message" : "Inhalt übertragen" 76 | }, 77 | "optionLocalText" : { 78 | "message" : "Lokal" 79 | }, 80 | "optionSyncTip" : { 81 | "message" : "Lokalspeicher ist nur auf diesem Rechner sichtbar. Synchronisierter Speicher ist im Google Chrome Browser sichtbar, wenn man angemeldet ist (es kann langsamer als Lokalspeicher funktionieren)" 82 | }, 83 | "descriptionPlaceholder" : { 84 | "message" : "Beschreibung" 85 | }, 86 | "popupHintNoElements" : { 87 | "message" : "Keine Einträge" 88 | }, 89 | "translatorsTitle" : { 90 | "message" : "Übersetzung" 91 | }, 92 | "extensionName" : { 93 | "message" : "Permanent Clipboard" 94 | }, 95 | "newDirectoryName" : { 96 | "message" : "Neuer Katalog" 97 | }, 98 | "contentPlaceholder" : { 99 | "message" : "Inhalt" 100 | }, 101 | "optionSyncText" : { 102 | "message" : "Synchronisiert" 103 | }, 104 | "optionStorageTypeText" : { 105 | "message" : "Speicherart" 106 | }, 107 | "popupHintTitle" : { 108 | "message" : "Weißt du, dass…?" 109 | }, 110 | "popupHint" : { 111 | "message" : "Klicke auf den Eintrag, um ihn in synchronisierte Zwischenablage zu kopieren" 112 | }, 113 | "popupHintsCount" : { 114 | "message" : "2" 115 | }, 116 | "errorFailedToSaveEntry" : { 117 | "message" : "Der Eintrag wurde nicht angelegt:" 118 | }, 119 | "syncedStorageUsed" : { 120 | "message" : "Synchronisierter Speicher wird genutzt" 121 | } 122 | } -------------------------------------------------------------------------------- /src/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "popup_unsavedChanges" : { 3 | "message" : "Unsaved changes" 4 | }, 5 | "optionsBackupInvalidFile" : { 6 | "message" : "Invalid backup file" 7 | }, 8 | "optionBackupTitle" : { 9 | "message" : "Backup" 10 | }, 11 | "popup_copiedToClipboard" : { 12 | "message" : "Copied to system clipboard" 13 | }, 14 | "donateWithPaypal" : { 15 | "message" : "Donate with PayPal" 16 | }, 17 | "optionsSwapStoragesHelp" : { 18 | "message" : "Swapping storages will replace the content of synchronized storage with the content of local storage and the other way around. This operation will fail if not enough space is available in synchronized storage." 19 | }, 20 | "optionsSavedToastText" : { 21 | "message" : "Options saved" 22 | }, 23 | "optionsStorageSizeHelp" : { 24 | "message" : "Currently synchronized storage size is limited by Google and cannot be increased. If you fill your space you should consider switching to local storage, which is unlimited. Don't forget to swap your storages." 25 | }, 26 | "optionsSave" : { 27 | "message" : "Save" 28 | }, 29 | "popupHintTitle" : { 30 | "message" : "Did you know?" 31 | }, 32 | "optionStorageUsage" : { 33 | "message" : "Synchronized storage usage " 34 | }, 35 | "optionSyncText" : { 36 | "message" : "Synchornized" 37 | }, 38 | "editEntryIconTitle" : { 39 | "message" : "Edit", 40 | "description" : "Hover text on edit icon" 41 | }, 42 | "extensionName" : { 43 | "message" : "Permanent clipboard", 44 | "description" : "Extension name." 45 | }, 46 | "localStorageUsed" : { 47 | "message" : "Using local storage" 48 | }, 49 | "optionBackupNewerFile" : { 50 | "message" : "Backup created with newer version of software. Please update your software." 51 | }, 52 | "optionsBackupRestoreFailed" : { 53 | "message" : "Backup restore failed" 54 | }, 55 | "deleteEntryIconTitle" : { 56 | "message" : "Delete" 57 | }, 58 | "storageSwappingFailedMessage" : { 59 | "message" : "Swapping storage failed, aborting: " 60 | }, 61 | "noMoreSpace" : { 62 | "message" : "No more space left" 63 | }, 64 | "optionBackupCreateButton" : { 65 | "message" : "Create" 66 | }, 67 | "optionBackupTip" : { 68 | "message" : "The backup will only be made from, and be restored to local storage. Sychronized storage is automatically backed up by Google when you sign in to your Google Account in Chrome." 69 | }, 70 | "optionsText" : { 71 | "message" : "Settings", 72 | "description" : "Text displayed on top of options page" 73 | }, 74 | "optionSwapStorageText" : { 75 | "message" : "Swap storages contents", 76 | "description" : "" 77 | }, 78 | "popupHint" : { 79 | "message" : "Click on the element to store it in system clipboard", 80 | "description" : "Hint text showed in popup" 81 | }, 82 | "optionsBackupRestored" : { 83 | "message" : "Backup restored" 84 | }, 85 | "optionStorageTypeText" : { 86 | "message" : "Storage type", 87 | "description" : "Field description before combo on options screen" 88 | }, 89 | "optionStorageCardTitle" : { 90 | "message" : "Storage" 91 | }, 92 | "translatorsTitle" : { 93 | "message" : "Translation" 94 | }, 95 | "optionBackupRestoreButton" : { 96 | "message" : "Read" 97 | }, 98 | "optionSwapText" : { 99 | "message" : "Swap" 100 | }, 101 | "addToExtensionDB" : { 102 | "message" : "Copy", 103 | "description" : "Context menu text on selected text." 104 | }, 105 | "popupBack" : { 106 | "message" : "Back" 107 | }, 108 | "insertFromExtension" : { 109 | "message" : "Paste", 110 | "description" : "Context menu text on editable elements." 111 | }, 112 | "optionsBackupCorrupted" : { 113 | "message" : "Backup file corrupted, can't restore" 114 | }, 115 | "popupHintNoElements" : { 116 | "message" : "No entries yet", 117 | "description" : "Hint visible when no elements are available" 118 | }, 119 | "dropOverlayPromptText" : { 120 | "message" : "Drop backup file to restore" 121 | }, 122 | "showAddFormText" : { 123 | "message" : "Add new entry", 124 | "description" : "Link text for new entry div trigger" 125 | }, 126 | "unknownError" : { 127 | "message" : "Unknown error" 128 | }, 129 | "contentPlaceholder" : { 130 | "message" : "Content", 131 | "description" : "Placeholder hint for content input box" 132 | }, 133 | "errorFailedToSaveEntry" : { 134 | "message" : "Failed to save selection: " 135 | }, 136 | "errorFailedToCreateDirectory": { 137 | "message" : "Failed to create directory: " 138 | }, 139 | "addBtnText" : { 140 | "message" : "Add", 141 | "description" : "Text on add button in popup" 142 | }, 143 | "extensionDescription" : { 144 | "message" : "Allows you to store and access multiple elements in clipboard", 145 | "description" : "Extension description." 146 | }, 147 | "manageText" : { 148 | "message" : "Manage" 149 | }, 150 | "commonCancel" : { 151 | "message" : "Cancel" 152 | }, 153 | "popupHintText_1" : { 154 | "message" : "You can support Permanent Clipboard with donation using link in options screen." 155 | }, 156 | "popupHintsCount" : { 157 | "message" : "2" 158 | }, 159 | "descriptionPlaceholder" : { 160 | "message" : "Description", 161 | "description" : "Placeholder on input field in popup" 162 | }, 163 | "popupHintText_2" : { 164 | "message" : "Enjoying PermanentClipboard? Rate it!<\/a>" 165 | }, 166 | "optionSyncTip" : { 167 | "message" : "Local storage is kept only on this chrome instance.\nSynchronized storage is shared across all your chrome instances (it might working a bit slower then local storage)." 168 | }, 169 | "popupNewElement" : { 170 | "message" : "Add from system clipboard", 171 | "description" : "New element title in popup" 172 | }, 173 | "syncedStorageUsed" : { 174 | "message" : "Using synchronized storage", 175 | "description" : "" 176 | }, 177 | "newDirectoryName" : { 178 | "message" : "New directory" 179 | }, 180 | "optionsSuccess" : { 181 | "message" : "Success" 182 | }, 183 | "optionLocalText" : { 184 | "message" : "Local" 185 | }, 186 | "popup_ButtonDiscard" : { 187 | "message" : "Discard" 188 | }, 189 | "menuRunningOutOfSpace" : { 190 | "message" : "Running out of space? Click here!" 191 | }, 192 | "popup_missingPermissionsWarning": { 193 | "message" : "Some permissions are missing. Click to fix" 194 | }, 195 | "permissions_clipboardRead": { 196 | "message" : "Reading clipboard" 197 | }, 198 | "permissions_clipboardRead_rationale": { 199 | "message": "Required to read data from the system clipboard to simplify the process of adding new entries." 200 | }, 201 | "permissions_clipboardWrite": { 202 | "message": "Writing to clipboard" 203 | }, 204 | "permissions_clipboardWrite_rationale": { 205 | "message": "Required to put a selected snippet into the system clipboard for easier access to your data." 206 | }, 207 | "permissions_grantPermission": { 208 | "message": "Grant" 209 | }, 210 | "permissions_title": { 211 | "message": "Permanent Clipboard needs the following permissions to function properly." 212 | }, 213 | "permissions_thankYou": { 214 | "message": "All permissions granted. Thank you!" 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/_locales/pl/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "popup_unsavedChanges" : { 3 | "message" : "Niezapisane zmiany" 4 | }, 5 | "optionsBackupInvalidFile" : { 6 | "message" : "Niepoprawny plik kopii zapasowej" 7 | }, 8 | "optionBackupTitle" : { 9 | "message" : "Kopia zapasowa" 10 | }, 11 | "popup_copiedToClipboard" : { 12 | "message" : "Skopiowano do schowka" 13 | }, 14 | "donateWithPaypal" : { 15 | "message" : "Dotuj przez PayPal" 16 | }, 17 | "optionsSwapStoragesHelp" : { 18 | "message" : "Zamiana miejscami sprawia, że zawartość synchronizowanego schowka, znajdzie się na miejscu schowka lokalnego, i odwrotnie.\nZamiana nie powiedzie się jeśli nie ma wystarczająco dużo miejsca w schowku synchronizowanym." 19 | }, 20 | "optionsSavedToastText" : { 21 | "message" : "Zapisano ustawienia" 22 | }, 23 | "optionsStorageSizeHelp" : { 24 | "message" : "Pojemność schowka synchronizowanego jest ograniczona przez Google i nie można jej zwiększyć. Jeśli zapełnisz tą przestrzeń, rozważ użycie schowka synchronizowanego. Tylko pamiętaj, żeby przenieść zawartość." 25 | }, 26 | "optionsSave" : { 27 | "message" : "Zapisz" 28 | }, 29 | "popupHintTitle" : { 30 | "message" : "Czy wiesz, \u0010\u0010\u0010że?" 31 | }, 32 | "optionStorageUsage" : { 33 | "message" : "Zużycie pamięci synchronizowanej " 34 | }, 35 | "optionSyncText" : { 36 | "message" : "Synchronizowana" 37 | }, 38 | "editEntryIconTitle" : { 39 | "message" : "Edytuj" 40 | }, 41 | "extensionName" : { 42 | "message" : "Stały schowek" 43 | }, 44 | "localStorageUsed" : { 45 | "message" : "Używasz pamięci lokalnej" 46 | }, 47 | "optionBackupNewerFile" : { 48 | "message" : "Kopia utworzona nowszą wersją schowka. Zaktualizuj swoje oprogramowanie." 49 | }, 50 | "optionsBackupRestoreFailed" : { 51 | "message" : "Nie udało się odtworzyć kopii zapasowej" 52 | }, 53 | "deleteEntryIconTitle" : { 54 | "message" : "Usuń" 55 | }, 56 | "storageSwappingFailedMessage" : { 57 | "message" : "Nie udało się podmienić zawartości: " 58 | }, 59 | "noMoreSpace" : { 60 | "message" : "brak miejsca" 61 | }, 62 | "optionBackupCreateButton" : { 63 | "message" : "Utwórz" 64 | }, 65 | "optionBackupTip" : { 66 | "message" : "Kopia zapasowa wykonuje, i odtwarza, tylko zawartość schowka lokalnego. Schowek synchronizowany jest automatycznie kopiowany przez Google po zalogowaniu się na koncie Google w przeglądarce Chrome." 67 | }, 68 | "optionsText" : { 69 | "message" : "Ustawienia" 70 | }, 71 | "optionSwapStorageText" : { 72 | "message" : "Przenieś zawartość" 73 | }, 74 | "popupHint" : { 75 | "message" : "Kliknij we wpis żeby zapisać go do schowka systemowego" 76 | }, 77 | "optionsBackupRestored" : { 78 | "message" : "Odtworzono" 79 | }, 80 | "optionStorageTypeText" : { 81 | "message" : "Typ pamięci" 82 | }, 83 | "optionStorageCardTitle" : { 84 | "message" : "Pamięć" 85 | }, 86 | "translatorsTitle" : { 87 | "message" : "Tłumaczenie" 88 | }, 89 | "optionBackupRestoreButton" : { 90 | "message" : "Wczytaj" 91 | }, 92 | "optionSwapText" : { 93 | "message" : "Zamień miejscami" 94 | }, 95 | "addToExtensionDB" : { 96 | "message" : "Kopiuj" 97 | }, 98 | "popupBack" : { 99 | "message" : "Wstecz" 100 | }, 101 | "insertFromExtension" : { 102 | "message" : "Wklej" 103 | }, 104 | "optionsBackupCorrupted" : { 105 | "message" : "Plik z kopią uszkodzony. Odzyskiwanie wstrzymane" 106 | }, 107 | "popupHintNoElements" : { 108 | "message" : "Brak wpisów" 109 | }, 110 | "dropOverlayPromptText" : { 111 | "message" : "Upuść plik kopii zapasowej żeby odtworzyć zawartość" 112 | }, 113 | "showAddFormText" : { 114 | "message" : "Dodaj nowy wpis" 115 | }, 116 | "unknownError" : { 117 | "message" : "Nieznany błąd" 118 | }, 119 | "contentPlaceholder" : { 120 | "message" : "Zawartość" 121 | }, 122 | "addBtnText" : { 123 | "message" : "Dodaj" 124 | }, 125 | "errorFailedToSaveEntry" : { 126 | "message" : "Nie udało się dodać wpisu: " 127 | }, 128 | "errorFailedToCreateDirectory": { 129 | "message" : "Nie udało się utworzyć katalogu: " 130 | }, 131 | "extensionDescription" : { 132 | "message" : "Pozwala na zachownie i dostęp do wielu elementów w schowku" 133 | }, 134 | "manageText" : { 135 | "message" : "" 136 | }, 137 | "commonCancel" : { 138 | "message" : "Anuluj" 139 | }, 140 | "popupHintText_1" : { 141 | "message" : "Możesz wesprzeć Stały schowek dotacją, klikając link w opcjach." 142 | }, 143 | "descriptionPlaceholder" : { 144 | "message" : "Opis" 145 | }, 146 | "popupHintsCount" : { 147 | "message" : "2" 148 | }, 149 | "popupHintText_2" : { 150 | "message" : "Podoba Ci się Stały schowek? Wystaw ocenę!<\/a>" 151 | }, 152 | "optionSyncTip" : { 153 | "message" : "Pamięć lokalna jest widoczna tylko na tym komputerze.\nPamięć synchronizowana jest widoczna na wszystkich przeglądarkach Google Chrome, na których jesteś zalgowany (może działać wolniej niż pamięć lokalna)." 154 | }, 155 | "popupNewElement" : { 156 | "message" : "Dodaj ze schowka systemowego" 157 | }, 158 | "newDirectoryName" : { 159 | "message" : "Nowy katalog" 160 | }, 161 | "syncedStorageUsed" : { 162 | "message" : "Używasz pamięci synchronizowanej" 163 | }, 164 | "optionsSuccess" : { 165 | "message" : "Zamieniono" 166 | }, 167 | "optionLocalText" : { 168 | "message" : "Lokalna" 169 | }, 170 | "popup_ButtonDiscard" : { 171 | "message" : "Odrzuć" 172 | }, 173 | "menuRunningOutOfSpace" : { 174 | "message" : "Kończy Ci się miejsce? Kliknij tutaj!" 175 | } 176 | } -------------------------------------------------------------------------------- /src/analytics.js: -------------------------------------------------------------------------------- 1 | function Analytics() {} 2 | 3 | Analytics.prototype = { 4 | userCode: function() { return 'UA-64085295-1'; }, 5 | initialize: function() { 6 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 7 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 8 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 9 | })(window,document,'script','https://ssl.google-analytics.com/analytics.js','ga'); 10 | 11 | ga('create', this.userCode(), 'auto'); 12 | ga('set', 'checkProtocolTask', null); 13 | }, 14 | trackEvent: function(category, action, label, value) { 15 | ga('send', 'event', category, action, label, value); 16 | } 17 | } 18 | 19 | var analytics = new Analytics(); 20 | analytics.initialize(); 21 | -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | var storage = new Storage(); 2 | 3 | let storagePercentageThreshold = 70; 4 | 5 | function IndexPath(string) { 6 | var separated = string.split('_'); 7 | this._elements = []; 8 | for (var e in separated) { 9 | this._elements.push(parseInt(separated[e])); 10 | } 11 | } 12 | 13 | IndexPath.prototype = { 14 | constructor: IndexPath, 15 | length: function() { return this._elements.length; }, 16 | get: function(part) { return this._elements[part]; }, 17 | getLast: function() { return this._elements[this.length()-1]; } 18 | } 19 | 20 | function traverseWithIndexPath(indexPath, data) { 21 | var e = data; 22 | for (var i = 0; i < indexPath.length()-1; ++i) 23 | e = e[indexPath.get(i)].e; 24 | return e[indexPath.getLast()].value; 25 | } 26 | 27 | function onMenuClicked(info, tab) { 28 | if (info.menuItemId == "selmenu") { 29 | analytics.trackEvent('Menu', 'Selection added'); 30 | chrome.tabs.sendMessage(tab.id, {event: ACTION__ADD_SELECTION}); 31 | } else if (info.menuItemId == "runningOutOfSpace") { 32 | chrome.tabs.create({ url: CONTACT_PAGE_URL }); 33 | } else { 34 | storage.getData('clipboard').then((data) => { 35 | var indexPath = new IndexPath(info.menuItemId); 36 | var val = traverseWithIndexPath(indexPath, data.clipboard); 37 | 38 | analytics.trackEvent('Menu', 'Inserting text'); 39 | chrome.tabs.sendMessage(tab.id, {event:ACTION__INSERT_TEXT, value: val}); 40 | }, (error) => console.error(error)); 41 | } 42 | } 43 | 44 | function buildMenuLevel(menu, parentId) { 45 | var cnt = 0; 46 | for (var e in menu) { 47 | var elem = menu[e]; 48 | if (!elem) 49 | continue; 50 | if (elem.e != null) { 51 | var newId = parentId + cnt + '_'; 52 | chrome.contextMenus.create({"title": elem.desc, "parentId": parentId, "contexts": ["editable"], "id": newId}); 53 | buildMenuLevel(elem.e, newId); 54 | } else { 55 | var newId = parentId + cnt; 56 | chrome.contextMenus.create({"title": elem.desc, "parentId": parentId, "contexts": ["editable"], "id": newId}); 57 | } 58 | cnt++; 59 | } 60 | } 61 | 62 | function rebuildMenus() { 63 | chrome.contextMenus.removeAll(function() { 64 | storage.getData({'clipboard':[]}).then(items => { 65 | if (items.clipboard.length == 0) return; 66 | var title = chrome.i18n.getMessage("insertFromExtension"); 67 | chrome.contextMenus.create({"title":title, "contexts":["editable"], "id": ""}); 68 | buildMenuLevel(items.clipboard, ""); 69 | }, error => { 70 | console.error("Failed to get data for menu filling: " + error.message); 71 | }); 72 | 73 | var title = chrome.i18n.getMessage("addToExtensionDB"); 74 | chrome.contextMenus.create({"title": title, "contexts":["selection"], "id": "selmenu"}); 75 | 76 | storage.getStorageUsagePercentage().then((usage) => { 77 | if (usage > storagePercentageThreshold) { 78 | chrome.contextMenus.create({ 79 | "id": "sep", 80 | "type": "separator", 81 | "parentId": "" 82 | }); 83 | chrome.contextMenus.create({ 84 | "title": chrome.i18n.getMessage("menuRunningOutOfSpace"), 85 | "contexts": ["selection", "editable"], 86 | "id": "runningOutOfSpace", 87 | "parentId": "" 88 | }); 89 | } 90 | }); 91 | }); 92 | } 93 | 94 | chrome.runtime.onMessage.addListener( 95 | function(message, sender, sendResponse) { 96 | if (message.event == "rebuildMenus") { 97 | rebuildMenus(); 98 | sendResponse({}); 99 | return; 100 | } else if (message.event == 'saveRecentItem') { 101 | storage.setData({'recent': message.value}).then(() => { 102 | sendResponse({}); 103 | }, (error) => sendResponse({'error': error})); 104 | } else if (message.event == 'addNewEntry') { 105 | storage.getData('clipboard').then((data) => { 106 | var clipboard = data.clipboard || []; 107 | clipboard.push({value: message.value, desc: message.value}); 108 | storage.setData({'clipboard': clipboard}).then(() => { 109 | sendResponse({}); 110 | rebuildMenus(); 111 | }, (error) => { 112 | sendResponse({'error': error}); 113 | rebuildMenus(); 114 | }); 115 | }, (error) => sendResponse({'error': error})); 116 | } 117 | return true; 118 | }); 119 | 120 | function installContentScriptInTabs() { 121 | chrome.tabs.query({}, function(tabs) { 122 | for(var i in tabs) { 123 | if (tabs[i].url.startsWith("http://") || tabs[i].url.startsWith("https://")) { 124 | chrome.tabs.executeScript(tabs[i].id, {file: "contentscript.js"}); 125 | } 126 | } 127 | }); 128 | } 129 | 130 | chrome.contextMenus.onClicked.addListener(onMenuClicked); 131 | 132 | chrome.runtime.onInstalled.addListener(function() { 133 | rebuildMenus(); 134 | installContentScriptInTabs(); 135 | }); -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | const ACTION__INSERT_TEXT = 'insertText'; 2 | const ACTION__ADD_SELECTION = 'addSelection'; 3 | 4 | const CONTACT_PAGE_URL = 'https://bartosz.im/permanent-clipboard/contact/index.html'; -------------------------------------------------------------------------------- /src/contentscript.js: -------------------------------------------------------------------------------- 1 | chrome.runtime.onMessage.addListener( 2 | function(message, sender, sendResponse) { 3 | switch (message.event) { 4 | case ACTION__INSERT_TEXT: 5 | document.execCommand("insertText", true, message.value); 6 | break; 7 | case ACTION__ADD_SELECTION: 8 | var selection = document.getSelection().toString(); 9 | if (selection.length > 0) 10 | chrome.runtime.sendMessage({event: 'addNewEntry', value: selection}, function(response) { 11 | if (response.error != null) 12 | alert(chrome.i18n.getMessage("errorFailedToSaveEntry") + response.error.message); 13 | }); 14 | break; 15 | default: 16 | console.warn('Unknown message event sent to content script' + message.event); 17 | } 18 | sendResponse({}); 19 | }); 20 | 21 | document.addEventListener('copy', function(e) { 22 | var selection = document.getSelection().toString(); 23 | if (selection.length > 0) 24 | chrome.runtime.sendMessage({event:"saveRecentItem", value: selection}, function(response) { 25 | if (response.error != null) 26 | console.error("Failed to save recent item: " + response.error.message); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/css/material-icons.css: -------------------------------------------------------------------------------- 1 | /* fallback */ 2 | @font-face { 3 | font-family: 'Material Icons'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: url(../fonts/Material-Icons.woff2) format('woff2'); 7 | } 8 | 9 | .material-icons { 10 | font-family: 'Material Icons'; 11 | font-weight: normal; 12 | font-style: normal; 13 | font-size: 24px; 14 | line-height: 1; 15 | letter-spacing: normal; 16 | text-transform: none; 17 | display: inline-block; 18 | white-space: nowrap; 19 | word-wrap: normal; 20 | direction: ltr; 21 | -webkit-font-feature-settings: 'liga'; 22 | -webkit-font-smoothing: antialiased; 23 | } 24 | -------------------------------------------------------------------------------- /src/css/options.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | 6 | main { 7 | flex: 1 0 auto; 8 | } 9 | 10 | #title { 11 | margin-left: 66px; 12 | font-size: 1.5rem; 13 | } 14 | 15 | .option-card-title { 16 | width: 680px; 17 | margin-left: auto; 18 | margin-right: auto; 19 | margin-top: 20pt; 20 | font-weight: 500; 21 | padding-left: 10pt; 22 | } 23 | 24 | .option-card { 25 | width: 680px; 26 | margin-left: auto; 27 | margin-right: auto; 28 | margin-top: 20pt; 29 | } 30 | 31 | .option-entry { 32 | margin-bottom: 0; 33 | display: flex; 34 | flex-direction: row; 35 | flex-wrap: nowrap; 36 | align-items: center; 37 | min-height: 46px; 38 | } 39 | 40 | .option-entry__name { 41 | flex-grow: 2; 42 | font-size: 1rem; 43 | align-items: flex-start; 44 | margin: auto 0; 45 | } 46 | 47 | .title-container { 48 | flex-grow: 2; 49 | align-items: flex-start; 50 | margin: auto 0; 51 | } 52 | 53 | .option-entry__title { 54 | flex-grow: 2; 55 | font-size: 1rem; 56 | align-items: flex-start; 57 | margin: auto 0; 58 | font-weight: bold; 59 | } 60 | 61 | .option-entry__subtitle { 62 | flex-grow: 2; 63 | font-size: 0.7rem; 64 | } 65 | 66 | .option-entry__action { 67 | display: flex; 68 | justify-content: flex-end; 69 | flex-grow: 2; 70 | align-self: flex-end; 71 | margin: auto 9pt; 72 | } 73 | 74 | /* Materialize css hack to remove bottom margin of select input */ 75 | .option-entry__action > div.select-wrapper > input.select-dropdown { 76 | margin-bottom: 0; 77 | } 78 | 79 | .option-entry__decorator { 80 | flex-shrink: 0; 81 | align-self: flex-end; 82 | margin: auto 0; 83 | } 84 | 85 | .select-dropdown { 86 | margin-bottom: 0; 87 | } 88 | 89 | .drop-overlay { 90 | width: 60%; 91 | height: 60%; 92 | margin-left: 20%; 93 | margin-top: 10%; 94 | position: absolute; 95 | background-color: #505050aa; 96 | z-index: -1; 97 | border-radius: 10pt; 98 | align-items: center; 99 | display: flex; 100 | justify-content: center; 101 | pointer-events:none; 102 | } 103 | 104 | .drop-overlay_content { 105 | color: white; 106 | font-size: 25pt; 107 | pointer-events:none; 108 | margin: 10pt; 109 | text-align:center; 110 | } 111 | 112 | .hidden { 113 | display: none; 114 | } 115 | 116 | .dropzone { 117 | box-sizing: border-box; 118 | position: fixed; 119 | width: 100%; 120 | height: 100%; 121 | left: 0; 122 | top: 0; 123 | z-index: 99999; 124 | } 125 | -------------------------------------------------------------------------------- /src/css/popup.css: -------------------------------------------------------------------------------- 1 | body { 2 | min-width: 357px; 3 | min-height: 357px; 4 | font-size: 10pt; 5 | display: flex; 6 | flex-direction: column; 7 | } 8 | 9 | main { 10 | flex: 1 0 auto; 11 | } 12 | 13 | a { 14 | cursor: pointer; 15 | } 16 | 17 | .default-cursor { 18 | cursor: default; 19 | } 20 | 21 | .ml1 { 22 | margin-left: 1pt; 23 | } 24 | 25 | .actionbtn { 26 | cursor: pointer; 27 | float: right; 28 | } 29 | 30 | div.rowrow { 31 | min-height: 40px; 32 | margin-bottom: 0; 33 | } 34 | .material-tooltip { 35 | white-space: pre; 36 | } 37 | 38 | td { 39 | padding: 10px 10px; 40 | } 41 | 42 | td.actioncell { 43 | width: 18pt; 44 | } 45 | 46 | div.cinvisible { 47 | display: none; 48 | } 49 | #current_div { 50 | padding-bottom: 0px; 51 | } 52 | div.top-padded { 53 | padding-top: 20px; 54 | padding-bottom: 1em; 55 | } 56 | 57 | .list-placeholder { 58 | background-color: #f5f5f5; 59 | } 60 | 61 | .topbar-button { 62 | margin-top: -20px; 63 | margin-left: 5pt; 64 | margin-right: 5pt; 65 | } 66 | 67 | .btn-action { 68 | padding: 0 .5em; 69 | } 70 | -------------------------------------------------------------------------------- /src/css/translators.css: -------------------------------------------------------------------------------- 1 | .option-entry__language { 2 | flex-grow: 2; 3 | font-size: 1rem; 4 | align-items: flex-start; 5 | margin: auto 0; 6 | } 7 | 8 | .option-entry__translator { 9 | display: flex; 10 | justify-content: flex-end; 11 | flex-grow: 2; 12 | align-self: flex-end; 13 | margin: auto 9pt; 14 | font-size: 1rem; 15 | } 16 | -------------------------------------------------------------------------------- /src/fonts/Material-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/Material-Icons.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Bold.eot -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Bold.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Light.eot -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Light.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Medium.eot -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Medium.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Regular.eot -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Thin.eot -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Thin.ttf -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /src/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /src/img/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icon-128.png -------------------------------------------------------------------------------- /src/img/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icon-16.png -------------------------------------------------------------------------------- /src/img/icon-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icon-19.png -------------------------------------------------------------------------------- /src/img/icon-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icon-38.png -------------------------------------------------------------------------------- /src/img/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/img/icons/ic_folder_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icons/ic_folder_1x.png -------------------------------------------------------------------------------- /src/img/icons/ic_folder_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icons/ic_folder_2x.png -------------------------------------------------------------------------------- /src/img/icons/ic_help_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icons/ic_help_1x.png -------------------------------------------------------------------------------- /src/img/icons/ic_help_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icons/ic_help_2x.png -------------------------------------------------------------------------------- /src/img/icons/ic_navigate_before_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icons/ic_navigate_before_1x.png -------------------------------------------------------------------------------- /src/img/icons/ic_navigate_before_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/img/icons/ic_navigate_before_2x.png -------------------------------------------------------------------------------- /src/jquery-ui/AUTHORS.txt: -------------------------------------------------------------------------------- 1 | Authors ordered by first contribution 2 | A list of current team members is available at http://jqueryui.com/about 3 | 4 | Paul Bakaus 5 | Richard Worth 6 | Yehuda Katz 7 | Sean Catchpole 8 | John Resig 9 | Tane Piper 10 | Dmitri Gaskin 11 | Klaus Hartl 12 | Stefan Petre 13 | Gilles van den Hoven 14 | Micheil Bryan Smith 15 | Jörn Zaefferer 16 | Marc Grabanski 17 | Keith Wood 18 | Brandon Aaron 19 | Scott González 20 | Eduardo Lundgren 21 | Aaron Eisenberger 22 | Joan Piedra 23 | Bruno Basto 24 | Remy Sharp 25 | Bohdan Ganicky 26 | David Bolter 27 | Chi Cheng 28 | Ca-Phun Ung 29 | Ariel Flesler 30 | Maggie Wachs 31 | Scott Jehl 32 | Todd Parker 33 | Andrew Powell 34 | Brant Burnett 35 | Douglas Neiner 36 | Paul Irish 37 | Ralph Whitbeck 38 | Thibault Duplessis 39 | Dominique Vincent 40 | Jack Hsu 41 | Adam Sontag 42 | Carl Fürstenberg 43 | Kevin Dalman 44 | Alberto Fernández Capel 45 | Jacek Jędrzejewski (http://jacek.jedrzejewski.name) 46 | Ting Kuei 47 | Samuel Cormier-Iijima 48 | Jon Palmer 49 | Ben Hollis 50 | Justin MacCarthy 51 | Eyal Kobrigo 52 | Tiago Freire 53 | Diego Tres 54 | Holger Rüprich 55 | Ziling Zhao 56 | Mike Alsup 57 | Robson Braga Araujo 58 | Pierre-Henri Ausseil 59 | Christopher McCulloh 60 | Andrew Newcomb 61 | Lim Chee Aun 62 | Jorge Barreiro 63 | Daniel Steigerwald 64 | John Firebaugh 65 | John Enters 66 | Andrey Kapitcyn 67 | Dmitry Petrov 68 | Eric Hynds 69 | Chairat Sunthornwiphat 70 | Josh Varner 71 | Stéphane Raimbault 72 | Jay Merrifield 73 | J. Ryan Stinnett 74 | Peter Heiberg 75 | Alex Dovenmuehle 76 | Jamie Gegerson 77 | Raymond Schwartz 78 | Phillip Barnes 79 | Kyle Wilkinson 80 | Khaled AlHourani 81 | Marian Rudzynski 82 | Jean-Francois Remy 83 | Doug Blood 84 | Filippo Cavallarin 85 | Heiko Henning 86 | Aliaksandr Rahalevich 87 | Mario Visic 88 | Xavi Ramirez 89 | Max Schnur 90 | Saji Nediyanchath 91 | Corey Frang 92 | Aaron Peterson 93 | Ivan Peters 94 | Mohamed Cherif Bouchelaghem 95 | Marcos Sousa 96 | Michael DellaNoce 97 | George Marshall 98 | Tobias Brunner 99 | Martin Solli 100 | David Petersen 101 | Dan Heberden 102 | William Kevin Manire 103 | Gilmore Davidson 104 | Michael Wu 105 | Adam Parod 106 | Guillaume Gautreau 107 | Marcel Toele 108 | Dan Streetman 109 | Matt Hoskins 110 | Giovanni Giacobbi 111 | Kyle Florence 112 | Pavol Hluchý 113 | Hans Hillen 114 | Mark Johnson 115 | Trey Hunner 116 | Shane Whittet 117 | Edward A Faulkner 118 | Adam Baratz 119 | Kato Kazuyoshi 120 | Eike Send 121 | Kris Borchers 122 | Eddie Monge 123 | Israel Tsadok 124 | Carson McDonald 125 | Jason Davies 126 | Garrison Locke 127 | David Murdoch 128 | Benjamin Scott Boyle 129 | Jesse Baird 130 | Jonathan Vingiano 131 | Dylan Just 132 | Hiroshi Tomita 133 | Glenn Goodrich 134 | Tarafder Ashek-E-Elahi 135 | Ryan Neufeld 136 | Marc Neuwirth 137 | Philip Graham 138 | Benjamin Sterling 139 | Wesley Walser 140 | Kouhei Sutou 141 | Karl Kirch 142 | Chris Kelly 143 | Jason Oster 144 | Felix Nagel 145 | Alexander Polomoshnov 146 | David Leal 147 | Igor Milla 148 | Dave Methvin 149 | Florian Gutmann 150 | Marwan Al Jubeh 151 | Milan Broum 152 | Sebastian Sauer 153 | Gaëtan Muller 154 | Michel Weimerskirch 155 | William Griffiths 156 | Stojce Slavkovski 157 | David Soms 158 | David De Sloovere 159 | Michael P. Jung 160 | Shannon Pekary 161 | Dan Wellman 162 | Matthew Edward Hutton 163 | James Khoury 164 | Rob Loach 165 | Alberto Monteiro 166 | Alex Rhea 167 | Krzysztof Rosiński 168 | Ryan Olton 169 | Genie <386@mail.com> 170 | Rick Waldron 171 | Ian Simpson 172 | Lev Kitsis 173 | TJ VanToll 174 | Justin Domnitz 175 | Douglas Cerna 176 | Bert ter Heide 177 | Jasvir Nagra 178 | Yuriy Khabarov <13real008@gmail.com> 179 | Harri Kilpiö 180 | Lado Lomidze 181 | Amir E. Aharoni 182 | Simon Sattes 183 | Jo Liss 184 | Guntupalli Karunakar 185 | Shahyar Ghobadpour 186 | Lukasz Lipinski 187 | Timo Tijhof 188 | Jason Moon 189 | Martin Frost 190 | Eneko Illarramendi 191 | EungJun Yi 192 | Courtland Allen 193 | Viktar Varvanovich 194 | Danny Trunk 195 | Pavel Stetina 196 | Michael Stay 197 | Steven Roussey 198 | Michael Hollis 199 | Lee Rowlands 200 | Timmy Willison 201 | Karl Swedberg 202 | Baoju Yuan 203 | Maciej Mroziński 204 | Luis Dalmolin 205 | Mark Aaron Shirley 206 | Martin Hoch 207 | Jiayi Yang 208 | Philipp Benjamin Köppchen 209 | Sindre Sorhus 210 | Bernhard Sirlinger 211 | Jared A. Scheel 212 | Rafael Xavier de Souza 213 | John Chen 214 | Robert Beuligmann 215 | Dale Kocian 216 | Mike Sherov 217 | Andrew Couch 218 | Marc-Andre Lafortune 219 | Nate Eagle 220 | David Souther 221 | Mathias Stenbom 222 | Sergey Kartashov 223 | Avinash R 224 | Ethan Romba 225 | Cory Gackenheimer 226 | Juan Pablo Kaniefsky 227 | Roman Salnikov 228 | Anika Henke 229 | Samuel Bovée 230 | Fabrício Matté 231 | Viktor Kojouharov 232 | Pawel Maruszczyk (http://hrabstwo.net) 233 | Pavel Selitskas 234 | Bjørn Johansen 235 | Matthieu Penant 236 | Dominic Barnes 237 | David Sullivan 238 | Thomas Jaggi 239 | Vahid Sohrabloo 240 | Travis Carden 241 | Bruno M. Custódio 242 | Nathanael Silverman 243 | Christian Wenz 244 | Steve Urmston 245 | Zaven Muradyan 246 | Woody Gilk 247 | Zbigniew Motyka 248 | Suhail Alkowaileet 249 | Toshi MARUYAMA 250 | David Hansen 251 | Brian Grinstead 252 | Christian Klammer 253 | Steven Luscher 254 | Gan Eng Chin 255 | Gabriel Schulhof 256 | Alexander Schmitz 257 | Vilhjálmur Skúlason 258 | Siebrand Mazeland 259 | Mohsen Ekhtiari 260 | Pere Orga 261 | Jasper de Groot 262 | Stephane Deschamps 263 | Jyoti Deka 264 | Andrei Picus 265 | Ondrej Novy 266 | Jacob McCutcheon 267 | Monika Piotrowicz 268 | Imants Horsts 269 | Eric Dahl 270 | Dave Stein 271 | Dylan Barrell 272 | Daniel DeGroff 273 | Michael Wiencek 274 | Thomas Meyer 275 | Ruslan Yakhyaev 276 | Brian J. Dowling 277 | Ben Higgins 278 | Yermo Lamers 279 | Patrick Stapleton 280 | Trisha Crowley 281 | Usman Akeju 282 | Rodrigo Menezes 283 | Jacques Perrault 284 | Frederik Elvhage 285 | Will Holley 286 | Uri Gilad 287 | Richard Gibson 288 | Simen Bekkhus 289 | Chen Eshchar 290 | Bruno Pérel 291 | Mohammed Alshehri 292 | Lisa Seacat DeLuca 293 | Anne-Gaelle Colom 294 | Adam Foster 295 | Luke Page 296 | Daniel Owens 297 | Michael Orchard 298 | Marcus Warren 299 | Nils Heuermann 300 | Marco Ziech 301 | Patricia Juarez 302 | Ben Mosher 303 | Ablay Keldibek 304 | Thomas Applencourt 305 | Jiabao Wu 306 | Eric Lee Carraway 307 | Victor Homyakov 308 | Myeongjin Lee 309 | Liran Sharir 310 | Weston Ruter 311 | Mani Mishra 312 | Hannah Methvin 313 | Leonardo Balter 314 | Benjamin Albert 315 | Michał Gołębiowski 316 | Alyosha Pushak 317 | Fahad Ahmad 318 | Matt Brundage 319 | Francesc Baeta 320 | Piotr Baran 321 | Mukul Hase 322 | Konstantin Dinev 323 | Rand Scullard 324 | Dan Strohl 325 | Maksim Ryzhikov 326 | Amine HADDAD 327 | Amanpreet Singh 328 | Alexey Balchunas 329 | Peter Kehl 330 | Peter Dave Hello 331 | Johannes Schäfer 332 | Ville Skyttä 333 | Ryan Oriecuia 334 | -------------------------------------------------------------------------------- /src/jquery-ui/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery-ui 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | Copyright and related rights for sample code are waived via CC0. Sample 34 | code is defined as all source code contained within the demos directory. 35 | 36 | CC0: http://creativecommons.org/publicdomain/zero/1.0/ 37 | 38 | ==== 39 | 40 | All files located in the node_modules and external directories are 41 | externally maintained libraries used by this software which have their 42 | own licenses; we recommend you read them, as their terms may differ from 43 | the terms above. 44 | -------------------------------------------------------------------------------- /src/jquery-ui/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/jquery-ui/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /src/jquery-ui/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/jquery-ui/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /src/jquery-ui/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/jquery-ui/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /src/jquery-ui/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/jquery-ui/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /src/jquery-ui/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/jquery-ui/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /src/jquery-ui/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/przybylski/permanent-clipboard/75bf107c7bf4d7720d57ec996f35b4e73416925a/src/jquery-ui/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /src/jquery-ui/jquery-ui.structure.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.12.1 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | .ui-draggable-handle { 12 | -ms-touch-action: none; 13 | touch-action: none; 14 | } 15 | /* Layout helpers 16 | ----------------------------------*/ 17 | .ui-helper-hidden { 18 | display: none; 19 | } 20 | .ui-helper-hidden-accessible { 21 | border: 0; 22 | clip: rect(0 0 0 0); 23 | height: 1px; 24 | margin: -1px; 25 | overflow: hidden; 26 | padding: 0; 27 | position: absolute; 28 | width: 1px; 29 | } 30 | .ui-helper-reset { 31 | margin: 0; 32 | padding: 0; 33 | border: 0; 34 | outline: 0; 35 | line-height: 1.3; 36 | text-decoration: none; 37 | font-size: 100%; 38 | list-style: none; 39 | } 40 | .ui-helper-clearfix:before, 41 | .ui-helper-clearfix:after { 42 | content: ""; 43 | display: table; 44 | border-collapse: collapse; 45 | } 46 | .ui-helper-clearfix:after { 47 | clear: both; 48 | } 49 | .ui-helper-zfix { 50 | width: 100%; 51 | height: 100%; 52 | top: 0; 53 | left: 0; 54 | position: absolute; 55 | opacity: 0; 56 | filter:Alpha(Opacity=0); /* support: IE8 */ 57 | } 58 | 59 | .ui-front { 60 | z-index: 100; 61 | } 62 | 63 | 64 | /* Interaction Cues 65 | ----------------------------------*/ 66 | .ui-state-disabled { 67 | cursor: default !important; 68 | pointer-events: none; 69 | } 70 | 71 | 72 | /* Icons 73 | ----------------------------------*/ 74 | .ui-icon { 75 | display: inline-block; 76 | vertical-align: middle; 77 | margin-top: -.25em; 78 | position: relative; 79 | text-indent: -99999px; 80 | overflow: hidden; 81 | background-repeat: no-repeat; 82 | } 83 | 84 | .ui-widget-icon-block { 85 | left: 50%; 86 | margin-left: -8px; 87 | display: block; 88 | } 89 | 90 | /* Misc visuals 91 | ----------------------------------*/ 92 | 93 | /* Overlays */ 94 | .ui-widget-overlay { 95 | position: fixed; 96 | top: 0; 97 | left: 0; 98 | width: 100%; 99 | height: 100%; 100 | } 101 | .ui-resizable { 102 | position: relative; 103 | } 104 | .ui-resizable-handle { 105 | position: absolute; 106 | font-size: 0.1px; 107 | display: block; 108 | -ms-touch-action: none; 109 | touch-action: none; 110 | } 111 | .ui-resizable-disabled .ui-resizable-handle, 112 | .ui-resizable-autohide .ui-resizable-handle { 113 | display: none; 114 | } 115 | .ui-resizable-n { 116 | cursor: n-resize; 117 | height: 7px; 118 | width: 100%; 119 | top: -5px; 120 | left: 0; 121 | } 122 | .ui-resizable-s { 123 | cursor: s-resize; 124 | height: 7px; 125 | width: 100%; 126 | bottom: -5px; 127 | left: 0; 128 | } 129 | .ui-resizable-e { 130 | cursor: e-resize; 131 | width: 7px; 132 | right: -5px; 133 | top: 0; 134 | height: 100%; 135 | } 136 | .ui-resizable-w { 137 | cursor: w-resize; 138 | width: 7px; 139 | left: -5px; 140 | top: 0; 141 | height: 100%; 142 | } 143 | .ui-resizable-se { 144 | cursor: se-resize; 145 | width: 12px; 146 | height: 12px; 147 | right: 1px; 148 | bottom: 1px; 149 | } 150 | .ui-resizable-sw { 151 | cursor: sw-resize; 152 | width: 9px; 153 | height: 9px; 154 | left: -5px; 155 | bottom: -5px; 156 | } 157 | .ui-resizable-nw { 158 | cursor: nw-resize; 159 | width: 9px; 160 | height: 9px; 161 | left: -5px; 162 | top: -5px; 163 | } 164 | .ui-resizable-ne { 165 | cursor: ne-resize; 166 | width: 9px; 167 | height: 9px; 168 | right: -5px; 169 | top: -5px; 170 | } 171 | .ui-selectable { 172 | -ms-touch-action: none; 173 | touch-action: none; 174 | } 175 | .ui-selectable-helper { 176 | position: absolute; 177 | z-index: 100; 178 | border: 1px dotted black; 179 | } 180 | .ui-sortable-handle { 181 | -ms-touch-action: none; 182 | touch-action: none; 183 | } 184 | .ui-accordion .ui-accordion-header { 185 | display: block; 186 | cursor: pointer; 187 | position: relative; 188 | margin: 2px 0 0 0; 189 | padding: .5em .5em .5em .7em; 190 | font-size: 100%; 191 | } 192 | .ui-accordion .ui-accordion-content { 193 | padding: 1em 2.2em; 194 | border-top: 0; 195 | overflow: auto; 196 | } 197 | .ui-autocomplete { 198 | position: absolute; 199 | top: 0; 200 | left: 0; 201 | cursor: default; 202 | } 203 | .ui-menu { 204 | list-style: none; 205 | padding: 0; 206 | margin: 0; 207 | display: block; 208 | outline: 0; 209 | } 210 | .ui-menu .ui-menu { 211 | position: absolute; 212 | } 213 | .ui-menu .ui-menu-item { 214 | margin: 0; 215 | cursor: pointer; 216 | /* support: IE10, see #8844 */ 217 | list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); 218 | } 219 | .ui-menu .ui-menu-item-wrapper { 220 | position: relative; 221 | padding: 3px 1em 3px .4em; 222 | } 223 | .ui-menu .ui-menu-divider { 224 | margin: 5px 0; 225 | height: 0; 226 | font-size: 0; 227 | line-height: 0; 228 | border-width: 1px 0 0 0; 229 | } 230 | .ui-menu .ui-state-focus, 231 | .ui-menu .ui-state-active { 232 | margin: -1px; 233 | } 234 | 235 | /* icon support */ 236 | .ui-menu-icons { 237 | position: relative; 238 | } 239 | .ui-menu-icons .ui-menu-item-wrapper { 240 | padding-left: 2em; 241 | } 242 | 243 | /* left-aligned */ 244 | .ui-menu .ui-icon { 245 | position: absolute; 246 | top: 0; 247 | bottom: 0; 248 | left: .2em; 249 | margin: auto 0; 250 | } 251 | 252 | /* right-aligned */ 253 | .ui-menu .ui-menu-icon { 254 | left: auto; 255 | right: 0; 256 | } 257 | .ui-button { 258 | padding: .4em 1em; 259 | display: inline-block; 260 | position: relative; 261 | line-height: normal; 262 | margin-right: .1em; 263 | cursor: pointer; 264 | vertical-align: middle; 265 | text-align: center; 266 | -webkit-user-select: none; 267 | -moz-user-select: none; 268 | -ms-user-select: none; 269 | user-select: none; 270 | 271 | /* Support: IE <= 11 */ 272 | overflow: visible; 273 | } 274 | 275 | .ui-button, 276 | .ui-button:link, 277 | .ui-button:visited, 278 | .ui-button:hover, 279 | .ui-button:active { 280 | text-decoration: none; 281 | } 282 | 283 | /* to make room for the icon, a width needs to be set here */ 284 | .ui-button-icon-only { 285 | width: 2em; 286 | box-sizing: border-box; 287 | text-indent: -9999px; 288 | white-space: nowrap; 289 | } 290 | 291 | /* no icon support for input elements */ 292 | input.ui-button.ui-button-icon-only { 293 | text-indent: 0; 294 | } 295 | 296 | /* button icon element(s) */ 297 | .ui-button-icon-only .ui-icon { 298 | position: absolute; 299 | top: 50%; 300 | left: 50%; 301 | margin-top: -8px; 302 | margin-left: -8px; 303 | } 304 | 305 | .ui-button.ui-icon-notext .ui-icon { 306 | padding: 0; 307 | width: 2.1em; 308 | height: 2.1em; 309 | text-indent: -9999px; 310 | white-space: nowrap; 311 | 312 | } 313 | 314 | input.ui-button.ui-icon-notext .ui-icon { 315 | width: auto; 316 | height: auto; 317 | text-indent: 0; 318 | white-space: normal; 319 | padding: .4em 1em; 320 | } 321 | 322 | /* workarounds */ 323 | /* Support: Firefox 5 - 40 */ 324 | input.ui-button::-moz-focus-inner, 325 | button.ui-button::-moz-focus-inner { 326 | border: 0; 327 | padding: 0; 328 | } 329 | .ui-controlgroup { 330 | vertical-align: middle; 331 | display: inline-block; 332 | } 333 | .ui-controlgroup > .ui-controlgroup-item { 334 | float: left; 335 | margin-left: 0; 336 | margin-right: 0; 337 | } 338 | .ui-controlgroup > .ui-controlgroup-item:focus, 339 | .ui-controlgroup > .ui-controlgroup-item.ui-visual-focus { 340 | z-index: 9999; 341 | } 342 | .ui-controlgroup-vertical > .ui-controlgroup-item { 343 | display: block; 344 | float: none; 345 | width: 100%; 346 | margin-top: 0; 347 | margin-bottom: 0; 348 | text-align: left; 349 | } 350 | .ui-controlgroup-vertical .ui-controlgroup-item { 351 | box-sizing: border-box; 352 | } 353 | .ui-controlgroup .ui-controlgroup-label { 354 | padding: .4em 1em; 355 | } 356 | .ui-controlgroup .ui-controlgroup-label span { 357 | font-size: 80%; 358 | } 359 | .ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item { 360 | border-left: none; 361 | } 362 | .ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item { 363 | border-top: none; 364 | } 365 | .ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content { 366 | border-right: none; 367 | } 368 | .ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content { 369 | border-bottom: none; 370 | } 371 | 372 | /* Spinner specific style fixes */ 373 | .ui-controlgroup-vertical .ui-spinner-input { 374 | 375 | /* Support: IE8 only, Android < 4.4 only */ 376 | width: 75%; 377 | width: calc( 100% - 2.4em ); 378 | } 379 | .ui-controlgroup-vertical .ui-spinner .ui-spinner-up { 380 | border-top-style: solid; 381 | } 382 | 383 | .ui-checkboxradio-label .ui-icon-background { 384 | box-shadow: inset 1px 1px 1px #ccc; 385 | border-radius: .12em; 386 | border: none; 387 | } 388 | .ui-checkboxradio-radio-label .ui-icon-background { 389 | width: 16px; 390 | height: 16px; 391 | border-radius: 1em; 392 | overflow: visible; 393 | border: none; 394 | } 395 | .ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon, 396 | .ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon { 397 | background-image: none; 398 | width: 8px; 399 | height: 8px; 400 | border-width: 4px; 401 | border-style: solid; 402 | } 403 | .ui-checkboxradio-disabled { 404 | pointer-events: none; 405 | } 406 | .ui-datepicker { 407 | width: 17em; 408 | padding: .2em .2em 0; 409 | display: none; 410 | } 411 | .ui-datepicker .ui-datepicker-header { 412 | position: relative; 413 | padding: .2em 0; 414 | } 415 | .ui-datepicker .ui-datepicker-prev, 416 | .ui-datepicker .ui-datepicker-next { 417 | position: absolute; 418 | top: 2px; 419 | width: 1.8em; 420 | height: 1.8em; 421 | } 422 | .ui-datepicker .ui-datepicker-prev-hover, 423 | .ui-datepicker .ui-datepicker-next-hover { 424 | top: 1px; 425 | } 426 | .ui-datepicker .ui-datepicker-prev { 427 | left: 2px; 428 | } 429 | .ui-datepicker .ui-datepicker-next { 430 | right: 2px; 431 | } 432 | .ui-datepicker .ui-datepicker-prev-hover { 433 | left: 1px; 434 | } 435 | .ui-datepicker .ui-datepicker-next-hover { 436 | right: 1px; 437 | } 438 | .ui-datepicker .ui-datepicker-prev span, 439 | .ui-datepicker .ui-datepicker-next span { 440 | display: block; 441 | position: absolute; 442 | left: 50%; 443 | margin-left: -8px; 444 | top: 50%; 445 | margin-top: -8px; 446 | } 447 | .ui-datepicker .ui-datepicker-title { 448 | margin: 0 2.3em; 449 | line-height: 1.8em; 450 | text-align: center; 451 | } 452 | .ui-datepicker .ui-datepicker-title select { 453 | font-size: 1em; 454 | margin: 1px 0; 455 | } 456 | .ui-datepicker select.ui-datepicker-month, 457 | .ui-datepicker select.ui-datepicker-year { 458 | width: 45%; 459 | } 460 | .ui-datepicker table { 461 | width: 100%; 462 | font-size: .9em; 463 | border-collapse: collapse; 464 | margin: 0 0 .4em; 465 | } 466 | .ui-datepicker th { 467 | padding: .7em .3em; 468 | text-align: center; 469 | font-weight: bold; 470 | border: 0; 471 | } 472 | .ui-datepicker td { 473 | border: 0; 474 | padding: 1px; 475 | } 476 | .ui-datepicker td span, 477 | .ui-datepicker td a { 478 | display: block; 479 | padding: .2em; 480 | text-align: right; 481 | text-decoration: none; 482 | } 483 | .ui-datepicker .ui-datepicker-buttonpane { 484 | background-image: none; 485 | margin: .7em 0 0 0; 486 | padding: 0 .2em; 487 | border-left: 0; 488 | border-right: 0; 489 | border-bottom: 0; 490 | } 491 | .ui-datepicker .ui-datepicker-buttonpane button { 492 | float: right; 493 | margin: .5em .2em .4em; 494 | cursor: pointer; 495 | padding: .2em .6em .3em .6em; 496 | width: auto; 497 | overflow: visible; 498 | } 499 | .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { 500 | float: left; 501 | } 502 | 503 | /* with multiple calendars */ 504 | .ui-datepicker.ui-datepicker-multi { 505 | width: auto; 506 | } 507 | .ui-datepicker-multi .ui-datepicker-group { 508 | float: left; 509 | } 510 | .ui-datepicker-multi .ui-datepicker-group table { 511 | width: 95%; 512 | margin: 0 auto .4em; 513 | } 514 | .ui-datepicker-multi-2 .ui-datepicker-group { 515 | width: 50%; 516 | } 517 | .ui-datepicker-multi-3 .ui-datepicker-group { 518 | width: 33.3%; 519 | } 520 | .ui-datepicker-multi-4 .ui-datepicker-group { 521 | width: 25%; 522 | } 523 | .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, 524 | .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { 525 | border-left-width: 0; 526 | } 527 | .ui-datepicker-multi .ui-datepicker-buttonpane { 528 | clear: left; 529 | } 530 | .ui-datepicker-row-break { 531 | clear: both; 532 | width: 100%; 533 | font-size: 0; 534 | } 535 | 536 | /* RTL support */ 537 | .ui-datepicker-rtl { 538 | direction: rtl; 539 | } 540 | .ui-datepicker-rtl .ui-datepicker-prev { 541 | right: 2px; 542 | left: auto; 543 | } 544 | .ui-datepicker-rtl .ui-datepicker-next { 545 | left: 2px; 546 | right: auto; 547 | } 548 | .ui-datepicker-rtl .ui-datepicker-prev:hover { 549 | right: 1px; 550 | left: auto; 551 | } 552 | .ui-datepicker-rtl .ui-datepicker-next:hover { 553 | left: 1px; 554 | right: auto; 555 | } 556 | .ui-datepicker-rtl .ui-datepicker-buttonpane { 557 | clear: right; 558 | } 559 | .ui-datepicker-rtl .ui-datepicker-buttonpane button { 560 | float: left; 561 | } 562 | .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, 563 | .ui-datepicker-rtl .ui-datepicker-group { 564 | float: right; 565 | } 566 | .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, 567 | .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { 568 | border-right-width: 0; 569 | border-left-width: 1px; 570 | } 571 | 572 | /* Icons */ 573 | .ui-datepicker .ui-icon { 574 | display: block; 575 | text-indent: -99999px; 576 | overflow: hidden; 577 | background-repeat: no-repeat; 578 | left: .5em; 579 | top: .3em; 580 | } 581 | .ui-dialog { 582 | position: absolute; 583 | top: 0; 584 | left: 0; 585 | padding: .2em; 586 | outline: 0; 587 | } 588 | .ui-dialog .ui-dialog-titlebar { 589 | padding: .4em 1em; 590 | position: relative; 591 | } 592 | .ui-dialog .ui-dialog-title { 593 | float: left; 594 | margin: .1em 0; 595 | white-space: nowrap; 596 | width: 90%; 597 | overflow: hidden; 598 | text-overflow: ellipsis; 599 | } 600 | .ui-dialog .ui-dialog-titlebar-close { 601 | position: absolute; 602 | right: .3em; 603 | top: 50%; 604 | width: 20px; 605 | margin: -10px 0 0 0; 606 | padding: 1px; 607 | height: 20px; 608 | } 609 | .ui-dialog .ui-dialog-content { 610 | position: relative; 611 | border: 0; 612 | padding: .5em 1em; 613 | background: none; 614 | overflow: auto; 615 | } 616 | .ui-dialog .ui-dialog-buttonpane { 617 | text-align: left; 618 | border-width: 1px 0 0 0; 619 | background-image: none; 620 | margin-top: .5em; 621 | padding: .3em 1em .5em .4em; 622 | } 623 | .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { 624 | float: right; 625 | } 626 | .ui-dialog .ui-dialog-buttonpane button { 627 | margin: .5em .4em .5em 0; 628 | cursor: pointer; 629 | } 630 | .ui-dialog .ui-resizable-n { 631 | height: 2px; 632 | top: 0; 633 | } 634 | .ui-dialog .ui-resizable-e { 635 | width: 2px; 636 | right: 0; 637 | } 638 | .ui-dialog .ui-resizable-s { 639 | height: 2px; 640 | bottom: 0; 641 | } 642 | .ui-dialog .ui-resizable-w { 643 | width: 2px; 644 | left: 0; 645 | } 646 | .ui-dialog .ui-resizable-se, 647 | .ui-dialog .ui-resizable-sw, 648 | .ui-dialog .ui-resizable-ne, 649 | .ui-dialog .ui-resizable-nw { 650 | width: 7px; 651 | height: 7px; 652 | } 653 | .ui-dialog .ui-resizable-se { 654 | right: 0; 655 | bottom: 0; 656 | } 657 | .ui-dialog .ui-resizable-sw { 658 | left: 0; 659 | bottom: 0; 660 | } 661 | .ui-dialog .ui-resizable-ne { 662 | right: 0; 663 | top: 0; 664 | } 665 | .ui-dialog .ui-resizable-nw { 666 | left: 0; 667 | top: 0; 668 | } 669 | .ui-draggable .ui-dialog-titlebar { 670 | cursor: move; 671 | } 672 | .ui-progressbar { 673 | height: 2em; 674 | text-align: left; 675 | overflow: hidden; 676 | } 677 | .ui-progressbar .ui-progressbar-value { 678 | margin: -1px; 679 | height: 100%; 680 | } 681 | .ui-progressbar .ui-progressbar-overlay { 682 | background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw=="); 683 | height: 100%; 684 | filter: alpha(opacity=25); /* support: IE8 */ 685 | opacity: 0.25; 686 | } 687 | .ui-progressbar-indeterminate .ui-progressbar-value { 688 | background-image: none; 689 | } 690 | .ui-selectmenu-menu { 691 | padding: 0; 692 | margin: 0; 693 | position: absolute; 694 | top: 0; 695 | left: 0; 696 | display: none; 697 | } 698 | .ui-selectmenu-menu .ui-menu { 699 | overflow: auto; 700 | overflow-x: hidden; 701 | padding-bottom: 1px; 702 | } 703 | .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { 704 | font-size: 1em; 705 | font-weight: bold; 706 | line-height: 1.5; 707 | padding: 2px 0.4em; 708 | margin: 0.5em 0 0 0; 709 | height: auto; 710 | border: 0; 711 | } 712 | .ui-selectmenu-open { 713 | display: block; 714 | } 715 | .ui-selectmenu-text { 716 | display: block; 717 | margin-right: 20px; 718 | overflow: hidden; 719 | text-overflow: ellipsis; 720 | } 721 | .ui-selectmenu-button.ui-button { 722 | text-align: left; 723 | white-space: nowrap; 724 | width: 14em; 725 | } 726 | .ui-selectmenu-icon.ui-icon { 727 | float: right; 728 | margin-top: 0; 729 | } 730 | .ui-slider { 731 | position: relative; 732 | text-align: left; 733 | } 734 | .ui-slider .ui-slider-handle { 735 | position: absolute; 736 | z-index: 2; 737 | width: 1.2em; 738 | height: 1.2em; 739 | cursor: default; 740 | -ms-touch-action: none; 741 | touch-action: none; 742 | } 743 | .ui-slider .ui-slider-range { 744 | position: absolute; 745 | z-index: 1; 746 | font-size: .7em; 747 | display: block; 748 | border: 0; 749 | background-position: 0 0; 750 | } 751 | 752 | /* support: IE8 - See #6727 */ 753 | .ui-slider.ui-state-disabled .ui-slider-handle, 754 | .ui-slider.ui-state-disabled .ui-slider-range { 755 | filter: inherit; 756 | } 757 | 758 | .ui-slider-horizontal { 759 | height: .8em; 760 | } 761 | .ui-slider-horizontal .ui-slider-handle { 762 | top: -.3em; 763 | margin-left: -.6em; 764 | } 765 | .ui-slider-horizontal .ui-slider-range { 766 | top: 0; 767 | height: 100%; 768 | } 769 | .ui-slider-horizontal .ui-slider-range-min { 770 | left: 0; 771 | } 772 | .ui-slider-horizontal .ui-slider-range-max { 773 | right: 0; 774 | } 775 | 776 | .ui-slider-vertical { 777 | width: .8em; 778 | height: 100px; 779 | } 780 | .ui-slider-vertical .ui-slider-handle { 781 | left: -.3em; 782 | margin-left: 0; 783 | margin-bottom: -.6em; 784 | } 785 | .ui-slider-vertical .ui-slider-range { 786 | left: 0; 787 | width: 100%; 788 | } 789 | .ui-slider-vertical .ui-slider-range-min { 790 | bottom: 0; 791 | } 792 | .ui-slider-vertical .ui-slider-range-max { 793 | top: 0; 794 | } 795 | .ui-spinner { 796 | position: relative; 797 | display: inline-block; 798 | overflow: hidden; 799 | padding: 0; 800 | vertical-align: middle; 801 | } 802 | .ui-spinner-input { 803 | border: none; 804 | background: none; 805 | color: inherit; 806 | padding: .222em 0; 807 | margin: .2em 0; 808 | vertical-align: middle; 809 | margin-left: .4em; 810 | margin-right: 2em; 811 | } 812 | .ui-spinner-button { 813 | width: 1.6em; 814 | height: 50%; 815 | font-size: .5em; 816 | padding: 0; 817 | margin: 0; 818 | text-align: center; 819 | position: absolute; 820 | cursor: default; 821 | display: block; 822 | overflow: hidden; 823 | right: 0; 824 | } 825 | /* more specificity required here to override default borders */ 826 | .ui-spinner a.ui-spinner-button { 827 | border-top-style: none; 828 | border-bottom-style: none; 829 | border-right-style: none; 830 | } 831 | .ui-spinner-up { 832 | top: 0; 833 | } 834 | .ui-spinner-down { 835 | bottom: 0; 836 | } 837 | .ui-tabs { 838 | position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ 839 | padding: .2em; 840 | } 841 | .ui-tabs .ui-tabs-nav { 842 | margin: 0; 843 | padding: .2em .2em 0; 844 | } 845 | .ui-tabs .ui-tabs-nav li { 846 | list-style: none; 847 | float: left; 848 | position: relative; 849 | top: 0; 850 | margin: 1px .2em 0 0; 851 | border-bottom-width: 0; 852 | padding: 0; 853 | white-space: nowrap; 854 | } 855 | .ui-tabs .ui-tabs-nav .ui-tabs-anchor { 856 | float: left; 857 | padding: .5em 1em; 858 | text-decoration: none; 859 | } 860 | .ui-tabs .ui-tabs-nav li.ui-tabs-active { 861 | margin-bottom: -1px; 862 | padding-bottom: 1px; 863 | } 864 | .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, 865 | .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, 866 | .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { 867 | cursor: text; 868 | } 869 | .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { 870 | cursor: pointer; 871 | } 872 | .ui-tabs .ui-tabs-panel { 873 | display: block; 874 | border-width: 0; 875 | padding: 1em 1.4em; 876 | background: none; 877 | } 878 | .ui-tooltip { 879 | padding: 8px; 880 | position: absolute; 881 | z-index: 9999; 882 | max-width: 300px; 883 | } 884 | body .ui-tooltip { 885 | border-width: 2px; 886 | } 887 | -------------------------------------------------------------------------------- /src/jquery-ui/jquery-ui.structure.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2021-09-03 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;font-size:100%}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-button{padding:.4em 1em;display:inline-block;position:relative;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2em;box-sizing:border-box;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-button-icon-only{text-indent:0}.ui-button-icon-only .ui-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.ui-button.ui-icon-notext .ui-icon{padding:0;width:2.1em;height:2.1em;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-icon-notext .ui-icon{width:auto;height:auto;text-indent:0;white-space:normal;padding:.4em 1em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-controlgroup{vertical-align:middle;display:inline-block}.ui-controlgroup > .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:75%;width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-text{display:block;margin-right:20px;overflow:hidden;text-overflow:ellipsis}.ui-selectmenu-button.ui-button{text-align:left;white-space:nowrap;width:14em}.ui-selectmenu-icon.ui-icon{float:right;margin-top:0}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:.222em 0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:2em}.ui-spinner-button{width:1.6em;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top-style:none;border-bottom-style:none;border-right-style:none}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px} -------------------------------------------------------------------------------- /src/jquery-ui/jquery-ui.theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.12.1 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | * 11 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=base&cornerRadiusShadow=8px&offsetLeftShadow=0px&offsetTopShadow=0px&thicknessShadow=5px&opacityShadow=30&bgImgOpacityShadow=0&bgTextureShadow=flat&bgColorShadow=666666&opacityOverlay=30&bgImgOpacityOverlay=0&bgTextureOverlay=flat&bgColorOverlay=aaaaaa&iconColorError=cc0000&fcError=5f3f3f&borderColorError=f1a899&bgTextureError=flat&bgColorError=fddfdf&iconColorHighlight=777620&fcHighlight=777620&borderColorHighlight=dad55e&bgTextureHighlight=flat&bgColorHighlight=fffa90&iconColorActive=ffffff&fcActive=ffffff&borderColorActive=003eff&bgTextureActive=flat&bgColorActive=007fff&iconColorHover=555555&fcHover=2b2b2b&borderColorHover=cccccc&bgTextureHover=flat&bgColorHover=ededed&iconColorDefault=777777&fcDefault=454545&borderColorDefault=c5c5c5&bgTextureDefault=flat&bgColorDefault=f6f6f6&iconColorContent=444444&fcContent=333333&borderColorContent=dddddd&bgTextureContent=flat&bgColorContent=ffffff&iconColorHeader=444444&fcHeader=333333&borderColorHeader=dddddd&bgTextureHeader=flat&bgColorHeader=e9e9e9&cornerRadius=3px&fwDefault=normal&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif 12 | */ 13 | 14 | 15 | /* Component containers 16 | ----------------------------------*/ 17 | .ui-widget { 18 | font-family: Arial,Helvetica,sans-serif; 19 | font-size: 1em; 20 | } 21 | .ui-widget .ui-widget { 22 | font-size: 1em; 23 | } 24 | .ui-widget input, 25 | .ui-widget select, 26 | .ui-widget textarea, 27 | .ui-widget button { 28 | font-family: Arial,Helvetica,sans-serif; 29 | font-size: 1em; 30 | } 31 | .ui-widget.ui-widget-content { 32 | border: 1px solid #c5c5c5; 33 | } 34 | .ui-widget-content { 35 | border: 1px solid #dddddd; 36 | background: #ffffff; 37 | color: #333333; 38 | } 39 | .ui-widget-content a { 40 | color: #333333; 41 | } 42 | .ui-widget-header { 43 | border: 1px solid #dddddd; 44 | background: #e9e9e9; 45 | color: #333333; 46 | font-weight: bold; 47 | } 48 | .ui-widget-header a { 49 | color: #333333; 50 | } 51 | 52 | /* Interaction states 53 | ----------------------------------*/ 54 | .ui-state-default, 55 | .ui-widget-content .ui-state-default, 56 | .ui-widget-header .ui-state-default, 57 | .ui-button, 58 | 59 | /* We use html here because we need a greater specificity to make sure disabled 60 | works properly when clicked or hovered */ 61 | html .ui-button.ui-state-disabled:hover, 62 | html .ui-button.ui-state-disabled:active { 63 | border: 1px solid #c5c5c5; 64 | background: #f6f6f6; 65 | font-weight: normal; 66 | color: #454545; 67 | } 68 | .ui-state-default a, 69 | .ui-state-default a:link, 70 | .ui-state-default a:visited, 71 | a.ui-button, 72 | a:link.ui-button, 73 | a:visited.ui-button, 74 | .ui-button { 75 | color: #454545; 76 | text-decoration: none; 77 | } 78 | .ui-state-hover, 79 | .ui-widget-content .ui-state-hover, 80 | .ui-widget-header .ui-state-hover, 81 | .ui-state-focus, 82 | .ui-widget-content .ui-state-focus, 83 | .ui-widget-header .ui-state-focus, 84 | .ui-button:hover, 85 | .ui-button:focus { 86 | border: 1px solid #cccccc; 87 | background: #ededed; 88 | font-weight: normal; 89 | color: #2b2b2b; 90 | } 91 | .ui-state-hover a, 92 | .ui-state-hover a:hover, 93 | .ui-state-hover a:link, 94 | .ui-state-hover a:visited, 95 | .ui-state-focus a, 96 | .ui-state-focus a:hover, 97 | .ui-state-focus a:link, 98 | .ui-state-focus a:visited, 99 | a.ui-button:hover, 100 | a.ui-button:focus { 101 | color: #2b2b2b; 102 | text-decoration: none; 103 | } 104 | 105 | .ui-visual-focus { 106 | box-shadow: 0 0 3px 1px rgb(94, 158, 214); 107 | } 108 | .ui-state-active, 109 | .ui-widget-content .ui-state-active, 110 | .ui-widget-header .ui-state-active, 111 | a.ui-button:active, 112 | .ui-button:active, 113 | .ui-button.ui-state-active:hover { 114 | border: 1px solid #003eff; 115 | background: #007fff; 116 | font-weight: normal; 117 | color: #ffffff; 118 | } 119 | .ui-icon-background, 120 | .ui-state-active .ui-icon-background { 121 | border: #003eff; 122 | background-color: #ffffff; 123 | } 124 | .ui-state-active a, 125 | .ui-state-active a:link, 126 | .ui-state-active a:visited { 127 | color: #ffffff; 128 | text-decoration: none; 129 | } 130 | 131 | /* Interaction Cues 132 | ----------------------------------*/ 133 | .ui-state-highlight, 134 | .ui-widget-content .ui-state-highlight, 135 | .ui-widget-header .ui-state-highlight { 136 | border: 1px solid #dad55e; 137 | background: #fffa90; 138 | color: #777620; 139 | } 140 | .ui-state-checked { 141 | border: 1px solid #dad55e; 142 | background: #fffa90; 143 | } 144 | .ui-state-highlight a, 145 | .ui-widget-content .ui-state-highlight a, 146 | .ui-widget-header .ui-state-highlight a { 147 | color: #777620; 148 | } 149 | .ui-state-error, 150 | .ui-widget-content .ui-state-error, 151 | .ui-widget-header .ui-state-error { 152 | border: 1px solid #f1a899; 153 | background: #fddfdf; 154 | color: #5f3f3f; 155 | } 156 | .ui-state-error a, 157 | .ui-widget-content .ui-state-error a, 158 | .ui-widget-header .ui-state-error a { 159 | color: #5f3f3f; 160 | } 161 | .ui-state-error-text, 162 | .ui-widget-content .ui-state-error-text, 163 | .ui-widget-header .ui-state-error-text { 164 | color: #5f3f3f; 165 | } 166 | .ui-priority-primary, 167 | .ui-widget-content .ui-priority-primary, 168 | .ui-widget-header .ui-priority-primary { 169 | font-weight: bold; 170 | } 171 | .ui-priority-secondary, 172 | .ui-widget-content .ui-priority-secondary, 173 | .ui-widget-header .ui-priority-secondary { 174 | opacity: .7; 175 | filter:Alpha(Opacity=70); /* support: IE8 */ 176 | font-weight: normal; 177 | } 178 | .ui-state-disabled, 179 | .ui-widget-content .ui-state-disabled, 180 | .ui-widget-header .ui-state-disabled { 181 | opacity: .35; 182 | filter:Alpha(Opacity=35); /* support: IE8 */ 183 | background-image: none; 184 | } 185 | .ui-state-disabled .ui-icon { 186 | filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ 187 | } 188 | 189 | /* Icons 190 | ----------------------------------*/ 191 | 192 | /* states and images */ 193 | .ui-icon { 194 | width: 16px; 195 | height: 16px; 196 | } 197 | .ui-icon, 198 | .ui-widget-content .ui-icon { 199 | background-image: url("images/ui-icons_444444_256x240.png"); 200 | } 201 | .ui-widget-header .ui-icon { 202 | background-image: url("images/ui-icons_444444_256x240.png"); 203 | } 204 | .ui-state-hover .ui-icon, 205 | .ui-state-focus .ui-icon, 206 | .ui-button:hover .ui-icon, 207 | .ui-button:focus .ui-icon { 208 | background-image: url("images/ui-icons_555555_256x240.png"); 209 | } 210 | .ui-state-active .ui-icon, 211 | .ui-button:active .ui-icon { 212 | background-image: url("images/ui-icons_ffffff_256x240.png"); 213 | } 214 | .ui-state-highlight .ui-icon, 215 | .ui-button .ui-state-highlight.ui-icon { 216 | background-image: url("images/ui-icons_777620_256x240.png"); 217 | } 218 | .ui-state-error .ui-icon, 219 | .ui-state-error-text .ui-icon { 220 | background-image: url("images/ui-icons_cc0000_256x240.png"); 221 | } 222 | .ui-button .ui-icon { 223 | background-image: url("images/ui-icons_777777_256x240.png"); 224 | } 225 | 226 | /* positioning */ 227 | .ui-icon-blank { background-position: 16px 16px; } 228 | .ui-icon-caret-1-n { background-position: 0 0; } 229 | .ui-icon-caret-1-ne { background-position: -16px 0; } 230 | .ui-icon-caret-1-e { background-position: -32px 0; } 231 | .ui-icon-caret-1-se { background-position: -48px 0; } 232 | .ui-icon-caret-1-s { background-position: -65px 0; } 233 | .ui-icon-caret-1-sw { background-position: -80px 0; } 234 | .ui-icon-caret-1-w { background-position: -96px 0; } 235 | .ui-icon-caret-1-nw { background-position: -112px 0; } 236 | .ui-icon-caret-2-n-s { background-position: -128px 0; } 237 | .ui-icon-caret-2-e-w { background-position: -144px 0; } 238 | .ui-icon-triangle-1-n { background-position: 0 -16px; } 239 | .ui-icon-triangle-1-ne { background-position: -16px -16px; } 240 | .ui-icon-triangle-1-e { background-position: -32px -16px; } 241 | .ui-icon-triangle-1-se { background-position: -48px -16px; } 242 | .ui-icon-triangle-1-s { background-position: -65px -16px; } 243 | .ui-icon-triangle-1-sw { background-position: -80px -16px; } 244 | .ui-icon-triangle-1-w { background-position: -96px -16px; } 245 | .ui-icon-triangle-1-nw { background-position: -112px -16px; } 246 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; } 247 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; } 248 | .ui-icon-arrow-1-n { background-position: 0 -32px; } 249 | .ui-icon-arrow-1-ne { background-position: -16px -32px; } 250 | .ui-icon-arrow-1-e { background-position: -32px -32px; } 251 | .ui-icon-arrow-1-se { background-position: -48px -32px; } 252 | .ui-icon-arrow-1-s { background-position: -65px -32px; } 253 | .ui-icon-arrow-1-sw { background-position: -80px -32px; } 254 | .ui-icon-arrow-1-w { background-position: -96px -32px; } 255 | .ui-icon-arrow-1-nw { background-position: -112px -32px; } 256 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; } 257 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } 258 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; } 259 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } 260 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; } 261 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; } 262 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; } 263 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; } 264 | .ui-icon-arrowthick-1-n { background-position: 1px -48px; } 265 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } 266 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; } 267 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; } 268 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; } 269 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } 270 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; } 271 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } 272 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } 273 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } 274 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } 275 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } 276 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } 277 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } 278 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } 279 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } 280 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } 281 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } 282 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } 283 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } 284 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } 285 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } 286 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } 287 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } 288 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } 289 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } 290 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } 291 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } 292 | .ui-icon-arrow-4 { background-position: 0 -80px; } 293 | .ui-icon-arrow-4-diag { background-position: -16px -80px; } 294 | .ui-icon-extlink { background-position: -32px -80px; } 295 | .ui-icon-newwin { background-position: -48px -80px; } 296 | .ui-icon-refresh { background-position: -64px -80px; } 297 | .ui-icon-shuffle { background-position: -80px -80px; } 298 | .ui-icon-transfer-e-w { background-position: -96px -80px; } 299 | .ui-icon-transferthick-e-w { background-position: -112px -80px; } 300 | .ui-icon-folder-collapsed { background-position: 0 -96px; } 301 | .ui-icon-folder-open { background-position: -16px -96px; } 302 | .ui-icon-document { background-position: -32px -96px; } 303 | .ui-icon-document-b { background-position: -48px -96px; } 304 | .ui-icon-note { background-position: -64px -96px; } 305 | .ui-icon-mail-closed { background-position: -80px -96px; } 306 | .ui-icon-mail-open { background-position: -96px -96px; } 307 | .ui-icon-suitcase { background-position: -112px -96px; } 308 | .ui-icon-comment { background-position: -128px -96px; } 309 | .ui-icon-person { background-position: -144px -96px; } 310 | .ui-icon-print { background-position: -160px -96px; } 311 | .ui-icon-trash { background-position: -176px -96px; } 312 | .ui-icon-locked { background-position: -192px -96px; } 313 | .ui-icon-unlocked { background-position: -208px -96px; } 314 | .ui-icon-bookmark { background-position: -224px -96px; } 315 | .ui-icon-tag { background-position: -240px -96px; } 316 | .ui-icon-home { background-position: 0 -112px; } 317 | .ui-icon-flag { background-position: -16px -112px; } 318 | .ui-icon-calendar { background-position: -32px -112px; } 319 | .ui-icon-cart { background-position: -48px -112px; } 320 | .ui-icon-pencil { background-position: -64px -112px; } 321 | .ui-icon-clock { background-position: -80px -112px; } 322 | .ui-icon-disk { background-position: -96px -112px; } 323 | .ui-icon-calculator { background-position: -112px -112px; } 324 | .ui-icon-zoomin { background-position: -128px -112px; } 325 | .ui-icon-zoomout { background-position: -144px -112px; } 326 | .ui-icon-search { background-position: -160px -112px; } 327 | .ui-icon-wrench { background-position: -176px -112px; } 328 | .ui-icon-gear { background-position: -192px -112px; } 329 | .ui-icon-heart { background-position: -208px -112px; } 330 | .ui-icon-star { background-position: -224px -112px; } 331 | .ui-icon-link { background-position: -240px -112px; } 332 | .ui-icon-cancel { background-position: 0 -128px; } 333 | .ui-icon-plus { background-position: -16px -128px; } 334 | .ui-icon-plusthick { background-position: -32px -128px; } 335 | .ui-icon-minus { background-position: -48px -128px; } 336 | .ui-icon-minusthick { background-position: -64px -128px; } 337 | .ui-icon-close { background-position: -80px -128px; } 338 | .ui-icon-closethick { background-position: -96px -128px; } 339 | .ui-icon-key { background-position: -112px -128px; } 340 | .ui-icon-lightbulb { background-position: -128px -128px; } 341 | .ui-icon-scissors { background-position: -144px -128px; } 342 | .ui-icon-clipboard { background-position: -160px -128px; } 343 | .ui-icon-copy { background-position: -176px -128px; } 344 | .ui-icon-contact { background-position: -192px -128px; } 345 | .ui-icon-image { background-position: -208px -128px; } 346 | .ui-icon-video { background-position: -224px -128px; } 347 | .ui-icon-script { background-position: -240px -128px; } 348 | .ui-icon-alert { background-position: 0 -144px; } 349 | .ui-icon-info { background-position: -16px -144px; } 350 | .ui-icon-notice { background-position: -32px -144px; } 351 | .ui-icon-help { background-position: -48px -144px; } 352 | .ui-icon-check { background-position: -64px -144px; } 353 | .ui-icon-bullet { background-position: -80px -144px; } 354 | .ui-icon-radio-on { background-position: -96px -144px; } 355 | .ui-icon-radio-off { background-position: -112px -144px; } 356 | .ui-icon-pin-w { background-position: -128px -144px; } 357 | .ui-icon-pin-s { background-position: -144px -144px; } 358 | .ui-icon-play { background-position: 0 -160px; } 359 | .ui-icon-pause { background-position: -16px -160px; } 360 | .ui-icon-seek-next { background-position: -32px -160px; } 361 | .ui-icon-seek-prev { background-position: -48px -160px; } 362 | .ui-icon-seek-end { background-position: -64px -160px; } 363 | .ui-icon-seek-start { background-position: -80px -160px; } 364 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ 365 | .ui-icon-seek-first { background-position: -80px -160px; } 366 | .ui-icon-stop { background-position: -96px -160px; } 367 | .ui-icon-eject { background-position: -112px -160px; } 368 | .ui-icon-volume-off { background-position: -128px -160px; } 369 | .ui-icon-volume-on { background-position: -144px -160px; } 370 | .ui-icon-power { background-position: 0 -176px; } 371 | .ui-icon-signal-diag { background-position: -16px -176px; } 372 | .ui-icon-signal { background-position: -32px -176px; } 373 | .ui-icon-battery-0 { background-position: -48px -176px; } 374 | .ui-icon-battery-1 { background-position: -64px -176px; } 375 | .ui-icon-battery-2 { background-position: -80px -176px; } 376 | .ui-icon-battery-3 { background-position: -96px -176px; } 377 | .ui-icon-circle-plus { background-position: 0 -192px; } 378 | .ui-icon-circle-minus { background-position: -16px -192px; } 379 | .ui-icon-circle-close { background-position: -32px -192px; } 380 | .ui-icon-circle-triangle-e { background-position: -48px -192px; } 381 | .ui-icon-circle-triangle-s { background-position: -64px -192px; } 382 | .ui-icon-circle-triangle-w { background-position: -80px -192px; } 383 | .ui-icon-circle-triangle-n { background-position: -96px -192px; } 384 | .ui-icon-circle-arrow-e { background-position: -112px -192px; } 385 | .ui-icon-circle-arrow-s { background-position: -128px -192px; } 386 | .ui-icon-circle-arrow-w { background-position: -144px -192px; } 387 | .ui-icon-circle-arrow-n { background-position: -160px -192px; } 388 | .ui-icon-circle-zoomin { background-position: -176px -192px; } 389 | .ui-icon-circle-zoomout { background-position: -192px -192px; } 390 | .ui-icon-circle-check { background-position: -208px -192px; } 391 | .ui-icon-circlesmall-plus { background-position: 0 -208px; } 392 | .ui-icon-circlesmall-minus { background-position: -16px -208px; } 393 | .ui-icon-circlesmall-close { background-position: -32px -208px; } 394 | .ui-icon-squaresmall-plus { background-position: -48px -208px; } 395 | .ui-icon-squaresmall-minus { background-position: -64px -208px; } 396 | .ui-icon-squaresmall-close { background-position: -80px -208px; } 397 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } 398 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } 399 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; } 400 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } 401 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } 402 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; } 403 | 404 | 405 | /* Misc visuals 406 | ----------------------------------*/ 407 | 408 | /* Corner radius */ 409 | .ui-corner-all, 410 | .ui-corner-top, 411 | .ui-corner-left, 412 | .ui-corner-tl { 413 | border-top-left-radius: 3px; 414 | } 415 | .ui-corner-all, 416 | .ui-corner-top, 417 | .ui-corner-right, 418 | .ui-corner-tr { 419 | border-top-right-radius: 3px; 420 | } 421 | .ui-corner-all, 422 | .ui-corner-bottom, 423 | .ui-corner-left, 424 | .ui-corner-bl { 425 | border-bottom-left-radius: 3px; 426 | } 427 | .ui-corner-all, 428 | .ui-corner-bottom, 429 | .ui-corner-right, 430 | .ui-corner-br { 431 | border-bottom-right-radius: 3px; 432 | } 433 | 434 | /* Overlays */ 435 | .ui-widget-overlay { 436 | background: #aaaaaa; 437 | opacity: .3; 438 | filter: Alpha(Opacity=30); /* support: IE8 */ 439 | } 440 | .ui-widget-shadow { 441 | -webkit-box-shadow: 0px 0px 5px #666666; 442 | box-shadow: 0px 0px 5px #666666; 443 | } 444 | -------------------------------------------------------------------------------- /src/jquery-ui/jquery-ui.theme.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2021-09-03 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} -------------------------------------------------------------------------------- /src/jquery-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-ui", 3 | "title": "jQuery UI", 4 | "description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.", 5 | "version": "1.12.1", 6 | "homepage": "http://jqueryui.com", 7 | "author": { 8 | "name": "jQuery Foundation and other contributors", 9 | "url": "https://github.com/jquery/jquery-ui/blob/1.12.1/AUTHORS.txt" 10 | }, 11 | "main": "ui/widget.js", 12 | "maintainers": [ 13 | { 14 | "name": "Scott González", 15 | "email": "scott.gonzalez@gmail.com", 16 | "url": "http://scottgonzalez.com" 17 | }, 18 | { 19 | "name": "Jörn Zaefferer", 20 | "email": "joern.zaefferer@gmail.com", 21 | "url": "http://bassistance.de" 22 | }, 23 | { 24 | "name": "Mike Sherov", 25 | "email": "mike.sherov@gmail.com", 26 | "url": "http://mike.sherov.com" 27 | }, 28 | { 29 | "name": "TJ VanToll", 30 | "email": "tj.vantoll@gmail.com", 31 | "url": "http://tjvantoll.com" 32 | }, 33 | { 34 | "name": "Felix Nagel", 35 | "email": "info@felixnagel.com", 36 | "url": "http://www.felixnagel.com" 37 | }, 38 | { 39 | "name": "Alex Schmitz", 40 | "email": "arschmitz@gmail.com", 41 | "url": "https://github.com/arschmitz" 42 | } 43 | ], 44 | "repository": { 45 | "type": "git", 46 | "url": "git://github.com/jquery/jquery-ui.git" 47 | }, 48 | "bugs": "https://bugs.jqueryui.com/", 49 | "license": "MIT", 50 | "scripts": { 51 | "test": "grunt" 52 | }, 53 | "dependencies": {}, 54 | "devDependencies": { 55 | "commitplease": "2.3.0", 56 | "grunt": "0.4.5", 57 | "grunt-bowercopy": "1.2.4", 58 | "grunt-cli": "0.1.13", 59 | "grunt-compare-size": "0.4.0", 60 | "grunt-contrib-concat": "0.5.1", 61 | "grunt-contrib-csslint": "0.5.0", 62 | "grunt-contrib-jshint": "0.12.0", 63 | "grunt-contrib-qunit": "1.0.1", 64 | "grunt-contrib-requirejs": "0.4.4", 65 | "grunt-contrib-uglify": "0.11.1", 66 | "grunt-git-authors": "3.1.0", 67 | "grunt-html": "6.0.0", 68 | "grunt-jscs": "2.1.0", 69 | "load-grunt-tasks": "3.4.0", 70 | "rimraf": "2.5.1", 71 | "testswarm": "1.1.0" 72 | }, 73 | "keywords": [] 74 | } 75 | -------------------------------------------------------------------------------- /src/js/i18n.js: -------------------------------------------------------------------------------- 1 | export { internacionalizeContent }; 2 | 3 | /** 4 | * Traverses the tree and replaces text nodes with their internatioalized verision. 5 | * The text node needs to follow the pattern __MSG_{message_name}_ the message_name 6 | * represents the message name in the localization file. 7 | * 8 | * @param {Node} node the root of the tree which needs to be traversed. 9 | */ 10 | function internacionalizeContent(node) { 11 | if (node.innerText) { 12 | const matches = node.innerText.match("^__MSG_([\\w_\\d]+)__$"); 13 | if (matches && matches.length > 1) { 14 | node.innerText = chrome.i18n.getMessage(matches[1]); 15 | return; 16 | } 17 | } 18 | if (node.childNodes && node.childNodes.length > 0) { 19 | let firstNode = node.childNodes[0]; 20 | while (firstNode) { 21 | internacionalizeContent(firstNode); 22 | firstNode = firstNode.nextElementSibling; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/js/translators.js: -------------------------------------------------------------------------------- 1 | 2 | function init_i18n() { 3 | $('#title').text(chrome.i18n.getMessage('translatorsTitle')) 4 | } 5 | 6 | function fillTranslators() { 7 | var element = $('#translators'); 8 | for(var index in translatorsData) { 9 | var element = translatorsData[index]; 10 | $('#translators').append(cardContentTemplate.format(index, element)); 11 | } 12 | } 13 | 14 | String.prototype.format = function() { 15 | var formatted = this; 16 | for (var i = 0; i < arguments.length; i++) { 17 | var regexp = new RegExp('\\{'+i+'\\}', 'gi'); 18 | formatted = formatted.replace(regexp, arguments[i]); 19 | } 20 | return formatted; 21 | }; 22 | 23 | var cardContentTemplate = 24 | '
' + 25 | '
' + 26 | '
' + 27 | '

{0}

' + 28 | '
' + 29 | '
' + 30 | '

{1}

' + 31 | '
' + 32 | '
'+ 33 | '
' + 34 | '
  • '; 35 | 36 | var translatorsData = { 37 | 'Deutsch': 'Aleksandra Dubaniowska', 38 | 'English': 'Bartosz Przybylski', 39 | 'Polski': 'Bartosz Przybylski' 40 | }; 41 | 42 | $(document).ready(function() { 43 | init_i18n(); 44 | fillTranslators(); 45 | }); 46 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "background": { 3 | "persistent": false, 4 | "scripts": [ "constants.js", "analytics.js", "storage.js", "background.js" ] 5 | }, 6 | "browser_action": { 7 | "default_icon": { 8 | "38": "img/icon-38.png", 9 | "19": "img/icon-19.png" 10 | }, 11 | "default_popup": "popup.html" 12 | }, 13 | "content_scripts": [ { 14 | "js": [ "constants.js", "contentscript.js" ], 15 | "matches": [ "http://*/*", "https://*/*" ], 16 | "all_frames": true 17 | } ], 18 | "default_locale": "en", 19 | "description": "__MSG_extensionDescription__", 20 | "icons": { 21 | "128": "img/icon-128.png", 22 | "16": "img/icon-16.png" 23 | }, 24 | "manifest_version": 2, 25 | "name": "__MSG_extensionName__", 26 | "options_page": "options.html", 27 | "permissions": [ "clipboardWrite", "clipboardRead", "storage", "contextMenus", "tabs", "activeTab", "http://*/", "https://*/" ], 28 | "version": "2.5.3", 29 | "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'" 30 | } 31 | -------------------------------------------------------------------------------- /src/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 |
    41 | 42 |
    43 |
    44 |
    45 | 46 |
    47 |
    48 |
    49 |

    50 |
    51 |
    52 | 56 |
    57 |
    58 | 59 | 60 | 61 |
    62 |
    63 |
    64 | 65 |
  • 66 | 67 |
    68 |
    69 |
    70 |

    71 |
    72 |
    73 | 74 |
    75 |
    76 | 77 | 78 | 79 |
    80 |
    81 |
    82 | 83 |
  • 84 | 85 |
    86 |
    87 |
    88 |

    89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |
    96 | 97 | 98 | 99 |
    100 |
    101 |
    102 | 103 |
  • 104 | 105 |
    106 |
    107 |
    108 |

    109 |
    110 |
    111 | 112 | 113 |   114 | 115 |
    116 |
    117 | 118 | 119 | 120 |
    121 |
    122 |
    123 |
    124 | 125 |
    126 |
    127 |
    128 |
    129 |
    130 |

    131 |
    132 |
    133 | 134 | keyboard_arrow_right 135 | 136 |
    137 |
    138 |
    139 |
    140 | 141 |
    142 | 143 | 151 | 152 | 160 | 161 | 169 | 170 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /src/options.js: -------------------------------------------------------------------------------- 1 | var SYNC_QUOTA = chrome.storage.sync.QUOTA_BYTES_PER_ITEM; 2 | 3 | function saveOptions() { 4 | var select = document.getElementById("storage_type"); 5 | var storage_type = select.children[select.selectedIndex].value; 6 | localStorage["storage_type"] = storage_type; 7 | chrome.runtime.sendMessage({event:'rebuildMenus'}); 8 | 9 | Materialize.toast(chrome.i18n.getMessage('optionsSavedToastText'), 2000); 10 | } 11 | 12 | function restoreOptions() { 13 | var storage_type = localStorage["storage_type"]; 14 | if (!storage_type) 15 | return; 16 | 17 | var select = document.getElementById("storage_type"); 18 | for (var i = 0; i < select.children.length; i++) { 19 | var child = select.children[i]; 20 | if (child.value == storage_type) { 21 | child.selected = "true"; 22 | break; 23 | } 24 | } 25 | } 26 | 27 | function swapStorage() { 28 | chrome.storage.local.get('clipboard', function(localItems) { 29 | localItems.clipboard = localItems.clipboard || []; 30 | 31 | chrome.storage.sync.get('clipboard', function(syncItems) { 32 | syncItems.clipboard = syncItems.clipboard || []; 33 | 34 | chrome.storage.sync.set({'clipboard': localItems.clipboard}, function() { 35 | if (chrome.runtime.lastError) { 36 | Materialize.toast(chrome.i18n.getMessage('storageSwappingFailedMessage') + chrome.runtime.lastError.message, 4000); 37 | analytics.trackEvent('Options', 'Swap Failed'); 38 | return; 39 | } 40 | chrome.storage.local.set({'clipboard': syncItems.clipboard}); 41 | chrome.runtime.sendMessage({event:'rebuildMenus'}); 42 | 43 | Materialize.toast(chrome.i18n.getMessage('optionsSuccess'), 4000); 44 | calculateAndSetFillBar(); 45 | 46 | analytics.trackEvent('Options', 'Swap Success'); 47 | }); 48 | }); 49 | 50 | }); 51 | } 52 | 53 | function getStorageColorClass(percent) { 54 | if (typeof(percent) != typeof(0.1)) 55 | return "black"; 56 | if (percent < 0 || percent > 1) 57 | return "blue"; 58 | if (percent < 0.8) 59 | return "light-green"; 60 | if (percent < 0.95) 61 | return "orange"; 62 | return "red"; 63 | } 64 | 65 | function calculateAndSetFillBar() { 66 | chrome.storage.sync.get({'clipboard':[]}, function(syncItems) { 67 | if (!(syncItems.clipboard instanceof Array)) 68 | return; 69 | 70 | $("#option_storage_usage").empty(); 71 | $("#option_storage_usage").append(chrome.i18n.getMessage("optionStorageUsage")); 72 | 73 | var size = computeObjectSize(syncItems.clipboard); 74 | var percentage = size/SYNC_QUOTA; 75 | $('#progress_progress').width(Math.floor(percentage*100)+'%'); 76 | $('#progress_progress').removeClass('black blue light-green orange red').addClass(getStorageColorClass(percentage)); 77 | $('#option_storage_usage').append(Math.floor(percentage*100)+"%"); 78 | }); 79 | } 80 | 81 | function computeObjectSize(object) { 82 | return JSON.stringify(object).length; 83 | } 84 | 85 | function readBackup() { 86 | $("#backup_files_input").click(); 87 | } 88 | 89 | function makeBackup() { 90 | chrome.storage.local.get({'clipboard':[]}, function(items) { 91 | if (chrome.runtime.lastError) { 92 | Materialize.toast("Creating backup failed", 4000); 93 | analytics.trackEvent('Backup', 'Create failed'); 94 | return; 95 | } 96 | var stringifiedContent = JSON.stringify(items.clipboard); 97 | var base64Content = btoa(unescape(encodeURIComponent(stringifiedContent))); 98 | var backupObject = { content: base64Content, hash: calculateChecksum(base64Content), version: 1 }; 99 | analytics.trackEvent('Backup', 'Create success'); 100 | downloadObjectAsFile(backupObject); 101 | }); 102 | } 103 | 104 | function downloadObjectAsFile(s) { 105 | var a = window.document.createElement('a'); 106 | a.href = window.URL.createObjectURL(new Blob([JSON.stringify(s)], {type:'application/json'})); 107 | a.download = 'permanentClipboard.backup'; 108 | document.body.appendChild(a); 109 | a.click(); 110 | document.body.removeChild(a); 111 | } 112 | 113 | function calculateChecksum(s) { 114 | var hashCode = stringHashCode(s); 115 | return hashCode.toString(16); 116 | } 117 | 118 | function stringHashCode(s) { 119 | var h = 0, l = s.length, i = 0; 120 | if ( l > 0 ) 121 | while (i < l) 122 | h = (h << 5) - h + s.charCodeAt(i++) | 0; 123 | return h; 124 | }; 125 | 126 | function handleInputSelection(e) { 127 | analytics.trackEvent('Backup', 'Selection restore'); 128 | restoreFromFile(e.originalEvent.target.files[0]); 129 | } 130 | 131 | function restoreFromFile(file) { 132 | var reader = new FileReader(); 133 | reader.onload = function(f) { 134 | try { 135 | var object = JSON.parse(this.result); 136 | var clipboardContent = object.content; 137 | var clipboardHashcode = object.hash; 138 | var backupMechanismVersion = object.version; 139 | if (backupMechanismVersion == undefined || calculateChecksum(clipboardContent) !== clipboardHashcode) { 140 | Materialize.toast(chrome.i18n.getMessage('optionsBackupCorrupted'), 4000); 141 | return; 142 | } 143 | if (backupMechanismVersion > 1) { 144 | Materialize.toast(chrome.i18n.getMessage('optionBackupNewerFile'), 4000); 145 | return; 146 | } 147 | var restoreObject = JSON.parse(decodeURIComponent(escape(atob(clipboardContent)))); 148 | chrome.storage.local.set({'clipboard':restoreObject}, function() { 149 | if (chrome.runtime.lastError) { 150 | Materialize.toast("Backup restore failed", 4000); 151 | return; 152 | } else { 153 | Materialize.toast(chrome.i18n.getMessage('optionsBackupRestored'), 4000); 154 | chrome.runtime.sendMessage({event:'rebuildMenus'}); 155 | return; 156 | } 157 | }) 158 | } catch (err) { 159 | Materialize.toast(chrome.i18n.getMessage('optionsBackupInvalidFile'), 4000); 160 | } 161 | }; 162 | reader.readAsText(file); 163 | } 164 | 165 | function handleDragoverOnDocument(e) { 166 | var ee = e.originalEvent; 167 | ee.stopPropagation(); 168 | ee.preventDefault(); 169 | ee.dataTransfer.dropEffect = 'copy'; 170 | $('#dropzone').removeClass('hidden'); 171 | } 172 | 173 | function handleDragleave(e) { 174 | var ee = e.originalEvent; 175 | ee.stopPropagation(); 176 | ee.preventDefault(); 177 | $('#dropzone').addClass('hidden'); 178 | } 179 | 180 | function handleDropOnDocument(e) { 181 | var ee = e.originalEvent; 182 | ee.stopPropagation(); 183 | ee.preventDefault(); 184 | $('#dropzone').addClass('hidden'); 185 | var file = ee.dataTransfer.files[0]; 186 | analytics.trackEvent('Backup', 'Drop restore'); 187 | restoreFromFile(file); 188 | } 189 | 190 | function init_i18n() { 191 | document.title = chrome.i18n.getMessage("optionsText"); 192 | var msg = chrome.i18n.getMessage; 193 | $("#title").append(chrome.i18n.getMessage("optionsText")); 194 | $("#option_sync_type_text").append(chrome.i18n.getMessage("optionStorageTypeText")); 195 | $("#option_sync_text").html(chrome.i18n.getMessage("optionSyncText")); 196 | $("#option_swap_storages_text").append(chrome.i18n.getMessage("optionSwapStorageText")); 197 | $("#option_swap_storage_btn_text").text(chrome.i18n.getMessage("optionSwapText")); 198 | $("#option_local_text").html(chrome.i18n.getMessage("optionLocalText")); 199 | $("#storage-card-title").text(chrome.i18n.getMessage("optionStorageCardTitle")); 200 | $('#option-name__translation-credits').text(chrome.i18n.getMessage('translatorsTitle')); 201 | 202 | $('#drop-overlay-content').text(msg('dropOverlayPromptText')); 203 | 204 | $('#option_storage_backup').text(chrome.i18n.getMessage('optionBackupTitle')); 205 | $('#option_make_backup').text(msg('optionBackupCreateButton')); 206 | $('#option_read_backup').text(msg('optionBackupRestoreButton')); 207 | 208 | $("#option_sync_tip").append(chrome.i18n.getMessage("optionSyncTip")); 209 | $("#option_used_storage_tip").append(chrome.i18n.getMessage("optionsStorageSizeHelp")); 210 | $("#option_swap_tip").append(chrome.i18n.getMessage("optionsSwapStoragesHelp")); 211 | $('#option_backup_tip').append(msg("optionBackupTip")); 212 | 213 | $("#save").text(chrome.i18n.getMessage("optionsSave")); 214 | $('#donate_button').append(chrome.i18n.getMessage('donateWithPaypal')); 215 | } 216 | 217 | function submitDonateForm() { 218 | $('#donate_form').submit(); 219 | } 220 | 221 | $(document).ready(function() { 222 | init_i18n(); 223 | restoreOptions(); 224 | $('select').material_select(); 225 | $('.modal').modal(); 226 | calculateAndSetFillBar(); 227 | $("#save").click(saveOptions); 228 | $('#option_swap_storage_btn_text').click(swapStorage); 229 | $('#donate_button').click(submitDonateForm); 230 | $('#option_make_backup').click(makeBackup); 231 | $('#option_read_backup').click(readBackup); 232 | $('#backup_files_input').on('change', handleInputSelection); 233 | $(window).bind({ 234 | dragenter: handleDragoverOnDocument 235 | }); 236 | $('#dropzone').bind({ 237 | dragenter: handleDragoverOnDocument, 238 | dragover: handleDragoverOnDocument, 239 | drop: handleDropOnDocument, 240 | dragleave: handleDragleave 241 | }); 242 | analytics.trackEvent('Options', 'Opened'); 243 | }); 244 | -------------------------------------------------------------------------------- /src/permissions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
    19 |
    __MSG_permissions_title__
    20 |
    21 | 22 |
    23 |
    24 |
    25 |
    26 |

    __MSG_permissions_clipboardRead__

    27 |
    28 |
    29 |

    __MSG_permissions_clipboardRead_rationale__

    30 |
    31 |
    32 |
    33 | __MSG_permissions_grantPermission__ 34 |
    35 |
    36 | check 37 |
    38 |
    39 |
    40 | 41 |
  • 42 | 43 |
    44 |
    45 |
    46 |
    47 |

    __MSG_permissions_clipboardWrite__

    48 |
    49 |
    50 |

    __MSG_permissions_clipboardWrite_rationale__

    51 |
    52 |
    53 |
    54 | __MSG_permissions_grantPermission__ 55 |
    56 |
    57 | check 58 |
    59 |
    60 |
    61 |
    62 |
    __MSG_permissions_thankYou__
    63 |
    64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/permissions.js: -------------------------------------------------------------------------------- 1 | import { internacionalizeContent } from './js/i18n.js'; 2 | 3 | window.onload = () => { 4 | internacionalizeContent(document.body); 5 | let readGranted = false; 6 | let writeGranted = false; 7 | navigator.permissions.query({'name': 'clipboard-read'}).then( 8 | result => { 9 | let handler = () => navigator.clipboard.readText(); 10 | processPermission(result, "#permission-read", handler); 11 | result.onchange = function() { 12 | processPermission(this, "#permission-read", handler); 13 | readGranted = result.state == 'granted'; 14 | updateTitle(readGranted, writeGranted); 15 | }; 16 | readGranted = result.state == 'granted'; 17 | updateTitle(readGranted, writeGranted); 18 | } 19 | ); 20 | navigator.permissions.query({'name': 'clipboard-write'}).then( 21 | result => { 22 | let handler = () => { navigator.clipboard.writeText(""); }; 23 | processPermission(result, "#permission-write", handler); 24 | result.onchange = function() { 25 | processPermission(this, "#permission-write", handler); 26 | writeGranted = result.state == 'granted'; 27 | updateTitle(readGranted, writeGranted); 28 | } 29 | writeGranted = result.state == 'granted'; 30 | updateTitle(readGranted, writeGranted); 31 | } 32 | ); 33 | } 34 | 35 | function updateTitle(readGranted, writeGranted) { 36 | if (readGranted && writeGranted) { 37 | $("#permissions-thankYou").removeClass("hide"); 38 | } else { 39 | $("#permissions-thankYou").addClass("hide"); 40 | } 41 | } 42 | 43 | function processPermission(permission, parentElement, actionHandler) { 44 | $(parentElement + " #action a").click(actionHandler); 45 | if (permission.state === 'granted') { 46 | $(parentElement + " #decorator").removeClass('hide'); 47 | $(parentElement + " #action").addClass('hide'); 48 | $(parentElement).addClass("green lighten-5"); 49 | $(parentElement).removeClass("red"); 50 | } else { 51 | $(parentElement + " #decorator").addClass('hide'); 52 | $(parentElement + " #action").removeClass('hide'); 53 | $(parentElement).addClass("red lighten-5"); 54 | $(parentElement).removeClass("green"); 55 | } 56 | } -------------------------------------------------------------------------------- /src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pernament Clipboard Popup 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
    21 |
    22 |
    23 | 24 |
    25 |
    26 | 27 | 28 |
    29 | 30 |
    31 | 32 |
    33 | add 34 |
    35 | 36 |
    37 |
    38 |
    39 | 68 |
    69 | 70 |
    71 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/popup.js: -------------------------------------------------------------------------------- 1 | function arrayRemove(a, idx) { 2 | var rest = a.slice(idx + 1 || a.length); 3 | a.length = idx < 0 ? a.length + idx : idx; 4 | return a.push.apply(a, rest); 5 | } 6 | 7 | var defaultAnimationDuration = 100; 8 | var storage = new Storage(); 9 | var traverseArray = []; 10 | 11 | function rebuildTable() { 12 | var tail = traverseArray[traverseArray.length-1]; 13 | $('#current_div').empty().append(createTable(tail)); 14 | $('#hint').empty().append(chrome.i18n.getMessage(tail.length == 0 ? "popupHintNoElements" : "popupHint")); 15 | $('.tooltipped').tooltip({ 16 | options: { 17 | enterDelay: defaultAnimationDuration 18 | } 19 | }); 20 | } 21 | 22 | function rebuildMenusAndReload() { 23 | chrome.runtime.sendMessage({event:'rebuildMenus'}, rebuildTable); 24 | } 25 | 26 | function addToPermClipboardFromRecent() { 27 | addToPermClipboard( 28 | document.getElementById('recent_name').value, 29 | document.getElementById('recent_text').innerText) 30 | .then(() => { 31 | analytics.trackEvent('Popup', 'Recent saved success'); 32 | $('#add_elements_collapsible').collapsible({onClose: function() { 33 | $('#recent_add_element').fadeOut('fast').delay().addClass('hide'); 34 | $('#add_elements_collapsible').collapsible({onClose: null}); 35 | }}) 36 | $('#add_elements_collapsible').collapsible('close', 1); 37 | }, (error) => 38 | analytics.trackEvent('Popup', 'Recent save fail', error.message) 39 | ); 40 | return false; 41 | } 42 | 43 | function addToPermClipboardFromManually() { 44 | // text can't be empty, name can 45 | // it will be replaced by text eventually 46 | var text = document.getElementById('new_content').value; 47 | if (text !== "") { 48 | addToPermClipboard(document.getElementById('new_name').value, text) 49 | .then( 50 | () => { 51 | $('#new_name').val(''); 52 | $('#new_content').val(''); 53 | $('#new_content').trigger('autoresize'); 54 | $('#add_elements_collapsible').collapsible('close', 0); 55 | localStorage.removeItem('unsaved_name'); 56 | localStorage.removeItem('unsaved_content'); 57 | 58 | analytics.trackEvent('Popup', 'Manually add success'); 59 | }, (error) => 60 | analytics.trackEvent('Popup', 'Manually add fail', error.message) 61 | ); 62 | } 63 | return false; 64 | } 65 | 66 | function addToPermClipboard(name, text) { 67 | traverseArray[traverseArray.length-1].push({ desc: name, value: text }); 68 | return storage.setData({'clipboard':traverseArray[0], 'recent':0}) 69 | .then(() => { 70 | rebuildMenusAndReload(); 71 | }, (error) => { 72 | traverseArray[traverseArray.length-1].pop(); 73 | var errorMessage = chrome.i18n.getMessage("unknownError"); 74 | if (error.message.match(/^QUOTA_BYTES_PER_ITEM/)) { 75 | errorMessage = chrome.i18n.getMessage("noMoreSpace"); 76 | } 77 | Materialize.toast(chrome.i18n.getMessage("errorFailedToSaveEntry") + errorMessage, 3000); 78 | }); 79 | } 80 | 81 | function discardNewEntry() { 82 | localStorage.removeItem('unsaved_name'); 83 | localStorage.removeItem('unsaved_content'); 84 | $("#new_name").val(""); 85 | $("#new_content").val(""); 86 | $("#add_elements_collapsible").collapsible('close', 0); 87 | } 88 | 89 | function discardRecentEntry() { 90 | $("#recent_name").val(""); 91 | $("#recent_text").text(""); 92 | $("#add_elements_collapsible").collapsible('close', 1); 93 | $("#recent_add_element").fadeOut(); 94 | storage.setData({'recent':0}); 95 | } 96 | 97 | function removeElement(s) { 98 | var elem = $(this.parentNode.parentNode); 99 | var e = parseInt(elem.attr('data-entryId')); 100 | elem.parent().slideUp('fast', function() {; 101 | arrayRemove(traverseArray[traverseArray.length-1], e); 102 | storage.setData({'clipboard':traverseArray[0]}).then(rebuildMenusAndReload); 103 | rebuildTable(); 104 | analytics.trackEvent('Popup', 'Remove element'); 105 | }); 106 | } 107 | 108 | function createEntryEditForm(name, content, id) { 109 | 110 | var e = $( 111 | '
    ' + 112 | '
    ' + 113 | '
    ' + 114 | '' + 115 | //'' + 116 | '
    ' + 117 | '
    ' + 118 | '
    ' + 119 | '
    ' + 120 | '' + 121 | //'' + 122 | '
    ' + 123 | '
    ' + 124 | '
    ' + 125 | '
    ' + chrome.i18n.getMessage('commonCancel') + '
    ' + 126 | '
    ' + chrome.i18n.getMessage('optionsSave') + '
    ' + 127 | '
    ' + 128 | '
    '); 129 | 130 | return e; 131 | } 132 | 133 | function createDirectoryEditForm(name, id) { 134 | var e = $( 135 | '
    ' + 136 | '
    ' + 137 | '
    ' + 138 | '' + 139 | //'' + 140 | '
    ' + 141 | '
    ' + 142 | '
    ' + 143 | '
    ' + chrome.i18n.getMessage('commonCancel') + '
    ' + 144 | '
    ' + chrome.i18n.getMessage('optionsSave') + '
    ' + 145 | '
    ' + 146 | '
    ' 147 | ); 148 | return e; 149 | } 150 | 151 | function init_i18n() { 152 | const T = chrome.i18n.getMessage; 153 | $("#recent_btn").text(T("addBtnText")); 154 | $("#recent_name_label").text(T("descriptionPlaceholder")); 155 | $("#recent_title").text(T("popupNewElement")); 156 | 157 | $("#new_btn").text(T("addBtnText")); 158 | $("#discard_new_btn").text(T("popup_buttonDiscard")); 159 | $("#discard_recent_btn").text(T("popup_buttonDiscard")); 160 | $("#new_name_label").text(T("descriptionPlaceholder")); 161 | $("#new_content_label").text(T("contentPlaceholder")); 162 | 163 | $("#new_item_content_trigger").text(T("showAddFormText")); 164 | const isLocalStorage = localStorage.storage_type == "local"; 165 | $("#storage_type_icon").attr("data-tooltip", T(isLocalStorage ? "localStorageUsed" : "syncedStorageUsed")); 166 | $("#storage_type_icon").text(isLocalStorage ? "fiber_manual_record" : "sync"); 167 | 168 | $("#options_text").attr("data-tooltip", T("optionsText")); 169 | 170 | $("#delete_label").text(T("deleteEntryIconTitle")); 171 | $("#cancel_label").text(T("commonCancel")); 172 | 173 | $('#back_button').attr('data-tooltip', T('popupBack')); 174 | $('#new_dir_button').attr('data-tooltip', T('newDirectoryName')); 175 | $('#missing_permissions').attr('data-tooltip', T('popup_missingPermissionsWarning')); 176 | } 177 | 178 | function copyToClipboard(s) { 179 | $(s.srcElement) 180 | .animate({opacity:0.5}, defaultAnimationDuration) 181 | .delay() 182 | .animate({opacity:1}, defaultAnimationDuration); 183 | 184 | navigator.clipboard.writeText(s.srcElement.dataset.contents) 185 | .then(() => { 186 | Materialize.toast(chrome.i18n.getMessage("popup_copiedToClipboard"), 2000); 187 | analytics.trackEvent('Popup', 'Element clicked'); 188 | }, 189 | e => { 190 | Materialize.toast("Failed to store in clipboard"); 191 | }); 192 | } 193 | 194 | function createEntry(item, id) { 195 | 196 | var createSrcSet = function(base, type) { 197 | return base + "_1x." + type + ", " + base + "_2x." + type + " 2x"; 198 | } 199 | 200 | var top1 = document.createElement('div'); 201 | var top = document.createElement('div'); 202 | top.classList.add('row', 'rowrow', 'valign-wrapper'); 203 | top1.appendChild(top); 204 | top1.setAttribute('data-entryId', id); 205 | top.setAttribute('data-entryId', id); 206 | 207 | var left = document.createElement('div'); 208 | left.classList.add('col', 's1'); 209 | 210 | if (item.e != null) { 211 | var i = document.createElement('img'); 212 | i.srcset = createSrcSet('img/icons/ic_folder', 'png'); 213 | left.appendChild(i); 214 | } 215 | 216 | top.appendChild(left); 217 | 218 | var main = document.createElement('div'); 219 | main.classList.add('col', 's10'); 220 | 221 | { 222 | var a = document.createElement('a'); 223 | a.appendChild(document.createTextNode(item.desc)); 224 | if (item.value != null) { 225 | a.onclick = copyToClipboard; 226 | a.dataset.contents = item.value; 227 | a.classList.add("tooltipped"); 228 | a.dataset.position = "top"; 229 | let elipssisTextLength = 35; 230 | a.dataset.tooltip = item.value.length > elipssisTextLength+3 231 | ? item.value.substr(0, elipssisTextLength) + "..." 232 | : item.value; 233 | } else { 234 | a.onclick = function(e) { 235 | traverseArray.push(item.e); 236 | rebuildTable(); 237 | $('#back_button').removeClass('scale-out'); 238 | }; 239 | } 240 | main.appendChild(a); 241 | } 242 | 243 | top.appendChild(main); 244 | 245 | var edit = document.createElement('div'); 246 | 247 | edit.classList.add('col', 'c1', 'btn-action-wrapper'); 248 | 249 | { 250 | var d = document.createElement('div'); 251 | d.classList.add('btn-action', 'btn-flat'); 252 | var i = document.createElement('i'); 253 | i.classList.add('material-icons', 'edit_icon'); 254 | i.appendChild(document.createTextNode('mode_edit')); 255 | 256 | 257 | d.onclick = function(s) { 258 | var d = $(document.createElement('div')) 259 | .addClass('container edit-form') 260 | .append(item.value != null ? createEntryEditForm(item.desc, item.value, id) : createDirectoryEditForm(item.desc, id)) 261 | .hide(); 262 | 263 | var vv = $(this).parent().parent().parent(); 264 | 265 | d.find('.cancel-button').click(function() { 266 | d.slideUp('fast', function() { 267 | d.remove(); 268 | }); 269 | vv.find('.edit_icon').fadeIn('fast').parent().removeClass('disabled'); 270 | }); 271 | 272 | d.find('.save-button').click(function() { 273 | d.slideUp('fast', function() { 274 | traverseArray[traverseArray.length-1][id].desc = $('#editName_'+id).val(); 275 | if (item.value != null) 276 | traverseArray[traverseArray.length-1][id].value = $('#editContent_'+id).val(); 277 | storage.setData({'clipboard':traverseArray[0]}).then(rebuildMenusAndReload); 278 | }); 279 | }); 280 | 281 | vv.append(d) 282 | d.slideDown('fast'); 283 | vv.find('.edit_icon').parent().addClass('disabled'); 284 | vv.find('.edit_icon').fadeOut('fast'); 285 | vv.find('#editName_' + id).focus(); 286 | }; 287 | 288 | d.appendChild(i); 289 | edit.appendChild(d); 290 | } 291 | 292 | top.appendChild(edit); 293 | 294 | var remove = document.createElement('div'); 295 | remove.classList.add('col', 'c1'); 296 | { 297 | var d = document.createElement('div'); 298 | d.classList.add('btn-action', 'btn-flat'); 299 | d.onclick = removeElement; 300 | var i = document.createElement('i'); 301 | i.classList.add('material-icons'); 302 | i.appendChild(document.createTextNode('delete')); 303 | 304 | d.appendChild(i); 305 | remove.appendChild(d); 306 | } 307 | top.appendChild(remove); 308 | 309 | return top1; 310 | } 311 | 312 | function createTable(items) { 313 | var table = document.createElement('div'); 314 | table.classList.add('top-padded'); 315 | for (var id in items) { 316 | var item = items[id]; 317 | if (!item.desc || item.desc.length == 0) 318 | item.desc = item.value; 319 | 320 | table.appendChild(createEntry(item, id)); 321 | } 322 | return table; 323 | } 324 | 325 | function createNewDirectory(s) { 326 | traverseArray[traverseArray.length-1].push({desc:chrome.i18n.getMessage('newDirectoryName'), e:[]}); 327 | storage.setData({clipboard: traverseArray[0]}).then(() => { 328 | rebuildMenusAndReload(); 329 | analytics.trackEvent('Popup', 'Directory created'); 330 | }, (error) => { 331 | var errorMessage = chrome.i18n.getMessage("unknownError"); 332 | if (error.message.match(/^QUOTA_BYTES_PER_ITEM/)) { 333 | errorMessage = chrome.i18n.getMessage("noMoreSpace"); 334 | } 335 | Materialize.toast(chrome.i18n.getMessage("errorFailedToCreateDirectory") + errorMessage, 3000); 336 | }); 337 | } 338 | 339 | function setupDidYouKnowContainer() { 340 | var MAX_DID_YOU_KNOW = parseInt(chrome.i18n.getMessage('popupHintsCount')); 341 | var didYouKnowIDToShow = Math.floor(Math.random() * (MAX_DID_YOU_KNOW)) + 1; 342 | 343 | $('#did_you_know_text').html(chrome.i18n.getMessage('popupHintText_' + didYouKnowIDToShow)); 344 | } 345 | 346 | window.onload = function() { 347 | document.body.onpageshow = function() { 348 | chrome.runtime.sendMessage({event:'rebuildMenus'}); 349 | initialize(); 350 | loadStorageItems(); 351 | checkPermissions(); 352 | }; 353 | } 354 | 355 | function initialize() { 356 | init_i18n(); 357 | 358 | $('#recent_btn').click(addToPermClipboardFromRecent); 359 | $('#new_btn').click(addToPermClipboardFromManually); 360 | $('#new_dir_button').click(createNewDirectory); 361 | $('#discard_new_btn').click(discardNewEntry); 362 | $('#discard_recent_btn').click(discardRecentEntry); 363 | 364 | $('.tooltipped').tooltip({ 365 | options: { 366 | enterDelay: defaultAnimationDuration 367 | } 368 | }); 369 | setupDidYouKnowContainer(); 370 | 371 | var elem = document.getElementById('current_div'); 372 | 373 | $("#options_text").click(function() { 374 | chrome.tabs.create({url:'options.html'}); 375 | }); 376 | $("#missing_permissions").click(() => { 377 | chrome.tabs.create({url:'permissions.html'}); 378 | }); 379 | 380 | $('#back_button').click(function(e) { 381 | traverseArray.pop(); 382 | if (traverseArray.length == 1) 383 | $('#back_button').addClass('scale-out'); 384 | rebuildTable(); 385 | }); 386 | 387 | $("#current_div").sortable({ 388 | placeholder: "list-placeholder", 389 | forcePlaceholderSize: true, 390 | cursor: "ns-resize", 391 | axis: 'y', 392 | items: 'div.top-padded > div', 393 | opacity: 0.7, 394 | revert: defaultAnimationDuration, 395 | helper : 'clone', 396 | start: function(event, ui) { 397 | $('.btn-action', ui.item).animate( { opacity: 0 }, defaultAnimationDuration); 398 | }, 399 | stop: function(event, ui) { 400 | $('.btn-action', ui.item).animate( { opacity: 1 }, defaultAnimationDuration); 401 | var uiRaw = ui.item.get(0); 402 | 403 | var source = parseInt(uiRaw.getAttribute("data-entryId")); 404 | var target = -1; 405 | 406 | if (uiRaw.nextSibling) { 407 | var nextId = parseInt(uiRaw.nextSibling.getAttribute("data-entryId")); 408 | target = nextId - (source < nextId ? 1 : 0); 409 | } else if (uiRaw.previousSibling) { 410 | var prevId = parseInt(uiRaw.previousSibling.getAttribute("data-entryId")); 411 | target = prevId + (source > prevId ? 1 : 0); 412 | } 413 | 414 | if (target != -1 && target != source) 415 | relocateElement(source, target); 416 | } 417 | }); 418 | 419 | $("#new_content").keyup(function() { 420 | localStorage.setItem('unsaved_content', $("#new_content").val()); 421 | }); 422 | $("#new_name").keyup(function() { 423 | localStorage.setItem('unsaved_name', $("#new_name").val()); 424 | }); 425 | $("#new_item_content_trigger").click(function() { 426 | $(this).find('.badge').fadeOut(); 427 | }); 428 | 429 | }; 430 | 431 | function checkPermissions() { 432 | navigator.permissions.query({name: 'clipboard-write'}).then( 433 | result => { 434 | if (result.state !== 'granted') { 435 | $("#missing_permissions").removeClass('hide'); 436 | } 437 | } 438 | ); 439 | navigator.permissions.query({name: 'clipboard-read'}).then( 440 | result => { 441 | if (result.state !== 'granted') { 442 | $("#missing_permissions").removeClass('hide'); 443 | } 444 | } 445 | ); 446 | } 447 | 448 | function loadStorageItems() { 449 | storage.getData({'clipboard':[], 'recent':null}).then((items) => { 450 | if (items.recent) { 451 | $('#recent_text').empty().text(items.recent); 452 | $('#recent_add_element').removeClass('hide'); 453 | } 454 | traverseArray.push(items.clipboard); 455 | rebuildTable(); 456 | }, (error) => { 457 | if (error != null) 458 | console.log(error.message); 459 | }); 460 | 461 | if ((!localStorage.unsaved_name || localStorage.unsaved_name === "") && 462 | (!localStorage.unsaved_content || localStorage.unsaved_content === "")) { 463 | return; 464 | } 465 | let i = document.createElement('span'); 466 | i.classList.add('new', 'badge'); 467 | i.dataset.badgeCaption = ""; 468 | i.appendChild(document.createTextNode(chrome.i18n.getMessage('popup_unsavedChanges'))); 469 | 470 | $("#new_content").val(localStorage.unsaved_content); 471 | $("#new_name").val(localStorage.unsaved_name); 472 | 473 | $("#new_item_content_trigger").append(i); 474 | } 475 | 476 | 477 | function relocateElement(from, to) { 478 | var elem = traverseArray[traverseArray.length-1][from]; 479 | arrayRemove(traverseArray[traverseArray.length-1], from); 480 | traverseArray[traverseArray.length-1].splice(to, 0, elem); 481 | storage.setData({'clipboard':traverseArray[0]}).then(rebuildMenusAndReload); 482 | 483 | analytics.trackEvent('Popup', 'Rearrange'); 484 | } -------------------------------------------------------------------------------- /src/storage.js: -------------------------------------------------------------------------------- 1 | function Storage() { } 2 | 3 | let SYNC_QUOTA = chrome.storage.sync.QUOTA_BYTES_PER_ITEM; 4 | let LOCAL_QUOTA = chrome.storage.local.QUOTA_BYTES; 5 | 6 | Storage.prototype = { 7 | constructor: Storage, 8 | getSynchronizedStorage: function() { 9 | return chrome.storage.sync; 10 | }, 11 | getLocalStorage: function() { 12 | return chrome.storage.local; 13 | }, 14 | getDefaultStorage: function() { 15 | if (localStorage['storage_type'] == 'local') 16 | return chrome.storage.local; 17 | return chrome.storage.sync; 18 | }, 19 | getData: function(data) { 20 | return new Promise((resolve, reject) => { 21 | this.getDefaultStorage().get(data, (result) => { 22 | if (chrome.runtime.lastError) 23 | return reject(chrome.runtime.lastError); 24 | resolve(result); 25 | }); 26 | }); 27 | }, 28 | setData: function(data) { 29 | return new Promise((resolve, reject) => { 30 | this.getDefaultStorage().set(data, () => { 31 | if (chrome.runtime.lastError) 32 | return reject(chrome.runtime.lastError); 33 | resolve(); 34 | }); 35 | }); 36 | }, 37 | getStorageUsagePercentage: function() { 38 | return new Promise((resolve) => { 39 | this.getData(null, {'clipboard':[]}, function(context, data, error) { 40 | if (error != null) { 41 | resolve(0.0); 42 | } 43 | let dataLength = JSON.stringify(data.clipboard).length; 44 | let usage = dataLength / (localStorage['storage_type'] == 'local' ? LOCAL_QUOTA : SYNC_QUOTA); 45 | if (callback != undefined) { 46 | resolve(usage * 100.0); 47 | } 48 | }); 49 | }); 50 | } 51 | } 52 | 53 | if (typeof module !== 'undefined') 54 | module.exports = Storage; 55 | -------------------------------------------------------------------------------- /src/translators.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 |
    27 | 28 |
    29 |
    30 |
    31 | If you want to see Permanent Clipboard in your language contact us. 32 |
    33 |
    34 | 35 |
    36 |
    37 | 38 |
    39 |
    40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/storage.test.js: -------------------------------------------------------------------------------- 1 | 2 | const Storage = require("../src/storage.js"); 3 | 4 | global.chrome = require('sinon-chrome'); 5 | var expect = require('chai').expect; 6 | 7 | 8 | describe("Storage", function() { 9 | 10 | var storage; 11 | 12 | beforeEach(function() { 13 | storage = new Storage(); 14 | }); 15 | 16 | afterEach(function() { 17 | chrome.flush(); 18 | }); 19 | 20 | it("storage creation", function() { 21 | expect(storage).to.not.be.null; 22 | }); 23 | 24 | it("getting synchronized storage", function() { 25 | expect(storage.getSynchronizedStorage()).to.deep.equal(chrome.storage.sync); 26 | }); 27 | 28 | it("getting local storage", function() { 29 | expect(storage.getLocalStorage()).to.deep.equal(chrome.storage.local); 30 | }); 31 | 32 | it("getting default unset storage", function() { 33 | localStorage['storage_type'] = undefined; 34 | expect(storage.getDefaultStorage()).to.deep.equal(chrome.storage.sync); 35 | }); 36 | 37 | it("getting set storage type", function() { 38 | 39 | localStorage['storage_type'] = 'local'; 40 | expect(storage.getDefaultStorage()).to.deep.equal(chrome.storage.local); 41 | 42 | localStorage['storage_type'] = 'sync'; 43 | expect(storage.getDefaultStorage()).to.deep.equal(chrome.storage.sync); 44 | }) 45 | 46 | it("get data from storage", function() { 47 | 48 | localStorage['storage_type'] = 'local'; 49 | 50 | var requestedDataWithDefaults = {a: 1, b: "string"}; 51 | chrome.storage.local.get.onFirstCall().callsArgWith(1, requestedDataWithDefaults); 52 | 53 | storage.getData(storage, {}, function(context, data, error) { 54 | expect(context).to.deep.equal(storage); 55 | expect(data).to.deep.equal(requestedDataWithDefaults); 56 | expect(error).to.be.null; 57 | }); 58 | }); 59 | 60 | it("failed to get data from storage", function() { 61 | localStorage['storage_type'] = 'local'; 62 | 63 | var requestedDataWithDefaults = {a: 1, b: 'string'}; 64 | var errorStr = 'failed to get'; 65 | chrome.runtime.lastError = errorStr; 66 | chrome.storage.local.get.onFirstCall().callsArgWith(1, null); 67 | 68 | storage.getData(storage, {}, function(context, data, error) { 69 | expect(context).to.deep.equal(storage); 70 | expect(data).to.be.null; 71 | expect(error).to.equal(errorStr); 72 | }); 73 | }); 74 | 75 | it("save data to storage", function() { 76 | localStorage['storage_type'] = 'local'; 77 | 78 | var dataToSave = {a:1, b:'string'}; 79 | chrome.storage.local.set.onFirstCall().callsArg(1); 80 | 81 | storage.saveData(storage, dataToSave, function(context, error) { 82 | expect(context).to.deep.equal(storage); 83 | expect(error).to.be.undefined; 84 | }); 85 | }); 86 | 87 | it("failed saving to storage", function() { 88 | localStorage['storage_type'] = 'local'; 89 | 90 | var dataToSave = {a:1, b:'string'}; 91 | var errorStr = 'failed to set'; 92 | chrome.runtime.lastError = errorStr; 93 | chrome.storage.local.set.onFirstCall().callsArg(1); 94 | 95 | storage.saveData(storage, dataToSave, function(context, error) { 96 | expect(context).to.deep.equal(storage); 97 | expect(error).to.equal(errorStr); 98 | }); 99 | }) 100 | 101 | }); --------------------------------------------------------------------------------