├── .gitattributes ├── LICENSE ├── README.md ├── screenshots ├── 1.png ├── 2.png ├── 3.png └── 4.png ├── src ├── _locales │ ├── de │ │ └── messages.json │ ├── en │ │ └── messages.json │ ├── fr │ │ └── messages.json │ └── pl │ │ └── messages.json ├── bg.html ├── bg.js ├── changelog.js ├── custom.js ├── database.js ├── dialog.css ├── dialog.html ├── dialog.js ├── diff.js ├── diffOld.js ├── favicon.js ├── icons │ ├── add.svg │ ├── arrow.svg │ ├── changelog.svg │ ├── checked.svg │ ├── clear.svg │ ├── clock.svg │ ├── close.svg │ ├── delete.svg │ ├── dropdown.svg │ ├── edit.svg │ ├── filter.svg │ ├── folder-add.svg │ ├── folder-closed.svg │ ├── folder-opened.svg │ ├── gear.svg │ ├── icon.svg │ ├── icon2.svg │ ├── information.svg │ ├── management.svg │ ├── open.svg │ ├── pause.svg │ ├── paused.svg │ ├── play.svg │ ├── radio.svg │ ├── scan.svg │ ├── search.svg │ ├── select.svg │ ├── sidebar.svg │ ├── support.svg │ ├── warn.svg │ └── warning.svg ├── import.js ├── inputs.css ├── inspect.css ├── inspect.js ├── inspectDialog.css ├── inspectDialog.html ├── inspectDialog.js ├── inspectView.html ├── inspectView.js ├── manifest.json ├── md5.js ├── notification.opus ├── notification2.opus ├── options.css ├── options.html ├── options.js ├── popup.css ├── popup.html ├── popup.js ├── shared.js ├── sidebar.css ├── sidebar.html ├── sidebar.js ├── sortable.js ├── view.css ├── view.html ├── view.js └── viewIframe.css └── xpi ├── Web Pages Scanner 1.0.2 signed.xpi ├── Web Pages Scanner 1.0.4 signed.xpi ├── Web Pages Scanner 1.1.2 signed.xpi ├── Web Pages Scanner 1.2.1 signed.xpi ├── Web Pages Scanner 1.2.5 signed.xpi ├── Web Pages Scanner 1.3.6 signed.xpi ├── Web Pages Scanner 1.4.0 signed.xpi ├── Web Pages Scanner 1.5.1 signed.xpi ├── Web Pages Scanner 1.5.2 signed.xpi ├── Web Pages Scanner 1.5.5 signed.xpi ├── Web Pages Scanner 1.5.6 signed.xpi ├── Web Pages Scanner 1.6.0 signed.xpi ├── Web Pages Scanner 1.6.5 signed.xpi ├── Web Pages Scanner 1.6.6 signed.xpi ├── Web Pages Scanner 1.6.7 signed.xpi ├── Web Pages Scanner 1.7.0 signed.xpi ├── Web Pages Scanner 1.7.2 signed.xpi ├── Web Pages Scanner 1.7.3 signed.xpi ├── Web Pages Scanner 1.7.4 signed.xpi ├── Web Pages Scanner 1.8.0 signed.xpi ├── Web Pages Scanner 1.8.1 signed.xpi ├── Web Pages Scanner 1.8.5 signed.xpi ├── Web Pages Scanner 1.8.6 signed.xpi ├── Web Pages Scanner 1.9.0 signed.xpi ├── Web Pages Scanner 1.9.1 signed.xpi ├── Web Pages Scanner 1.9.2 signed.xpi ├── Web Pages Scanner 1.9.3 signed.xpi ├── Web Pages Scanner 1.9.4 signed.xpi ├── Web Pages Scanner 1.9.5 signed.xpi ├── Web Pages Scanner 1.9.6 signed.xpi ├── Web Pages Scanner 1.9.6.1 signed.xpi ├── Web Pages Scanner 2.0.0 signed.xpi ├── Web Pages Scanner 2.0.1 signed.xpi ├── Web Pages Scanner 2.1.0 signed.xpi └── Web Pages Scanner 2.1.5 signed.xpi /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web pages scanner ![](https://img.shields.io/amo/v/web-pages-scanner.svg) 2 | Scan web pages for updates. 3 | 4 | Features: 5 | - unlimited number of pages 6 | - automatic and manual asynchronous scanning 7 | - ability to change charset, accuracy, interval between scans 8 | - notifications about detected changes 9 | - easily add pages to scan list 10 | - preview old and new version of page 11 | - sidebar 12 | and a lot more... 13 | 14 | ## Screenshot 15 | ![](screenshots/4.png) 16 | 17 | ## Requirements 18 | - Firefox 63+ 19 | 20 | ## Permissions 21 | - Tabs 22 | - Storage 23 | - Alarms 24 | - Notifications 25 | - Context menus 26 | - 27 | - Bookmarks (optional) 28 | 29 | ## Download 30 | https://addons.mozilla.org/firefox/addon/web-pages-scanner?src=external-github 31 | -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/screenshots/2.png -------------------------------------------------------------------------------- /screenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/screenshots/3.png -------------------------------------------------------------------------------- /screenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/screenshots/4.png -------------------------------------------------------------------------------- /src/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "Web Pages Scanner" 4 | }, 5 | "extensionDescription": { 6 | "message": "Scan web pages for updates." 7 | }, 8 | 9 | "scanWebpage": { 10 | "message": "Scan" 11 | }, 12 | "openWebpage": { 13 | "message": "Open changed pages" 14 | }, 15 | "addWebpage": { 16 | "message": "Add a new page" 17 | }, 18 | "add": { 19 | "message": "Add" 20 | }, 21 | "fillForm": { 22 | "message": "Fill" 23 | }, 24 | "address": { 25 | "message": "Address:" 26 | }, 27 | "title": { 28 | "message": "Title:" 29 | }, 30 | "scanFreq": { 31 | "message": "Interval:" 32 | }, 33 | "minutes": { 34 | "message": "Minute(s)" 35 | }, 36 | "hours": { 37 | "message": "Hour(s)" 38 | }, 39 | "days": { 40 | "message": "Day(s)" 41 | }, 42 | "weeks": { 43 | "message": "Week(s)" 44 | }, 45 | "modeTitle": { 46 | "message": "Mode:" 47 | }, 48 | "modeM0": { 49 | "message": "Change in length more than 10 characters" 50 | }, 51 | "modeM1": { 52 | "message": "Change in length" 53 | }, 54 | "modeM2": { 55 | "message": "Every change" 56 | }, 57 | "modeM3": { 58 | "message": "Change in length more than 50 characters" 59 | }, 60 | "modeM4": { 61 | "message": "Change in length more than 250 characters" 62 | }, 63 | "cancel": { 64 | "message": "Cancel" 65 | }, 66 | "editWebpage": { 67 | "message": "Edit page" 68 | }, 69 | "save": { 70 | "message": "Save" 71 | }, 72 | "deleteWebpage": { 73 | "message": "Do you want to delete this page?" 74 | }, 75 | "delete": { 76 | "message": "Delete" 77 | }, 78 | "edit": { 79 | "message": "Edit" 80 | }, 81 | "addedWebpage": { 82 | "message": "Added $1" 83 | }, 84 | "addedWebpageError": { 85 | "message": "Error getting page" 86 | }, 87 | "savedWebpage": { 88 | "message": "Saved $1" 89 | }, 90 | "deletedWebpage": { 91 | "message": "Deleted $1" 92 | }, 93 | "scanCompleted": { 94 | "message": "Scanned completed" 95 | }, 96 | "oneDetected": { 97 | "message": "One page has been updated" 98 | }, 99 | "moreDetected": { 100 | "message": "$1 pages have been updated" 101 | }, 102 | "editFolder": { 103 | "message": "Edit folder" 104 | }, 105 | "name": { 106 | "message": "Name" 107 | }, 108 | "deleteFolder": { 109 | "message": "Do you want to delete this folder?" 110 | }, 111 | "deleteFolderDesc": { 112 | "message": "All web pages will be moved to the root folder." 113 | }, 114 | "addFolder": { 115 | "message": "Add a new folder" 116 | }, 117 | "newFolder": { 118 | "message": "New folder" 119 | }, 120 | 121 | "oldVersion": { 122 | "message": "Old version" 123 | }, 124 | "newVersion": { 125 | "message": "New version" 126 | }, 127 | "newElements": { 128 | "message": "New elements" 129 | }, 130 | "deletedElements": { 131 | "message": "Deleted elements" 132 | }, 133 | "highlight": { 134 | "message": "Highlight changes" 135 | }, 136 | "rawData": { 137 | "message": "Raw data" 138 | }, 139 | "currentWebpage": { 140 | "message": "Current page" 141 | }, 142 | "lastScan": { 143 | "message": "Last scan: $1 at $2" 144 | }, 145 | "monthList": { 146 | "message": ",January,February,March,April,May,June,July,August,September,October,November,December" 147 | }, 148 | "hideInterface": { 149 | "message": "Hide interface" 150 | }, 151 | "showInterface": { 152 | "message": "Show interface" 153 | }, 154 | 155 | "addThis": { 156 | "message": "Add to scan list" 157 | }, 158 | "scanNow": { 159 | "message": "Scan now" 160 | }, 161 | "showList": { 162 | "message": "Show scan list" 163 | }, 164 | "errorAdding": { 165 | "message": "Problem with adding page $1" 166 | }, 167 | "charset": { 168 | "message": "Charset" 169 | }, 170 | "options": { 171 | "message": "Options" 172 | }, 173 | "general": { 174 | "message": "General" 175 | }, 176 | "notifications": { 177 | "message": "Notifications" 178 | }, 179 | "autoOpen": { 180 | "message": "Open automatically" 181 | }, 182 | "hideHeader": { 183 | "message": "Hide interface" 184 | }, 185 | "defaultView": { 186 | "message": "Default view" 187 | }, 188 | "showNotification": { 189 | "message": "Show notification of changes" 190 | }, 191 | "notificationTime": { 192 | "message": "Notification display time" 193 | }, 194 | "volume": { 195 | "message": "Notification volume" 196 | }, 197 | "maxRequestTime": { 198 | "message": "Maximum request time [s]" 199 | }, 200 | "changedPages": { 201 | "message": "Changed pages" 202 | }, 203 | "openNewWindow": { 204 | "message": "Open in new window" 205 | }, 206 | "openNewWindowMore": { 207 | "message": "Only if changes were detected on at least 2 pages" 208 | }, 209 | "diffOld": { 210 | "message": "Use old comparing script (faster but less accurate)" 211 | }, 212 | "popupList": { 213 | "message": "Show the scan list in the popup" 214 | }, 215 | "theme": { 216 | "message": "Theme" 217 | }, 218 | "lightTheme": { 219 | "message": "Light" 220 | }, 221 | "darkTheme": { 222 | "message": "Dark" 223 | }, 224 | "autoTheme": { 225 | "message": "Automatic" 226 | }, 227 | "backup": { 228 | "message": "Create a backup" 229 | }, 230 | "showNextPrev": { 231 | "message": "Show interface for scrolling changes" 232 | }, 233 | "scrollToFirstChange": { 234 | "message": "Automatically scroll to the first change" 235 | }, 236 | "skipMinorChanges": { 237 | "message": "Skip minor changes" 238 | }, 239 | "highlightOutsideChanges": { 240 | "message": "Show changes outside the scanned element" 241 | }, 242 | "subHighlightOutside": { 243 | "message": "Applies to partially scanned pages" 244 | }, 245 | "changeOf": { 246 | "message": "Change $1 of $2" 247 | }, 248 | "numberOfChanges": { 249 | "message": "Number of changes: $1" 250 | }, 251 | "scrollPrev": { 252 | "message": "Scroll to the previous change" 253 | }, 254 | "scrollNext": { 255 | "message": "Scroll to the next change" 256 | }, 257 | "close": { 258 | "message": "Close" 259 | }, 260 | "thBackup": { 261 | "message": "Backup" 262 | }, 263 | "restoreBackup": { 264 | "message": "Restore backup" 265 | }, 266 | "restoreAlertH4": { 267 | "message": "Are you sure you want to restore the selected backup?" 268 | }, 269 | "restoreAlertP": { 270 | "message": "This operation can not be undone. All current data will be deleted. If you select the wrong or corrupted file, the extension will not work properly." 271 | }, 272 | "restoreButton": { 273 | "message": "Restore" 274 | }, 275 | "restoreError": { 276 | "message": "A problem occured. Please try again." 277 | }, 278 | "restoreOk": { 279 | "message": "The backup has been restored." 280 | }, 281 | "version": { 282 | "message": "Version " 283 | }, 284 | "changelog": { 285 | "message": "Changelog" 286 | }, 287 | "support": { 288 | "message": "Support" 289 | }, 290 | "bugReport": { 291 | "message": "Report a bug" 292 | }, 293 | "spanBugReport": { 294 | "message": "You have found a bug, maybe you have an idea how to improve the extension, create a new issue on" 295 | }, 296 | "translation": { 297 | "message": "Translation" 298 | }, 299 | "spanTranslation1": { 300 | "message": "Do you want the extension to be available in your native language, please translate" 301 | }, 302 | "spanTranslation2": { 303 | "message": "this file" 304 | }, 305 | "spanTranslation3": { 306 | "message": "and add it in a new issue on" 307 | }, 308 | "share": { 309 | "message": "Share" 310 | }, 311 | "spanShare": { 312 | "message": "Do you like this extension? Share it or write a review to reach as many people as possible." 313 | }, 314 | "h3pageView": { 315 | "message": "Page view" 316 | }, 317 | "addToContextMenu": { 318 | "message": "Add item to context menu" 319 | }, 320 | "openChangelog": { 321 | "message": "Open the 'Changelog' page after update." 322 | }, 323 | "defaultCharset": { 324 | "message": "Default charset" 325 | }, 326 | "importExport": { 327 | "message": "Import / Export" 328 | }, 329 | "importBtn": { 330 | "message": "Import pages from a bookmark folder" 331 | }, 332 | "folderName": { 333 | "message": "folder name" 334 | }, 335 | "importAlertH4": { 336 | "message": "Found multiple folders with this name." 337 | }, 338 | "importAlertP": { 339 | "message": "Select the folder from which you want to import bookmarks." 340 | }, 341 | "continue": { 342 | "message": "Continue" 343 | }, 344 | "exportBtn": { 345 | "message": "Export pages to the bookmark folder" 346 | }, 347 | "exporting": { 348 | "message": "Exporting - $1" 349 | }, 350 | "exportOK": { 351 | "message": "Completed export pages to the bookmark folder (Web Pages Scanner)" 352 | }, 353 | "importError": { 354 | "message": "Not found a folder called $1. Check that the name is correct. The size of letters is important." 355 | }, 356 | "importing": { 357 | "message": "Importing $1/$2 - $3" 358 | }, 359 | "checking": { 360 | "message": "Checking..." 361 | }, 362 | "emptyFolder": { 363 | "message": "No bookmarks in this folder" 364 | }, 365 | "importOK": { 366 | "message": "Importing completed." 367 | }, 368 | "importAlert2H4": { 369 | "message": "Pages that have not been added ($1)" 370 | }, 371 | "management": { 372 | "message": "Management" 373 | }, 374 | "deleteDuplicates": { 375 | "message": "Delete duplicates" 376 | }, 377 | "deleteBroken": { 378 | "message": "Delete broken pages" 379 | }, 380 | "deleteAlertH4": { 381 | "message": "Do you want to delete $1 pages from the scan list?" 382 | }, 383 | "noDuplicates": { 384 | "message": "No duplicates" 385 | }, 386 | "deleting": { 387 | "message": "Deleting..." 388 | }, 389 | "noBroken": { 390 | "message": "No broken pages" 391 | }, 392 | "deletedPages": { 393 | "message": "From the scan list has been deleted $1 pages" 394 | }, 395 | "labelPeriod": { 396 | "message": "Frequency of automatic scanner startup [min]" 397 | }, 398 | "sublabelPeriod": { 399 | "message": "Too low value can have a negative impact on performance" 400 | }, 401 | "labelAutoScanPause": { 402 | "message": "Disable automatic page scanning" 403 | }, 404 | "scanningAlert": { 405 | "message": "Automatic page scanning is disabled" 406 | }, 407 | "enable": { 408 | "message": "Enable" 409 | }, 410 | "pauseScan": { 411 | "message": "Stop scanning" 412 | }, 413 | "playScan": { 414 | "message": "Resume scanning" 415 | }, 416 | "permissionGranted": { 417 | "message": "The extension has permission to access the bookmarks" 418 | }, 419 | "permissionRevoked": { 420 | "message": "To use these features you have to allow to access the bookmarks" 421 | }, 422 | "grant": { 423 | "message": "Grant permission" 424 | }, 425 | "revoke": { 426 | "message": "Revoke permission" 427 | }, 428 | "search": { 429 | "message": "Search..." 430 | }, 431 | "hidePages": { 432 | "message": "Show only pages:" 433 | }, 434 | "changed": { 435 | "message": "Changed" 436 | }, 437 | "paused": { 438 | "message": "Paused" 439 | }, 440 | "broken": { 441 | "message": "Broken" 442 | }, 443 | "normal": { 444 | "message": "Normal" 445 | }, 446 | "paritially": { 447 | "message": "Scanned partially" 448 | }, 449 | "showSearchbar": { 450 | "message": "Show search bar" 451 | }, 452 | "delay": { 453 | "message": "Delay in opening next pages in new tabs [s]" 454 | }, 455 | "subDelay": { 456 | "message": "Default value: 0, all pages opened simultaneously" 457 | }, 458 | "shortcutLabel": { 459 | "message": "Shortcut opening sidebar" 460 | }, 461 | "inspectText": { 462 | "message": "Selected element. Changes will be detected only inside this element." 463 | }, 464 | "inspectRetry": { 465 | "message": "Pick another element" 466 | }, 467 | "paritialMode": { 468 | "message": "Scan a part of the page" 469 | }, 470 | "selectorCSS": { 471 | "message": "CSS Selector" 472 | }, 473 | "inspectElement": { 474 | "message": "Pick an element from the page" 475 | }, 476 | "ok": { 477 | "message": "OK" 478 | }, 479 | "scanList": { 480 | "message": "Scan list" 481 | }, 482 | "ignoreNumbers":{ 483 | "message": "Ignore number changes" 484 | }, 485 | "scrollbarMarkers":{ 486 | "message": "Show change markers on a scrollbar" 487 | }, 488 | "faviconService":{ 489 | "message": "Favicon service" 490 | }, 491 | "native":{ 492 | "message": "Native" 493 | }, 494 | "deleteScripts":{ 495 | "message": "Delete scripts" 496 | }, 497 | "deleteComments":{ 498 | "message": "Delete comments" 499 | }, 500 | "ignoreHrefs":{ 501 | "message": "Ignore link addresses" 502 | }, 503 | "ignoreStyles":{ 504 | "message": "Ignore page styles" 505 | }, 506 | "ignoreAllAttributes":{ 507 | "message": "Ignore all attributes" 508 | }, 509 | "yes":{ 510 | "message": "Yes" 511 | }, 512 | "no":{ 513 | "message": "No" 514 | }, 515 | "global":{ 516 | "message": "Global value" 517 | }, 518 | "notificationSound":{ 519 | "message": "Notification sound" 520 | }, 521 | "sound":{ 522 | "message": "Sound " 523 | }, 524 | "externalSound":{ 525 | "message": "External sound" 526 | }, 527 | "soundUrl":{ 528 | "message": "Sound URL" 529 | }, 530 | "tooltipOpenPages":{ 531 | "message": "\r Open changed pages (middle-click)" 532 | }, 533 | "tooltipStopOpening":{ 534 | "message": "\r Stop opening changed pages (middle-click)" 535 | }, 536 | "h3sidebar":{ 537 | "message": "Sidebar" 538 | }, 539 | "h3defaultValues":{ 540 | "message": "Default values" 541 | }, 542 | "defaultInterval":{ 543 | "message": "Default interval" 544 | }, 545 | "defaultMode":{ 546 | "message": "Default mode" 547 | }, 548 | "defaultIgnoreNumbers":{ 549 | "message": "By default, ignore number changes" 550 | }, 551 | "defaultDeleteScripts":{ 552 | "message": "By default, delete scripts" 553 | }, 554 | "defaultDeleteComments":{ 555 | "message": "By default, delete comments" 556 | }, 557 | "defaultIgnoreHrefs":{ 558 | "message": "By default, ignore link addresses" 559 | }, 560 | "defaultIgnoreStyles":{ 561 | "message": "By default, ignore page styles" 562 | }, 563 | "defaultIgnoreAllAttributes":{ 564 | "message": "By default, ignore all attributes" 565 | }, 566 | "warningPart":{ 567 | "message": "The selected element of partial scanning does not exist." 568 | }, 569 | "warningBroken":{ 570 | "message": "This page was not scanned. The problem occurred $1 times." 571 | }, 572 | "warnBeforeUpdating":{ 573 | "message": "Inform about the extension update" 574 | }, 575 | "updateAlertH4":{ 576 | "message": "A new version of the extension is available" 577 | }, 578 | "updateAlertP":{ 579 | "message": "It is recommended to make a backup before updating" 580 | }, 581 | "updateNow":{ 582 | "message": "Update now" 583 | }, 584 | "foundDuplicate":{ 585 | "message": "Found a duplicate" 586 | }, 587 | "duplicateMessage":{ 588 | "message": "The '$1' page was already on the scan list. Show duplicates." 589 | }, 590 | "duplicateMessage2":{ 591 | "message": "This page is already added to the scan list" 592 | }, 593 | "show":{ 594 | "message": "Show" 595 | }, 596 | "saveOnlyPart":{ 597 | "message": "Save only the selected element" 598 | }, 599 | "defaultSaveOnlyPart":{ 600 | "message": "By default, save only the selected element" 601 | }, 602 | "dropHere":{ 603 | "message": "Drop here to add to the scan list" 604 | }, 605 | "h3sort": { 606 | "message": "Sorting" 607 | }, 608 | "sort": { 609 | "message": "Sort" 610 | }, 611 | "descDate": { 612 | "message": "By newest" 613 | }, 614 | "ascDate": { 615 | "message": "By oldest" 616 | }, 617 | "az": { 618 | "message": "From A to Z" 619 | }, 620 | "za": { 621 | "message": "From Z to A" 622 | }, 623 | "chooseFile": { 624 | "message": "Choose file" 625 | } 626 | } 627 | -------------------------------------------------------------------------------- /src/_locales/pl/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": { 3 | "message": "Skaner Stron" 4 | }, 5 | "extensionDescription": { 6 | "message": "Skanuj strony w poszukiwaniu zmian." 7 | }, 8 | 9 | "scanWebpage": { 10 | "message": "Skanuj" 11 | }, 12 | "openWebpage": { 13 | "message": "Otwórz zmienione strony" 14 | }, 15 | "addWebpage": { 16 | "message": "Dodaj nową stronę" 17 | }, 18 | "add": { 19 | "message": "Dodaj" 20 | }, 21 | "fillForm": { 22 | "message": "Uzupełnij" 23 | }, 24 | "address": { 25 | "message": "Adres:" 26 | }, 27 | "title": { 28 | "message": "Tytuł:" 29 | }, 30 | "scanFreq": { 31 | "message": "Interwał:" 32 | }, 33 | "minutes": { 34 | "message": "Minut/y" 35 | }, 36 | "hours": { 37 | "message": "Godzin/y" 38 | }, 39 | "days": { 40 | "message": "Dni" 41 | }, 42 | "weeks": { 43 | "message": "Tygodni/e" 44 | }, 45 | "modeTitle": { 46 | "message": "Tryb:" 47 | }, 48 | "modeM0": { 49 | "message": "Zmiana długości powyżej 10 znaków" 50 | }, 51 | "modeM1": { 52 | "message": "Zmiana długości" 53 | }, 54 | "modeM2": { 55 | "message": "Każda zmiana" 56 | }, 57 | "modeM3": { 58 | "message": "Zmiana długości powyżej 50 znaków" 59 | }, 60 | "modeM4": { 61 | "message": "Zmiana długości powyżej 250 znaków" 62 | }, 63 | "cancel": { 64 | "message": "Anuluj" 65 | }, 66 | "editWebpage": { 67 | "message": "Edytuj stronę" 68 | }, 69 | "save": { 70 | "message": "Zapisz" 71 | }, 72 | "deleteWebpage": { 73 | "message": "Chcesz usunąć tę stronę?" 74 | }, 75 | "delete": { 76 | "message": "Usuń" 77 | }, 78 | "edit": { 79 | "message": "Edytuj" 80 | }, 81 | "addedWebpage": { 82 | "message": "Dodano $1" 83 | }, 84 | "addedWebpageError": { 85 | "message": "Wystąpił problem z pobraniem strony" 86 | }, 87 | "savedWebpage": { 88 | "message": "Zapisano $1" 89 | }, 90 | "deletedWebpage": { 91 | "message": "Usunięto $1" 92 | }, 93 | "scanCompleted": { 94 | "message": "Zakończono skanowanie" 95 | }, 96 | "oneDetected": { 97 | "message": "Wykryto zmiany na jednej stronie" 98 | }, 99 | "moreDetected": { 100 | "message": "Wykryto zmiany na $1 stronach" 101 | }, 102 | "editFolder": { 103 | "message": "Edytuj folder" 104 | }, 105 | "name": { 106 | "message": "Nazwa" 107 | }, 108 | "deleteFolder": { 109 | "message": "Czy chcesz usunąć ten folder?" 110 | }, 111 | "deleteFolderDesc": { 112 | "message": "Wszystkie strony zostaną przeniesione do folderu głównego." 113 | }, 114 | "addFolder": { 115 | "message": "Dodaj nowy folder" 116 | }, 117 | "newFolder": { 118 | "message": "Nowy folder" 119 | }, 120 | 121 | "oldVersion": { 122 | "message": "Stara wersja" 123 | }, 124 | "newVersion": { 125 | "message": "Nowa wersja" 126 | }, 127 | "newElements": { 128 | "message": "Nowe elementy" 129 | }, 130 | "deletedElements": { 131 | "message": "Usunięte elementy" 132 | }, 133 | "highlight": { 134 | "message": "Podświetl zmiany" 135 | }, 136 | "rawData": { 137 | "message": "Surowe dane" 138 | }, 139 | "currentWebpage": { 140 | "message": "Bieżąca strona" 141 | }, 142 | "lastScan": { 143 | "message": "Ostatnie skanowanie: $1 o $2" 144 | }, 145 | "monthList": { 146 | "message": ",stycznia,lutego,marca,kwietnia,maja,czerwca,lipca,sierpnia,września,października,listopada,grudnia" 147 | }, 148 | "hideInterface": { 149 | "message": "Ukryj interfejs" 150 | }, 151 | "showInterface": { 152 | "message": "Pokaż interfejs" 153 | }, 154 | 155 | "addThis": { 156 | "message": "Dodaj do listy skanowania" 157 | }, 158 | "scanNow": { 159 | "message": "Skanuj teraz" 160 | }, 161 | "showList": { 162 | "message": "Pokaż listę skanowania" 163 | }, 164 | "errorAdding": { 165 | "message": "Problem z dodaniem strony $1" 166 | }, 167 | "charset": { 168 | "message": "Kodowanie" 169 | }, 170 | "options": { 171 | "message": "Opcje" 172 | }, 173 | "general": { 174 | "message": "Ogólne" 175 | }, 176 | "notifications": { 177 | "message": "Powiadomienia" 178 | }, 179 | "autoOpen": { 180 | "message": "Otwórz automatycznie" 181 | }, 182 | "hideHeader": { 183 | "message": "Ukryj interfejs" 184 | }, 185 | "defaultView": { 186 | "message": "Domyślny widok" 187 | }, 188 | "showNotification": { 189 | "message": "Pokaż powiadomienie o zmianach" 190 | }, 191 | "notificationTime": { 192 | "message": "Czas wyświetlania powiadomienia" 193 | }, 194 | "volume": { 195 | "message": "Głośność powiadomienia" 196 | }, 197 | "maxRequestTime": { 198 | "message": "Maksymalny czas żadania [s]" 199 | }, 200 | "changedPages": { 201 | "message": "Zmienione strony" 202 | }, 203 | "openNewWindow": { 204 | "message": "Otwórz w nowym oknie" 205 | }, 206 | "openNewWindowMore": { 207 | "message": "Tylko, jeśli wykryto zmiany na co najmniej 2 stronach" 208 | }, 209 | "diffOld": { 210 | "message": "Użyj starego skryptu porównującego (szybszy, ale mniej dokładny)" 211 | }, 212 | "popupList": { 213 | "message": "Pokaż listę skanowania w wyskującym okienku" 214 | }, 215 | "theme": { 216 | "message": "Motyw" 217 | }, 218 | "lightTheme": { 219 | "message": "Jasny" 220 | }, 221 | "darkTheme": { 222 | "message": "Ciemny" 223 | }, 224 | "autoTheme": { 225 | "message": "Automatyczny" 226 | }, 227 | "backup": { 228 | "message": "Utwórz kopię zapasową" 229 | }, 230 | "showNextPrev": { 231 | "message": "Pokaż interfejs przewijania zmian" 232 | }, 233 | "scrollToFirstChange": { 234 | "message": "Automatyczne przewijanie do pierwszej zmiany" 235 | }, 236 | "skipMinorChanges": { 237 | "message": "Pomiń drobne zmiany" 238 | }, 239 | "highlightOutsideChanges": { 240 | "message": "Pokaż zmiany poza skanowanym elementem" 241 | }, 242 | "subHighlightOutside": { 243 | "message": "Dotyczy stron skanowanych częściowo" 244 | }, 245 | "changeOf": { 246 | "message": "Zmiana $1 z $2" 247 | }, 248 | "numberOfChanges": { 249 | "message": "Liczba zmian: $1" 250 | }, 251 | "scrollPrev": { 252 | "message": "Przewiń do poprzedniej zmiany" 253 | }, 254 | "scrollNext": { 255 | "message": "Przewiń do następnej zmiany" 256 | }, 257 | "close": { 258 | "message": "Zamknij" 259 | }, 260 | "thBackup": { 261 | "message": "Kopia zapasowa" 262 | }, 263 | "restoreBackup": { 264 | "message": "Przywróć kopię zapasową" 265 | }, 266 | "restoreAlertH4": { 267 | "message": "Czy na pewno chcesz przywrócić wybraną kopię zapasową?" 268 | }, 269 | "restoreAlertP": { 270 | "message": "Tej operacji nie można cofnąć. Wszystkie obecne dane zostaną usunięte. Jeśli wybrano niewłaściwy lub uszkodzony plik rozszerzenie nie będzie działało poprawnie." 271 | }, 272 | "restoreButton": { 273 | "message": "Przywróć" 274 | }, 275 | "restoreError": { 276 | "message": "Wystąpił problem. Proszę spróbować ponownie." 277 | }, 278 | "restoreOk": { 279 | "message": "Kopia zapasowa została przywrócona." 280 | }, 281 | "version": { 282 | "message": "Wersja " 283 | }, 284 | "changelog": { 285 | "message": "Historia zmian" 286 | }, 287 | "support": { 288 | "message": "Wsparcie" 289 | }, 290 | "bugReport": { 291 | "message": "Zgłoś błąd" 292 | }, 293 | "spanBugReport": { 294 | "message": "Znalazłeś błąd, a może masz pomysł jak ulepszyć rozszerzenie, załóź nowy wątek na" 295 | }, 296 | "translation": { 297 | "message": "Tłumaczenie" 298 | }, 299 | "spanTranslation1": { 300 | "message": "Chcesz aby rozszerzenie było dostępne w twoim ojczystym języku, przetłumacz" 301 | }, 302 | "spanTranslation2": { 303 | "message": "ten plik" 304 | }, 305 | "spanTranslation3": { 306 | "message": "i dodaj go w nowym wątku na" 307 | }, 308 | "share": { 309 | "message": "Podziel się" 310 | }, 311 | "spanShare": { 312 | "message": "Lubisz to rozszerzenie? Podziel się nim lub pozostaw opinię, aby dotarło do jak największej liczby osób." 313 | }, 314 | "h3pageView": { 315 | "message": "Widok strony" 316 | }, 317 | "addToContextMenu": { 318 | "message": "Dodaj element do menu kontekstowego" 319 | }, 320 | "openChangelog": { 321 | "message": "Otwórz stronę z 'Historią zmian' po aktualizacji" 322 | }, 323 | "defaultCharset": { 324 | "message": "Domyślne kodowanie tekstu" 325 | }, 326 | "importExport": { 327 | "message": "Import / Eksport" 328 | }, 329 | "importBtn": { 330 | "message": "Importuj strony z folderu zakładek" 331 | }, 332 | "folderName": { 333 | "message": "nazwa folderu" 334 | }, 335 | "importAlertH4": { 336 | "message": "Znaleziono wiele folderów o takiej nazwie." 337 | }, 338 | "importAlertP": { 339 | "message": "Wybierz folder, z którego chcesz importować zakładki." 340 | }, 341 | "continue": { 342 | "message": "Kontynuuj" 343 | }, 344 | "exportBtn": { 345 | "message": "Eksportuj strony do folderu zakładek" 346 | }, 347 | "exporting": { 348 | "message": "Eksportowanie - $1" 349 | }, 350 | "exportOK": { 351 | "message": "Zakończono eksportowanie stron do folderu zakładek (Skaner Stron)" 352 | }, 353 | "importError": { 354 | "message": "Nie odnaleziono folderu o nazwie $1. Sprawdź, czy nazwa jest poprawna. Wielkość liter ma znaczenie." 355 | }, 356 | "importing": { 357 | "message": "Importowanie $1/$2 - $3" 358 | }, 359 | "checking": { 360 | "message": "Sprawdzanie..." 361 | }, 362 | "emptyFolder": { 363 | "message": "Brak zakładek w tym folderze" 364 | }, 365 | "importOK": { 366 | "message": "Importowanie zakończone." 367 | }, 368 | "importAlert2H4": { 369 | "message": "Strony, które nie zostały dodane ($1)" 370 | }, 371 | "management": { 372 | "message": "Zarządzanie" 373 | }, 374 | "deleteDuplicates": { 375 | "message": "Usuń duplikaty" 376 | }, 377 | "deleteBroken": { 378 | "message": "Usuń niedziałające strony" 379 | }, 380 | "deleteAlertH4": { 381 | "message": "Czy checesz usunąć z listy skanowania $1 stron/y?" 382 | }, 383 | "noDuplicates": { 384 | "message": "Brak duplikatów" 385 | }, 386 | "deleting": { 387 | "message": "Usuwanie..." 388 | }, 389 | "noBroken": { 390 | "message": "Brak niedziałających stron" 391 | }, 392 | "deletedPages": { 393 | "message": "Z listy skanowania usunięto $1 stron/y" 394 | }, 395 | "labelPeriod": { 396 | "message": "Częstotliwość automatycznego uruchamiania skanera [min]" 397 | }, 398 | "sublabelPeriod": { 399 | "message": "Zbyt mała wartość może mieć negatywny wpływ na wydajność" 400 | }, 401 | "labelAutoScanPause": { 402 | "message": "Wyłącz automatyczne skanowanie stron" 403 | }, 404 | "scanningAlert": { 405 | "message": "Automatyczne skanowanie stron jest wyłączone" 406 | }, 407 | "enable": { 408 | "message": "Włącz" 409 | }, 410 | "pauseScan": { 411 | "message": "Zatrzymaj skanowanie" 412 | }, 413 | "playScan": { 414 | "message": "Wznów skanowanie" 415 | }, 416 | "permissionGranted": { 417 | "message": "Rozszerzenie posiada pozwolenie na dostęp do zakładek" 418 | }, 419 | "permissionRevoked": { 420 | "message": "Aby korzystać z tych funkcji, musisz zezwolić na dostęp do zakładek" 421 | }, 422 | "grant": { 423 | "message": "Przyznaj uprawnienia" 424 | }, 425 | "revoke": { 426 | "message": "Cofnij uprawnienia" 427 | }, 428 | "search": { 429 | "message": "Szukaj..." 430 | }, 431 | "hidePages": { 432 | "message": "Pokaż tylko strony:" 433 | }, 434 | "changed": { 435 | "message": "Zmienione" 436 | }, 437 | "paused": { 438 | "message": "Wstrzymane" 439 | }, 440 | "broken": { 441 | "message": "Uszkodzone" 442 | }, 443 | "normal": { 444 | "message": "Normalne" 445 | }, 446 | "paritially": { 447 | "message": "Skanowane częściowo" 448 | }, 449 | "showSearchbar": { 450 | "message": "Pokaż pasek wyszukiwania" 451 | }, 452 | "delay": { 453 | "message": "Opóźnienie w otwieraniu kolejnych stron w nowych kartach [s]" 454 | }, 455 | "subDelay": { 456 | "message": "Domyślna wartość: 0, wszystkie strony otwierane jednocześnie" 457 | }, 458 | "shortcutLabel": { 459 | "message": "Skrót otwierający panel boczny" 460 | }, 461 | "inspectText": { 462 | "message": "Wybrano element. Zmiany będą wykrywane wyłącznie wewnątrz tego elementu." 463 | }, 464 | "inspectRetry": { 465 | "message": "Wskaż inny element" 466 | }, 467 | "paritialMode": { 468 | "message": "Skanuj część strony" 469 | }, 470 | "selectorCSS": { 471 | "message": "Selektor CSS" 472 | }, 473 | "inspectElement": { 474 | "message": "Wskaż element na stronie" 475 | }, 476 | "ok": { 477 | "message": "OK" 478 | }, 479 | "scanList": { 480 | "message": "Lista skanowania" 481 | }, 482 | "ignoreNumbers":{ 483 | "message": "Ignoruj zmiany liczb" 484 | }, 485 | "scrollbarMarkers":{ 486 | "message": "Pokaż znaczniki zmian na pasku przewijania" 487 | }, 488 | "faviconService":{ 489 | "message": "Usługa ikon stron" 490 | }, 491 | "native":{ 492 | "message": "Natywna" 493 | }, 494 | "deleteScripts":{ 495 | "message": "Usuwaj skrypty" 496 | }, 497 | "deleteComments":{ 498 | "message": "Usuwaj komentarze" 499 | }, 500 | "ignoreHrefs":{ 501 | "message": "Ignoruj adresy odnośników" 502 | }, 503 | "ignoreStyles":{ 504 | "message": "Ignoruj style strony" 505 | }, 506 | "ignoreAllAttributes":{ 507 | "message": "Ignoruj wszystkie atrybuty" 508 | }, 509 | "yes":{ 510 | "message": "Tak" 511 | }, 512 | "no":{ 513 | "message": "Nie" 514 | }, 515 | "global":{ 516 | "message": "Wartość globalna" 517 | }, 518 | "notificationSound":{ 519 | "message": "Dźwięk powiadomienia" 520 | }, 521 | "sound":{ 522 | "message": "Dźwięk " 523 | }, 524 | "externalSound":{ 525 | "message": "Dźwięk zewnętrzny" 526 | }, 527 | "soundUrl":{ 528 | "message": "Adres URL dźwięku" 529 | }, 530 | "tooltipOpenPages":{ 531 | "message": "\r Otwórz zmienione strony (środkowy przycisk)" 532 | }, 533 | "tooltipStopOpening":{ 534 | "message": "\r Zatrzymaj otwieranie zmienionych stron (środkowy przycisk)" 535 | }, 536 | "h3sidebar":{ 537 | "message": "Panel boczny" 538 | }, 539 | "h3defaultValues":{ 540 | "message": "Wartości domyślne" 541 | }, 542 | "defaultInterval":{ 543 | "message": "Domyślny interwał" 544 | }, 545 | "defaultMode":{ 546 | "message": "Domyślny tryb" 547 | }, 548 | "defaultIgnoreNumbers":{ 549 | "message": "Domyślnie ignoruj zmiany liczb" 550 | }, 551 | "defaultDeleteScripts":{ 552 | "message": "Domyślnie usuwaj skrypty" 553 | }, 554 | "defaultDeleteComments":{ 555 | "message": "Domyślnie usuwaj komentarze" 556 | }, 557 | "defaultIgnoreHrefs":{ 558 | "message": "Domyślnie ignoruj adresy odnośników" 559 | }, 560 | "defaultIgnoreStyles":{ 561 | "message": "Domyślnie ignoruj style strony" 562 | }, 563 | "defaultIgnoreAllAttributes":{ 564 | "message": "Domyślnie ignoruj wszystkie atrybuty" 565 | }, 566 | "warningPart":{ 567 | "message": "Wybrany element skanowania częściowego nie istnieje." 568 | }, 569 | "warningBroken":{ 570 | "message": "Ta strona nie została przeskanowana. Problem wystąpił $1 razy." 571 | }, 572 | "warnBeforeUpdating":{ 573 | "message": "Informuj o aktualizacji rozszerzenia" 574 | }, 575 | "updateAlertH4":{ 576 | "message": "Dostępna jest nowa wersja rozszerzenia" 577 | }, 578 | "updateAlertP":{ 579 | "message": "Przed aktualizacją zaleca się wykonanie kopii zapasowej" 580 | }, 581 | "updateNow":{ 582 | "message": "Aktualizuj teraz" 583 | }, 584 | "foundDuplicate":{ 585 | "message": "Znaleziono duplikat" 586 | }, 587 | "duplicateMessage":{ 588 | "message": "Strona '$1' była już na liście skanowania. Pokaż duplikaty." 589 | }, 590 | "duplicateMessage2":{ 591 | "message": "Ta strona jest już dodana do listy skanowania" 592 | }, 593 | "show":{ 594 | "message": "Pokaż" 595 | }, 596 | "saveOnlyPart":{ 597 | "message": "Zapisuj tylko wybrany element" 598 | }, 599 | "defaultSaveOnlyPart":{ 600 | "message": "Domyślnie zapisuj tylko wybrany element" 601 | }, 602 | "dropHere":{ 603 | "message": "Upuść tutaj, aby dodać do listy skanowania" 604 | }, 605 | "h3sort": { 606 | "message": "Sortowanie" 607 | }, 608 | "sort": { 609 | "message": "Sortuj" 610 | }, 611 | "descDate": { 612 | "message": "Od najnowszych" 613 | }, 614 | "ascDate": { 615 | "message": "Od najstarszych" 616 | }, 617 | "az": { 618 | "message": "Od A do Z" 619 | }, 620 | "za": { 621 | "message": "Od Z do A" 622 | }, 623 | "chooseFile": { 624 | "message": "Wybierz plik" 625 | } 626 | } 627 | -------------------------------------------------------------------------------- /src/bg.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/bg.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | browser.runtime.onInstalled.addListener(handleInstalled); 4 | function handleInstalled(details) { 5 | const defaultSettings={ 6 | "notificationVolume":60, 7 | "notificationTime":10000, 8 | "showNotification":true, 9 | "autoOpen":false, 10 | "hideHeader":false, 11 | "defaultView":"light", 12 | "openWindow":false, 13 | "openWindowMore":1, 14 | "requestTime":10000, 15 | "diffOld":false, 16 | "popupList":false, 17 | "theme":"auto", 18 | "showNextPrev":true, 19 | "scrollToFirstChange":true, 20 | "skipMinorChanges":true, 21 | "addToContextMenu":true, 22 | "changelog":true, 23 | "charset":"utf-8", 24 | "period":60, 25 | "paused":false, 26 | "search":true, 27 | "delay":0, 28 | "highlightOutsideChanges":false, 29 | "scrollbarMarkers":true, 30 | "faviconService":"native", 31 | "notificationSound":"notification.opus", 32 | "defaultFreq":8, 33 | "defaultMode":"m0", 34 | "defaultIgnoreNumbers":false, 35 | "defaultDeleteScripts":true, 36 | "defaultDeleteComments":true, 37 | "defaultIgnoreHrefs":false, 38 | "defaultIgnoreStyles":false, 39 | "defaultIgnoreAllAttributes":false, 40 | "defaultSaveOnlyPart":false, 41 | "warnBeforeUpdating":true, 42 | }; 43 | if(details.reason==="install"){ 44 | browser.storage.local.get(['sites','settings','dbVersion']).then(result=>{ 45 | const storage={}; 46 | if(result.sites===undefined){ 47 | Object.assign(storage,{sites:[],sort:[]}); 48 | } 49 | if(result.settings===undefined){ 50 | Object.assign(storage,{settings:defaultSettings}); 51 | } 52 | if(result.dbVersion===undefined){ 53 | Object.assign(storage,{dbVersion:1}); 54 | } 55 | browser.storage.local.set(storage).then(async ()=>{ 56 | if(!db)await getDB(); 57 | init(); 58 | if(!details.temporary){ 59 | browser.tabs.create({ 60 | url:`${extURL}options.html#changelog`, 61 | active:true 62 | }); 63 | } 64 | },err=>{ 65 | console.error(err); 66 | }); 67 | },err=>{ 68 | console.error(err); 69 | }); 70 | }else if(details.reason==="update"){ 71 | browser.storage.local.get('settings').then(result=>{ 72 | const settings=Object.assign({},defaultSettings,result.settings); 73 | browser.storage.local.set({settings}).then(()=>{ 74 | if(!details.temporary&&settings.changelog){ 75 | browser.tabs.create({ 76 | url:`${extURL}options.html#changelog`, 77 | active:true 78 | }); 79 | } 80 | },err=>{ 81 | console.error(err); 82 | }); 83 | },err=>{ 84 | console.error(err); 85 | }); 86 | } 87 | } 88 | 89 | browser.browserAction.onClicked.addListener(async (tab,e)=>{ 90 | if(e.button===1){ 91 | const activeAlarm=browser.alarms.get("openSitesDelay"); 92 | const badgeNumber=browser.browserAction.getBadgeText({}); 93 | if(await activeAlarm){ 94 | browser.alarms.clear("openSitesDelay"); 95 | updateTooltip("alarm"); 96 | }else if(delayLinksId&&delayLinksId.length){ 97 | browser.alarms.create("openSitesDelay",{delayInMinutes:0.01}); 98 | updateTooltip("alarm"); 99 | }else if(await badgeNumber){ 100 | openSite(); 101 | } 102 | } 103 | }); 104 | 105 | browser.runtime.onUpdateAvailable.addListener(()=>{ 106 | browser.storage.local.get("settings").then(result=>{ 107 | if(result.settings.warnBeforeUpdating){ 108 | browser.tabs.create({ 109 | url:`${extURL}options.html?update#management`, 110 | active:true 111 | }); 112 | } 113 | },err=>{ 114 | console.error(err); 115 | }); 116 | }); 117 | 118 | browser.notifications.onClicked.addListener(e=>{ 119 | switch(e){ 120 | case "webpagesScannerScanned": 121 | getSettings("autoOpen").then(s=>{ 122 | if(!s){openSite();} 123 | }); 124 | break; 125 | case "webpagesScannerDuplicates": 126 | openDuplicates(); 127 | break; 128 | } 129 | }); 130 | 131 | (function(){ 132 | browser.storage.local.get(['sites','sort','settings','dbVersion']).then(result=>{ 133 | if(result.sites===undefined||result.settings===undefined){ 134 | handleInstalled({reason:"install"}); 135 | }else if(result.dbVersion===1){ 136 | init(); 137 | }else{ 138 | convertDb(); 139 | } 140 | if(result.sort===undefined&&result.sites!==undefined){ 141 | let sort=[]; 142 | result.sites.forEach((value,i)=>{ 143 | sort.push([`item${i}`,"root","item","",false]); 144 | }); 145 | browser.storage.local.set({sort}).then(()=>{},err=>{console.error(err);}); 146 | } 147 | },err=>{ 148 | console.error(err); 149 | }); 150 | })(); 151 | 152 | function init(){ 153 | browser.storage.local.get('settings').then(result=>{ 154 | if(!result.settings.popupList)browser.browserAction.setPopup({popup:"/popup.html"}); 155 | else browser.browserAction.setPopup({popup:"/sidebar.html?"}); 156 | showContext(result.settings.addToContextMenu); 157 | let period=result.settings.period?result.settings.period:60; 158 | if(!result.settings.paused){ 159 | browser.alarms.create("webpageScanner",{delayInMinutes:1,periodInMinutes:period+1}); 160 | } 161 | },err=>{ 162 | console.error(err); 163 | }); 164 | } 165 | 166 | browser.alarms.onAlarm.addListener(alarm=>{ 167 | if(alarm.name==="webpageScanner")scanSites(); 168 | else if(alarm.name==="openSitesDelay")openSitesDelay(); 169 | }); 170 | 171 | let delayCurrentId, 172 | delayTime, 173 | delayLinksId, 174 | lastWindowId; 175 | 176 | browser.runtime.onMessage.addListener(run); 177 | function run(m,s,r){ 178 | if(m.addThis)rqstAdd(m.url,m.title,m.favicon,m.mode,m.freq,m.addBookmark,m.cssSelector,m.ignoreNumbers,m.deleteScripts,m.deleteComments,m.ignoreHrefs,m.charset,m.pageSettings,m.ignoreStyles,m.ignoreAllAttributes,m.saveOnlyPart,m.folder); 179 | if(m.scanSites)scanSites(m.force); 180 | if(m.openSites)openSite(); 181 | if(m.addToContextMenu!==undefined)showContext(m.addToContextMenu); 182 | if(m.period)browser.alarms.create("webpageScanner",{delayInMinutes:1,periodInMinutes:m.period}); 183 | if(m.openSitesDelay){delayCurrentId=0;delayTime=m.openSitesDelay;delayLinksId=m.linksId;lastWindowId=-1;openSitesDelay(m.openWindow);} 184 | if(m.closeTab){browser.tabs.remove(s.tab.id);} 185 | if(m.scanPagesById){scanPagesById(m.idArray);} 186 | if(m.updateBadge){updateBadge(m.updateBadgeArg);} 187 | if(m.unchange){unchange(m.unchangeArg);} 188 | if(m.tabInfo){r({tab:s.tab});} 189 | if(m.showWpsPopup){showPopup(m.mode,m.editId);} 190 | if(m.unhideWpsPopup){ 191 | browser.tabs.executeScript(s.tab.id,{ 192 | code:`document.getElementById("__wps_pageSettings").style.visibility="visible";` 193 | }).then(()=>{},err=>{ 194 | console.error(err); 195 | }); 196 | } 197 | if(m.deleteWpsPopup){ 198 | browser.tabs.executeScript(s.tab.id,{ 199 | code:`document.getElementById("__wps_pageSettings").remove();` 200 | }).then(()=>{},err=>{ 201 | console.error(err); 202 | }); 203 | } 204 | if(m.inspectTab){ 205 | browser.tabs.create({url:`${extURL}inspectView.html`}).then(tab=>{ 206 | browser.tabs.executeScript(tab.id,{ 207 | file: "/inspectView.js", 208 | runAt:"document_start" 209 | }).then(()=>{ 210 | browser.tabs.sendMessage(tab.id,{ 211 | "inspectUrl":m.inspectUrl, 212 | "loadXHR":true, 213 | "dialogTabId":s.tab.id, 214 | }).then(()=>{},err=>{ 215 | console.warn(err); 216 | }); 217 | },err=>{ 218 | console.error(err); 219 | browser.tabs.sendMessage(tab.id,{ 220 | "inspectUrl":m.inspectUrl, 221 | "loadXHR":true, 222 | "dialogTabId":s.tab.id, 223 | }).then(()=>{},err=>{ 224 | console.warn(err); 225 | }); 226 | }); 227 | },err=>{ 228 | console.warn(err); 229 | }); 230 | } 231 | if(m.inspectMe){ 232 | browser.tabs.executeScript(s.tab.id,{ 233 | file: "/inspect.js", 234 | runAt:"document_end" 235 | }).then(()=>{ 236 | browser.tabs.sendMessage(s.tab.id,{ 237 | "initInspect":true, 238 | "dialogTabId":m.dialogTabId 239 | }).then(()=>{},err=>{ 240 | console.warn(err); 241 | }); 242 | },err=>{ 243 | console.error(err); 244 | browser.tabs.sendMessage(s.tab.id,{ 245 | "initInspect":true, 246 | "dialogTabId":m.dialogTabId 247 | }).then(()=>{},err=>{ 248 | console.warn(err); 249 | }); 250 | }); 251 | browser.tabs.insertCSS(s.tab.id,{ 252 | file: "/inspect.css", 253 | runAt:"document_end" 254 | }).then(()=>{},err=>{ 255 | console.error(err); 256 | }); 257 | } 258 | if(m.returnToDialogTab){ 259 | browser.tabs.remove(s.tab.id).then(()=>{ 260 | browser.tabs.sendMessage(m.dialogTabId,{ 261 | "changeSelector":true, 262 | "selector":m.cssSelector 263 | }).then(()=>{},err=>{ 264 | console.warn(err); 265 | }); 266 | browser.tabs.update(m.dialogTabId,{ 267 | active:true 268 | }) 269 | }); 270 | } 271 | if(m.editThis){editSite(m.id,m.url,m.title,m.mode,m.freq,m.charset,m.cssSelector,m.ignoreNumbers,m.ignoreHrefs,m.deleteScripts,m.deleteComments,m.pageSettings,m.ignoreStyles,m.ignoreAllAttributes,m.saveOnlyPart);} 272 | if(m.executeCustom){ 273 | browser.tabs.executeScript(s.tab.id,{ 274 | file:"/custom.js" 275 | }).then(()=>{},err=>{ 276 | console.error(err); 277 | }); 278 | } 279 | if(m.byBG){ 280 | browser.tabs.sendMessage(s.tab.id,m).then(()=>{},err=>{console.warn(err);}); 281 | } 282 | if(m.openViewPage){browser.tabs.create({url:`${extURL}view.html?${m.viewId}`});} 283 | if(m.convertDB){convertDb(true);} 284 | if(m.getChanges){return getChanges(m.index);} 285 | if(m.getAllChanges){return getAllChanges();} 286 | if(m.setChanges){return setChanges(m.record);} 287 | if(m.deleteChanges){return deleteChanges(m.index);} 288 | if(m.clearChanges){return clearChanges();} 289 | } 290 | 291 | function showContext(e){ 292 | if(e){ 293 | browser.contextMenus.create({ 294 | id: "addThis", 295 | title: i18n("addThis"), 296 | contexts: ["page","tab"], 297 | onclick: contextAdd, 298 | documentUrlPatterns: [""] 299 | }); 300 | }else 301 | browser.contextMenus.remove("addThis"); 302 | } 303 | 304 | function contextAdd(e,tab){ 305 | if(e.viewType==="tab"){ 306 | showPopup(); 307 | }else{ 308 | browser.tabs.update(tab.id,{ 309 | active:true 310 | }).then(()=>{ 311 | showPopup(); 312 | }); 313 | } 314 | } 315 | 316 | function openSitesDelay(openWindow){ 317 | if(delayCurrentId{ 322 | lastWindowId=win.id; 323 | delayCurrentId++; 324 | browser.alarms.create("openSitesDelay",{delayInMinutes:delayTime/60}); 325 | }); 326 | }else if(lastWindowId>=0){ 327 | browser.tabs.create({ 328 | url:`${extURL}view.html?${delayLinksId[delayCurrentId]}`, 329 | active:false, 330 | windowId:lastWindowId 331 | }).then(tab=>{ 332 | delayCurrentId++; 333 | browser.alarms.create("openSitesDelay",{delayInMinutes:delayTime/60}); 334 | },err=>{ 335 | openSitesDelay(true); 336 | }); 337 | }else{ 338 | browser.tabs.create({ 339 | url:`${extURL}view.html?${delayLinksId[delayCurrentId]}`, 340 | active:false 341 | }).then(tab=>{ 342 | delayCurrentId++; 343 | browser.alarms.create("openSitesDelay",{delayInMinutes:delayTime/60}); 344 | }); 345 | } 346 | updateBadge(-1); 347 | unchange([delayLinksId[delayCurrentId]]); 348 | browser.runtime.sendMessage({ 349 | "unchangeItem":true, 350 | "unchangeItemId":[delayLinksId[delayCurrentId]] 351 | }).then(()=>{},err=>{ 352 | console.warn(err); 353 | }); 354 | }else{ 355 | delayLinksId=[]; 356 | lastWindowId=-1; 357 | } 358 | } 359 | 360 | function showPopup(mode="add",editId){ 361 | const code=` 362 | (function(){ 363 | if(!document.getElementById("__wps_pageSettings")&&(("${mode}"==="add"&&this.location.protocol.startsWith("http"))||("${mode}"==="edit"&&this.location.protocol==="moz-extension:"))){ 364 | let popup=document.createElement("wps-popup"); 365 | popup.id="__wps_pageSettings"; 366 | popup.setAttribute("editId","${editId}"); 367 | popup.setAttribute("mode","${mode}"); 368 | document.documentElement.appendChild(popup); 369 | } 370 | })(); 371 | `; 372 | browser.tabs.executeScript({ 373 | file:"/custom.js" 374 | }).then(()=>{ 375 | browser.tabs.executeScript({ 376 | code:code 377 | }).then(()=>{},err=>{ 378 | console.error(err); 379 | if(mode!=="edit"){ 380 | browser.tabs.query({active:true}).then(tab=>{ 381 | rqstAdd(tab.url,tab.title,tab.favIconUrl); 382 | }); 383 | } 384 | }); 385 | },err=>{ 386 | console.error(err); 387 | if(mode==="add"){ 388 | browser.tabs.query({currentWindow:true,active:true}).then(tabs=>{ 389 | const tab=tabs[0]; 390 | if(tab.url.startsWith("http")){ 391 | browser.tabs.create({url:`${extURL}dialog.html?onEmptyTab&add&tabId=${tab.id}`}); 392 | }else{ 393 | browser.tabs.create({url:`${extURL}dialog.html?onEmptyTab&add`}); 394 | } 395 | }); 396 | }else{ 397 | browser.tabs.create({url:`${extURL}dialog.html?onEmptyTab&edit&editId=${editId}`}); 398 | } 399 | }); 400 | } 401 | 402 | function editSite(id,url,title,mode,freq,charset,cssSelector,ignoreNumbers,ignoreHrefs,deleteScripts,deleteComments,pageSettings,ignoreStyles,ignoreAllAttributes,saveOnlyPart){ 403 | browser.storage.local.get("sites").then(async result=>{ 404 | let sites=result.sites; 405 | const uniqId=sites[id].uniq; 406 | let obj={ 407 | url, 408 | title, 409 | mode, 410 | freq, 411 | charset, 412 | paritialMode:(cssSelector!==false)?true:false, 413 | cssSelector:(cssSelector!==false)?cssSelector:"", 414 | ignoreNumbers, 415 | ignoreHrefs, 416 | ignoreStyles, 417 | ignoreAllAttributes, 418 | deleteScripts, 419 | deleteComments, 420 | saveOnlyPart, 421 | }; 422 | const old={ 423 | paritialMode:sites[id].paritialMode, 424 | cssSelector :sites[id].cssSelector, 425 | ignoreNumbers:sites[id].ignoreNumbers, 426 | ignoreHrefs :sites[id].ignoreHrefs, 427 | ignoreStyles :sites[id].ignoreStyles, 428 | ignoreAllAttributes:sites[id].ignoreAllAttributes, 429 | }; 430 | if(old.paritialMode!==obj.paritialMode||old.cssSelector!==obj.cssSelector||old.ignoreNumbers!==ignoreNumbers||old.ignoreHrefs!==ignoreHrefs||old.ignoreStyles!==ignoreStyles||old.ignoreAllAttributes!==ignoreAllAttributes){ 431 | const idb=await getChanges(uniqId); 432 | const html_data=idb.html; 433 | if(cssSelector===false){ 434 | Object.assign(obj,length_md5(html_data,ignoreNumbers,ignoreHrefs,ignoreStyles,ignoreAllAttributes)); 435 | }else{ 436 | let parser=new DOMParser(), 437 | doc=parser.parseFromString(html_data,"text/html"), 438 | selectedElement=doc.querySelector(cssSelector); 439 | if(selectedElement){ 440 | let partHTML=selectedElement.outerHTML; 441 | Object.assign(obj,length_md5(partHTML,ignoreNumbers,ignoreHrefs,ignoreStyles,ignoreAllAttributes)); 442 | }else{ 443 | Object.assign(obj,length_md5(html_data,ignoreNumbers,ignoreHrefs,ignoreStyles,ignoreAllAttributes)); 444 | } 445 | } 446 | } 447 | Object.assign(obj,{settings:pageSettings}); 448 | Object.assign(sites[id],obj); 449 | browser.storage.local.set({sites}).then(()=>{ 450 | browser.runtime.sendMessage({ 451 | "statusbar":true, 452 | "statusbarArg":i18n("savedWebpage",sites[id].title), 453 | "listSite":true, 454 | "reload":true, 455 | "reloadId":id, 456 | }).then(()=>{},err=>{ 457 | console.warn(err); 458 | }); 459 | },err=>{ 460 | console.error(err); 461 | }); 462 | },err=>{ 463 | console.error(err); 464 | }); 465 | } 466 | 467 | async function convertDb(e){ 468 | if(!db)await getDB(); 469 | browser.storage.local.get(["sites","changes"]).then(async result=>{ 470 | const {sites,changes}=result; 471 | sites.forEach((site,i)=>{ 472 | if(!site.uniq)site.uniq=uniqueId(); 473 | }); 474 | await browser.storage.local.set({sites}); 475 | const tx=db.transaction(["changes"],"readwrite"); 476 | const store=tx.objectStore("changes"); 477 | tx.oncomplete=(e)=>{ 478 | browser.storage.local.set({dbVersion:1}).then(()=>{ 479 | browser.storage.local.remove("changes"); 480 | if(!e)init(); 481 | browser.runtime.sendMessage({"listSite":true}).then(()=>{},err=>{console.warn(err);}); 482 | },err=>{ 483 | console.error(err); 484 | }); 485 | }; 486 | tx.onerror=(e)=>{ 487 | console.error(e.target.error); 488 | }; 489 | sites.forEach((site,i)=>{ 490 | changes[i].uniq=site.uniq; 491 | store.add(changes[i]); 492 | }); 493 | }); 494 | } 495 | -------------------------------------------------------------------------------- /src/custom.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | (function(){ 4 | let customDefined=customElements.get('wps-popup'); 5 | if(!customDefined){ 6 | class wpsPopup extends HTMLElement{ 7 | static get observedAttributes() { 8 | return ["mode"]; 9 | } 10 | constructor(){ 11 | super(); 12 | const shadow=this.attachShadow({mode:"open"}); 13 | const style=document.createElement("style"); 14 | style.textContent="iframe{height:100%;width:100%;display:block;position:fixed;top:0;left:0;border:0;z-index:2147483647;}"; 15 | shadow.appendChild(style); 16 | } 17 | attributeChangedCallback() { 18 | const iframe=document.createElement("iframe"); 19 | const mode=this.getAttribute("mode"); 20 | const editId=this.getAttribute("editId"); 21 | const selector=this.getAttribute("selector"); 22 | const dialogTabId=this.getAttribute("dialogTabId"); 23 | const extURL=browser.runtime.getURL(""); 24 | if(mode==="edit"){ 25 | iframe.src=`${extURL}dialog.html?onViewTab&edit&editId=${editId}`; 26 | }else if(mode==="add"){ 27 | iframe.src=`${extURL}dialog.html?add&charset=${document.charset}`; 28 | } if(mode==="inspect"){ 29 | iframe.src=`${extURL}inspectDialog.html?dialogTabId=${dialogTabId}&selector=${selector}`; 30 | } 31 | this.shadowRoot.appendChild(iframe); 32 | } 33 | } 34 | customElements.define('wps-popup', wpsPopup); 35 | } 36 | })(); 37 | -------------------------------------------------------------------------------- /src/database.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let db,mode; 4 | 5 | function getDB(){ 6 | if(mode!==undefined)return mode; 7 | const request=indexedDB.open("WPS"); 8 | return new Promise((resolve,reject)=>{ 9 | request.onerror=(e)=>{ 10 | console.warn(e.target.error); 11 | mode=false; 12 | resolve(false); 13 | }; 14 | request.onsuccess=(e)=>{ 15 | db=e.target.result; 16 | mode=true; 17 | resolve(true); 18 | }; 19 | request.onupgradeneeded=(e)=>{ 20 | db=e.target.result; 21 | db.createObjectStore("changes",{keyPath:"uniq"}); 22 | }; 23 | }); 24 | } 25 | 26 | async function getChanges(index){ 27 | if(await getDB()){ 28 | const tx=db.transaction("changes","readonly"); 29 | const store=tx.objectStore("changes"); 30 | const request=store.get(index); 31 | return new Promise((resolve,reject)=>{ 32 | tx.onerror=(e)=>{ 33 | console.error(e.target.error); 34 | }; 35 | request.onsuccess=(e)=>{ 36 | resolve(e.target.result); 37 | }; 38 | }); 39 | }else{ 40 | return await browser.runtime.sendMessage({ 41 | "getChanges":true, 42 | "index":index 43 | }); 44 | } 45 | } 46 | 47 | async function getAllChanges(){ 48 | if(await getDB()){ 49 | const tx=db.transaction("changes","readonly"); 50 | const store=tx.objectStore("changes"); 51 | const request=store.getAll(); 52 | return new Promise((resolve,reject)=>{ 53 | tx.onerror=(e)=>{ 54 | console.error(e.target.error); 55 | }; 56 | request.onsuccess=(e)=>{ 57 | resolve(e.target.result); 58 | }; 59 | }); 60 | }else{ 61 | return await browser.runtime.sendMessage({ 62 | "getAllChanges":true 63 | }); 64 | } 65 | } 66 | 67 | async function setChanges(data){ 68 | if(await getDB()){ 69 | const tx=db.transaction("changes","readwrite"); 70 | const store=tx.objectStore("changes"); 71 | store.put(data); 72 | return new Promise((resolve,reject)=>{ 73 | tx.onerror=(e)=>{ 74 | console.error(e.target.error); 75 | }; 76 | tx.oncomplete=(e)=>{ 77 | resolve(true); 78 | }; 79 | }); 80 | }else{ 81 | return await browser.runtime.sendMessage({ 82 | "setChanges":true, 83 | "record":data 84 | }); 85 | } 86 | } 87 | 88 | async function deleteChanges(index){ 89 | if(await getDB()){ 90 | const tx=db.transaction("changes","readwrite"); 91 | const store=tx.objectStore("changes"); 92 | store.delete(index); 93 | return new Promise((resolve,reject)=>{ 94 | tx.onerror=(e)=>{ 95 | console.error(e.target.error); 96 | }; 97 | tx.oncomplete=(e)=>{ 98 | resolve(true); 99 | }; 100 | }); 101 | }else{ 102 | return await browser.runtime.sendMessage({ 103 | "deleteChanges":true, 104 | "index":index 105 | }); 106 | } 107 | } 108 | 109 | async function clearChanges(){ 110 | if(await getDB()){ 111 | const tx=db.transaction("changes","readwrite"); 112 | const store=tx.objectStore("changes"); 113 | store.clear(); 114 | return new Promise((resolve,reject)=>{ 115 | tx.onerror=(e)=>{ 116 | console.error(e.target.error); 117 | resolve(false); 118 | }; 119 | tx.oncomplete=(e)=>{ 120 | resolve(true); 121 | }; 122 | }); 123 | }else{ 124 | return await browser.runtime.sendMessage({ 125 | "clearChanges":true 126 | }); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/dialog.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --text-color:#15141a; 3 | --border-color:#d7d7db; 4 | --background-color:#fff; 5 | --titlebar-background:#fff; 6 | --icon:url("icons/icon.svg"); 7 | --overlay-background:#00000080; 8 | --select:url("icons/select.svg#l"); 9 | --message-background:#f0f0f4; 10 | --message-image:url("icons/information.svg#l"); 11 | } 12 | 13 | .dark:root { 14 | --text-color:#fbfbfe; 15 | --border-color:#676670; 16 | --background-color:#1c1b22; 17 | --titlebar-background:#42414d; 18 | --icon:url("icons/icon.svg#w"); 19 | --overlay-background:#000c; 20 | --select:url("icons/select.svg#d"); 21 | --message-background:#3d3c43; 22 | --message-image:url("icons/information.svg#d"); 23 | } 24 | 25 | @media (prefers-color-scheme: dark) { 26 | .auto:root { 27 | --text-color:#fbfbfe; 28 | --border-color:#676670; 29 | --background-color:#1c1b22; 30 | --titlebar-background:#42414d; 31 | --icon:url("icons/icon.svg#w"); 32 | --overlay-background:#000c; 33 | --select:url("icons/select.svg#d"); 34 | --message-background:#3d3c43; 35 | --message-image:url("icons/information.svg#d"); 36 | } 37 | } 38 | 39 | *:-moz-focusring{ 40 | outline:none; 41 | } 42 | 43 | html, 44 | body{ 45 | height:100%; 46 | margin:0; 47 | padding:0; 48 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 49 | font-size:14px; 50 | color:var(--text-color); 51 | } 52 | 53 | body{ 54 | opacity:1; 55 | transform:scale(1); 56 | transition:opacity 200ms, transform 160ms; 57 | } 58 | 59 | h1{ 60 | font-size:14px; 61 | font-weight:600; 62 | line-height:36px; 63 | margin:0; 64 | } 65 | 66 | h2{ 67 | font-size:15px; 68 | font-weight:600; 69 | line-height:21px; 70 | margin:0 0 6px 0; 71 | } 72 | 73 | input[type="text"], 74 | input[type="number"], 75 | select{ 76 | margin:0; 77 | } 78 | 79 | label{ 80 | white-space:nowrap; 81 | display:inline-block; 82 | line-height:24px; 83 | } 84 | 85 | .disabled{ 86 | opacity:.4; 87 | } 88 | 89 | *[disabled]{ 90 | pointer-events:none; 91 | } 92 | 93 | #pageSettingsDialog{ 94 | background:var(--background-color); 95 | border:1px solid var(--border-color); 96 | border-radius:8px; 97 | box-shadow:0 0 0 2000px var(--overlay-background); 98 | padding:0 20px 15px 20px; 99 | position:fixed; 100 | box-sizing:border-box; 101 | z-index:2147483647; 102 | display:grid; 103 | grid-template-columns:400px calc(100% - 420px); 104 | grid-column-gap:20px; 105 | grid-row-gap:10px; 106 | align-items:start; 107 | top:calc(50% - ( 608px / 2 )); 108 | left:calc(50% - 400px); 109 | width:800px; 110 | } 111 | 112 | #propertiesSection{ 113 | display:grid; 114 | grid-template-columns:min-content auto; 115 | grid-row-gap:6px; 116 | grid-column-gap:6px; 117 | align-items:center; 118 | } 119 | 120 | #propertiesSection h2, 121 | #propertiesSection .row{ 122 | grid-column:1 / 3; 123 | } 124 | 125 | #scanFreqInput{ 126 | width:50%; 127 | border-radius:4px 0 0 4px; 128 | } 129 | 130 | #unitInput{ 131 | width:50%; 132 | border-left:none; 133 | border-radius:0 4px 4px 0; 134 | } 135 | 136 | #inspectButtonInput{ 137 | height:33px; 138 | width:33px; 139 | box-sizing:border-box; 140 | padding:9px 8px 8px 9px; 141 | vertical-align:bottom; 142 | margin-left:4px; 143 | background-image:var(--select); 144 | background-repeat:no-repeat; 145 | background-position:center; 146 | } 147 | 148 | #cssSelectorInput{ 149 | width:calc(100% - 37px); 150 | } 151 | 152 | #optionsSection .row{ 153 | display:flex; 154 | flex-flow:row; 155 | align-items:center; 156 | padding-top:6px; 157 | } 158 | 159 | #optionsSection .row label{ 160 | padding-right:8px; 161 | } 162 | 163 | .radio { 164 | display:grid; 165 | grid-template-columns:20px auto 20px auto 20px auto; 166 | grid-template-rows:auto 28px; 167 | } 168 | 169 | #optionsSection .radio>label:first-child{ 170 | grid-column:1/7; 171 | grid-row:1/2; 172 | white-space:break-spaces; 173 | padding-top:3px; 174 | padding-bottom:3px; 175 | } 176 | 177 | #optionsSection input[type="radio"] + label{ 178 | padding-left:8px; 179 | } 180 | 181 | .popupFooter{ 182 | float:right; 183 | grid-column:2/3; 184 | justify-self:right; 185 | } 186 | 187 | #titlebar{ 188 | grid-column: 1/3; 189 | background-color:var(--titlebar-background); 190 | background-image:var(--icon); 191 | background-repeat:no-repeat; 192 | height:36px; 193 | display:block; 194 | background-size: 24px 24px; 195 | background-position: 6px 6px; 196 | border-bottom:1px solid var(--border-color); 197 | margin:0 -20px; 198 | text-align:center; 199 | border-radius:8px 8px 0 0; 200 | } 201 | 202 | .fade{ 203 | opacity:0; 204 | transform:scale(.6); 205 | transition:opacity 200ms, transform 160ms; 206 | } 207 | 208 | .hidden{ 209 | display:none !important; 210 | } 211 | 212 | #messageBar{ 213 | z-index:2147483647; 214 | width: 800px; 215 | position: fixed; 216 | left: calc(50% - 400px); 217 | top: calc(50% + ( 608px / 2 ) + 4px); 218 | box-sizing: border-box; 219 | border-radius:6px; 220 | font-size:13px; 221 | line-height:24px; 222 | padding:4px 4px 4px 32px; 223 | } 224 | 225 | #messageButton{ 226 | min-height:24px; 227 | height:24px; 228 | font-size:11px; 229 | padding:0 8px; 230 | min-width:initial; 231 | margin-left:8px; 232 | } 233 | 234 | #messageBar.info{ 235 | background-color:var(--message-background); 236 | background-image:var(--message-image); 237 | background-repeat:no-repeat; 238 | background-position:8px center; 239 | background-size:16px; 240 | color:var(--text-color); 241 | border:1px solid var(--border-color); 242 | } 243 | -------------------------------------------------------------------------------- /src/dialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |

12 |
13 |

14 | 15 | 16 | 17 | 18 | 25 | 26 | 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 |
43 |
44 |

45 |
46 | 56 |
57 |
58 | 59 | 62 |
63 |
64 | 65 | 68 |
69 |
70 | 71 | 74 |
75 |
76 | 77 | 80 |
81 |
82 | 83 | 86 |
87 |
88 | 89 | 92 |
93 |
94 |
95 | 98 |
99 |
100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /src/dialog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let tabIcon, 4 | thisTabId, 5 | onEmptyTab, 6 | onViewTab, 7 | editId, 8 | modeEdit, 9 | modeAdd, 10 | prevTabId; 11 | 12 | (async function(){ 13 | const result=browser.storage.local.get(["sites","settings"]); 14 | const returnMessage=browser.runtime.sendMessage({"tabInfo":true}); 15 | 16 | const urlParams=new URLSearchParams(window.location.search); 17 | onEmptyTab=urlParams.has("onEmptyTab"); 18 | onViewTab=urlParams.has("onViewTab"); 19 | editId=urlParams.get("editId")*1; 20 | modeEdit=urlParams.has("edit"); 21 | modeAdd=urlParams.has("add"); 22 | prevTabId=urlParams.has("tabId")?urlParams.get("tabId")*1:false; 23 | 24 | translate(); 25 | 26 | const {sites,settings}=await result; 27 | document.documentElement.className=settings.theme?settings.theme:"auto"; 28 | document.body.removeAttribute("class"); 29 | 30 | const {tab}=await returnMessage; 31 | tabIcon=tab.favIconUrl; 32 | thisTabId=tab.id; 33 | 34 | let url,title,charset,freq,mode,ignoreNumbers,ignoreHrefs,ignoreStyles,ignoreAllAttributes,deleteScripts,deleteComments,paritialMode,selectorCSS,saveOnlyPart; 35 | if(onEmptyTab&&modeAdd){ 36 | if(prevTabId!==false){ 37 | document.getElementById("fillForm").classList.remove("hidden"); 38 | } 39 | url =""; 40 | title =""; 41 | charset =settings.charset; 42 | freq =settings.defaultFreq; 43 | mode =settings.defaultMode; 44 | ignoreNumbers =settings.defaultIgnoreNumbers; 45 | ignoreHrefs =settings.defaultIgnoreHrefs; 46 | ignoreStyles =settings.defaultIgnoreStyles; 47 | ignoreAllAttributes=settings.defaultIgnoreAllAttributes; 48 | deleteScripts =settings.defaultDeleteScripts; 49 | deleteComments =settings.defaultDeleteComments; 50 | paritialMode =false; 51 | selectorCSS =""; 52 | saveOnlyPart =settings.defaultSaveOnlyPart; 53 | }else if(modeEdit){ 54 | url =sites[editId].url; 55 | title =sites[editId].title; 56 | charset =sites[editId].charset; 57 | freq =sites[editId].freq; 58 | mode =sites[editId].mode; 59 | ignoreNumbers =sites[editId].ignoreNumbers; 60 | ignoreHrefs =sites[editId].ignoreHrefs; 61 | ignoreStyles =sites[editId].ignoreStyles; 62 | ignoreAllAttributes=sites[editId].ignoreAllAttributes; 63 | deleteScripts =sites[editId].deleteScripts; 64 | deleteComments =sites[editId].deleteComments; 65 | paritialMode =sites[editId].paritialMode; 66 | selectorCSS =sites[editId].cssSelector; 67 | saveOnlyPart =sites[editId].saveOnlyPart; 68 | const pageSettings=sites[editId].settings; 69 | if(pageSettings){ 70 | document.getElementById("defaultView").value=pageSettings.defaultView; 71 | document.querySelector(`input[name="hideHeader"][value="${pageSettings.hideHeader}"]`).checked=true; 72 | document.querySelector(`input[name="showNextPrev"][value="${pageSettings.showNextPrev}"]`).checked=true; 73 | document.querySelector(`input[name="scrollToFirstChange"][value="${pageSettings.scrollToFirstChange}"]`).checked=true; 74 | document.querySelector(`input[name="skipMinorChanges"][value="${pageSettings.skipMinorChanges}"]`).checked=true; 75 | document.querySelector(`input[name="highlightOutsideChanges"][value="${pageSettings.highlightOutsideChanges}"]`).checked=true; 76 | document.querySelector(`input[name="scrollbarMarkers"][value="${pageSettings.scrollbarMarkers}"]`).checked=true; 77 | } 78 | }else{ 79 | url =tab.url; 80 | title =tab.title; 81 | charset =urlParams.get("charset"); 82 | freq =settings.defaultFreq; 83 | mode =settings.defaultMode; 84 | ignoreNumbers =settings.defaultIgnoreNumbers; 85 | ignoreHrefs =settings.defaultIgnoreHrefs; 86 | ignoreStyles =settings.defaultIgnoreStyles; 87 | ignoreAllAttributes=settings.defaultIgnoreAllAttributes; 88 | deleteScripts =settings.defaultDeleteScripts; 89 | deleteComments =settings.defaultDeleteComments; 90 | paritialMode =false; 91 | selectorCSS =""; 92 | saveOnlyPart =settings.defaultSaveOnlyPart; 93 | 94 | const duplicates=[]; 95 | sites.forEach((v,i)=>{ 96 | if(v.url===url){ 97 | duplicates.push(i); 98 | } 99 | }); 100 | if(duplicates.length){ 101 | const messageBar=document.getElementById("messageBar"); 102 | const messageText=document.getElementById("messageText"); 103 | const messageButton=document.getElementById("messageButton"); 104 | messageText.textContent=i18n("duplicateMessage2"); 105 | messageButton.textContent=i18n("show"); 106 | messageButton.addEventListener("click",()=>{ 107 | duplicates.forEach(id=>{ 108 | browser.runtime.sendMessage({"openViewPage":true,"viewId":id}).then(()=>{},err=>{console.warn(err);}); 109 | }); 110 | }); 111 | messageBar.classList.remove("hidden"); 112 | } 113 | } 114 | 115 | document.getElementById("urlInput").value=url; 116 | document.getElementById("titleInput").value=title; 117 | document.getElementById("charsetInput").value=charset||settings.charset; 118 | let unit; 119 | if(!(freq%168)) 120 | unit=168; 121 | else if(!(freq%24)) 122 | unit=24; 123 | else if(freq<1) 124 | unit=0.0166667; 125 | else 126 | unit=1; 127 | document.getElementById("scanFreqInput").value=parseInt(freq/unit); 128 | document.getElementById("unitInput").value=unit; 129 | document.getElementById("modeInput").value=mode; 130 | document.getElementById("ignoreNumbersInput").checked=ignoreNumbers; 131 | document.getElementById("ignoreHrefsInput").checked=ignoreHrefs; 132 | document.getElementById("ignoreStylesInput").checked=ignoreStyles; 133 | document.getElementById("ignoreAllAttributesInput").checked=ignoreAllAttributes; 134 | document.getElementById("deleteScriptsInput").checked=deleteScripts; 135 | document.getElementById("deleteCommentsInput").checked=deleteComments; 136 | toggleSelector(paritialMode); 137 | document.getElementById("paritialModeInput").checked=paritialMode; 138 | document.getElementById("cssSelectorInput").value=selectorCSS===undefined?"":selectorCSS; 139 | document.getElementById("saveOnlyPartInput").checked=saveOnlyPart; 140 | document.getElementById("editOk").addEventListener("click",saveSite); 141 | document.getElementById("editCancel").addEventListener("click",e=>{ 142 | if(onEmptyTab){ 143 | browser.runtime.sendMessage({"closeTab":true}).then(()=>{},err=>{console.warn(err);}); 144 | }else{ 145 | browser.runtime.sendMessage({"deleteWpsPopup":true}).then(()=>{},err=>{console.warn(err);}); 146 | } 147 | }); 148 | document.getElementById("paritialModeInput").addEventListener("change",e=>{ 149 | toggleSelector(e.target.checked); 150 | }); 151 | document.getElementById("inspectButtonInput").addEventListener("click",inspect); 152 | document.getElementById("fillForm").addEventListener("click",fillForm); 153 | })(); 154 | 155 | function saveSite(){ 156 | const url=document.getElementById("urlInput").value, 157 | title=document.getElementById("titleInput").value, 158 | charset=document.getElementById("charsetInput").value, 159 | favicon=tabIcon||false, 160 | mode=document.getElementById("modeInput").value, 161 | aFreq=parseInt(document.getElementById("scanFreqInput").value), 162 | freq=aFreq>0?aFreq*parseFloat(document.getElementById("unitInput").value):8, 163 | cssSelector=(document.getElementById("paritialModeInput").checked&&document.getElementById("cssSelectorInput").value.length)?document.getElementById("cssSelectorInput").value:false, 164 | saveOnlyPart=(document.getElementById("paritialModeInput").checked&&document.getElementById("cssSelectorInput").value.length)?document.getElementById("saveOnlyPartInput").checked:false, 165 | ignoreNumbers=document.getElementById("ignoreNumbersInput").checked, 166 | deleteScripts=document.getElementById("deleteScriptsInput").checked, 167 | deleteComments=document.getElementById("deleteCommentsInput").checked, 168 | ignoreHrefs=document.getElementById("ignoreHrefsInput").checked, 169 | ignoreStyles=document.getElementById("ignoreStylesInput").checked, 170 | ignoreAllAttributes=document.getElementById("ignoreAllAttributesInput").checked; 171 | const pageSettings={ 172 | defaultView: document.getElementById("defaultView").value, 173 | hideHeader: getRadioValue("hideHeader"), 174 | showNextPrev: getRadioValue("showNextPrev"), 175 | scrollToFirstChange: getRadioValue("scrollToFirstChange"), 176 | skipMinorChanges: getRadioValue("skipMinorChanges"), 177 | highlightOutsideChanges: getRadioValue("highlightOutsideChanges"), 178 | scrollbarMarkers: getRadioValue("scrollbarMarkers"), 179 | } 180 | 181 | let message; 182 | if(modeEdit){ 183 | message={"editThis":true,"id":editId,url,title,mode,freq,cssSelector,ignoreNumbers,deleteScripts,deleteComments,ignoreHrefs,charset,pageSettings,ignoreStyles,ignoreAllAttributes,saveOnlyPart}; 184 | }else{ 185 | message={"addThis":true,url,title,favicon,mode,freq,cssSelector,ignoreNumbers,deleteScripts,deleteComments,ignoreHrefs,charset,pageSettings,ignoreStyles,ignoreAllAttributes,saveOnlyPart}; 186 | } 187 | browser.runtime.sendMessage(message).then(()=>{ 188 | if(onEmptyTab){ 189 | browser.runtime.sendMessage({"closeTab":true}).then(()=>{},err=>{console.warn(err);}); 190 | }else{ 191 | browser.runtime.sendMessage({"deleteWpsPopup":true}).then(()=>{},err=>{console.warn(err);}); 192 | } 193 | },err=>{ 194 | console.warn(err); 195 | }); 196 | } 197 | 198 | function getRadioValue(e){ 199 | if(document.getElementById(e+"True").checked)return true; 200 | else if(document.getElementById(e+"False").checked)return false; 201 | return "global"; 202 | } 203 | 204 | function fillForm(){ 205 | browser.tabs.get(prevTabId).then(tab=>{ 206 | document.getElementById("urlInput").value=tab.url; 207 | document.getElementById("titleInput").value=tab.title; 208 | tabIcon=tab.favIconUrl; 209 | }); 210 | } 211 | 212 | function toggleSelector(paritial){ 213 | if(paritial){ 214 | document.getElementById("cssSelectorLabel").removeAttribute("class"); 215 | document.getElementById("spanSelectorInput").removeAttribute("class"); 216 | document.getElementById("saveOnlyPartInput").removeAttribute("class"); 217 | document.getElementById("saveOnlyPartLabel").removeAttribute("class"); 218 | }else{ 219 | document.getElementById("cssSelectorLabel").className="disabled"; 220 | document.getElementById("spanSelectorInput").className="disabled"; 221 | document.getElementById("saveOnlyPartInput").className="disabled"; 222 | document.getElementById("saveOnlyPartLabel").className="disabled"; 223 | } 224 | document.getElementById("cssSelectorInput").disabled=!paritial; 225 | document.getElementById("inspectButtonInput").disabled=!paritial; 226 | document.getElementById("saveOnlyPartInput").disabled=!paritial; 227 | document.getElementById("saveOnlyPartLabel").disabled=!paritial; 228 | } 229 | 230 | function i18n(e,s1){ 231 | return browser.i18n.getMessage(e,s1); 232 | } 233 | 234 | function translate(){ 235 | if(modeAdd){ 236 | document.title=i18n("extensionName")+" - "+i18n("addWebpage"); 237 | document.getElementById("pageSettingsH2").textContent=i18n("addWebpage"); 238 | document.getElementById("editOk").textContent=i18n("add"); 239 | }else{ 240 | document.title=i18n("extensionName")+" - "+i18n("editWebpage"); 241 | document.getElementById("pageSettingsH2").textContent=i18n("editWebpage"); 242 | document.getElementById("editOk").textContent=i18n("save"); 243 | } 244 | document.getElementById("titlebarH1").textContent=i18n("extensionName"); 245 | document.getElementById("urlLabel").textContent=i18n("address"); 246 | document.getElementById("titleLabel").textContent=i18n("title"); 247 | document.getElementById("charsetLabel").textContent=i18n("charset"); 248 | document.getElementById("scanFreqLabel").textContent=i18n("scanFreq"); 249 | document.getElementById("modeLabel").textContent=i18n("modeTitle"); 250 | let selectFreq=document.getElementById("unitInput").options; 251 | selectFreq[0].text=i18n("minutes"); 252 | selectFreq[1].text=i18n("hours"); 253 | selectFreq[2].text=i18n("days"); 254 | selectFreq[3].text=i18n("weeks"); 255 | let selectMode=document.getElementById("modeInput").options; 256 | selectMode[0].text=i18n("modeM0"); 257 | selectMode[1].text=i18n("modeM3"); 258 | selectMode[2].text=i18n("modeM4"); 259 | selectMode[3].text=i18n("modeM1"); 260 | selectMode[4].text=i18n("modeM2"); 261 | document.getElementById("ignoreNumbersLabel").textContent=i18n("ignoreNumbers"); 262 | document.getElementById("ignoreHrefsLabel").textContent=i18n("ignoreHrefs"); 263 | document.getElementById("ignoreStylesLabel").textContent=i18n("ignoreStyles"); 264 | document.getElementById("ignoreAllAttributesLabel").textContent=i18n("ignoreAllAttributes"); 265 | document.getElementById("deleteScriptsLabel").textContent=i18n("deleteScripts"); 266 | document.getElementById("deleteCommentsLabel").textContent=i18n("deleteComments"); 267 | document.getElementById("paritialModeLabel").textContent=i18n("paritialMode"); 268 | document.getElementById("cssSelectorLabel").textContent=i18n("selectorCSS"); 269 | document.getElementById("inspectButtonInput").title=i18n("inspectElement"); 270 | document.getElementById("editCancel").textContent=i18n("cancel"); 271 | document.getElementById("optionsH2").textContent=i18n("options"); 272 | document.getElementById("labelDefaultView").textContent=i18n("defaultView"); 273 | let defaultViewSelect=document.getElementById("defaultView").options; 274 | defaultViewSelect[0].text=i18n("highlight"); 275 | defaultViewSelect[1].text=i18n("newElements"); 276 | defaultViewSelect[2].text=i18n("deletedElements"); 277 | defaultViewSelect[3].text=i18n("newVersion"); 278 | defaultViewSelect[4].text=i18n("oldVersion"); 279 | defaultViewSelect[5].text=i18n("rawData"); 280 | defaultViewSelect[6].text=i18n("global"); 281 | document.getElementById("labelHideHeader").textContent=i18n("hideHeader"); 282 | document.getElementById("hideHeaderTrue").nextSibling.textContent=i18n("yes"); 283 | document.getElementById("hideHeaderFalse").nextSibling.textContent=i18n("no"); 284 | document.getElementById("hideHeaderGlobal").nextSibling.textContent=i18n("global"); 285 | document.getElementById("labelShowNextPrev").textContent=i18n("showNextPrev"); 286 | document.getElementById("showNextPrevTrue").nextSibling.textContent=i18n("yes"); 287 | document.getElementById("showNextPrevFalse").nextSibling.textContent=i18n("no"); 288 | document.getElementById("showNextPrevGlobal").nextSibling.textContent=i18n("global"); 289 | document.getElementById("labelScrollToFirstChange").textContent=i18n("scrollToFirstChange"); 290 | document.getElementById("scrollToFirstChangeTrue").nextSibling.textContent=i18n("yes"); 291 | document.getElementById("scrollToFirstChangeFalse").nextSibling.textContent=i18n("no"); 292 | document.getElementById("scrollToFirstChangeGlobal").nextSibling.textContent=i18n("global"); 293 | document.getElementById("labelSkipMinorChanges").textContent=i18n("skipMinorChanges"); 294 | document.getElementById("skipMinorChangesTrue").nextSibling.textContent=i18n("yes"); 295 | document.getElementById("skipMinorChangesFalse").nextSibling.textContent=i18n("no"); 296 | document.getElementById("skipMinorChangesGlobal").nextSibling.textContent=i18n("global"); 297 | document.getElementById("labelHighlightOutsideChanges").textContent=i18n("highlightOutsideChanges"); 298 | document.getElementById("highlightOutsideChangesTrue").nextSibling.textContent=i18n("yes"); 299 | document.getElementById("highlightOutsideChangesFalse").nextSibling.textContent=i18n("no"); 300 | document.getElementById("highlightOutsideChangesGlobal").nextSibling.textContent=i18n("global"); 301 | document.getElementById("labelScrollbarMarkers").textContent=i18n("scrollbarMarkers"); 302 | document.getElementById("scrollbarMarkersTrue").nextSibling.textContent=i18n("yes"); 303 | document.getElementById("scrollbarMarkersFalse").nextSibling.textContent=i18n("no"); 304 | document.getElementById("scrollbarMarkersGlobal").nextSibling.textContent=i18n("global"); 305 | document.getElementById("fillForm").textContent=i18n("fillForm"); 306 | document.getElementById("saveOnlyPartLabel").textContent=i18n("saveOnlyPart"); 307 | } 308 | 309 | function inspect(){ 310 | let wpsURL=document.getElementById("urlInput").value; 311 | if(wpsURL.startsWith("http")){ 312 | browser.runtime.sendMessage({ 313 | "inspectTab":true, 314 | "inspectUrl":wpsURL, 315 | }).then(()=>{},err=>{ 316 | console.warn(err); 317 | }); 318 | } 319 | } 320 | 321 | browser.runtime.onMessage.addListener(run); 322 | function run(m,s){ 323 | if(m.changeSelector){ 324 | document.getElementById("cssSelectorInput").value=m.selector.replace(/+/g,"+"); 325 | } 326 | if(m.fadeOut){ 327 | document.body.className="fade"; 328 | } 329 | if(m.deletedSite){ 330 | if(modeEdit&&editId){ 331 | let dId=m.id*1; 332 | if(dId===editId){ 333 | browser.tabs.getCurrent().then(tab=>{browser.tabs.remove(tab.id);}); 334 | }else if(dId]*>)[\n\f\r\u0020\u0009]*/, 17 | /[<>{}]/, 18 | /( )/, 19 | /<\/a>/, 20 | /<[^>]*>/, 21 | /<[^>]*>|\s/, 22 | //, 23 | /<\/a>/], 24 | aN=[], 25 | aO=[], 26 | iN=n.split(reg[0]).filter(v=>{if(v)return v;}), 27 | iO=o.split(reg[0]).filter(v=>{if(v)return v;}); 28 | iN.forEach(v=>{ 29 | if(!reg[1].test(v)){ 30 | v.split(reg[2]).forEach(w=>{ 31 | aN.push(w); 32 | }); 33 | }else 34 | aN.push(v); 35 | }); 36 | iO.forEach(v=>{ 37 | if(!reg[1].test(v)){ 38 | v.split(reg[2]).forEach(w=>{ 39 | aO.push(w); 40 | }); 41 | }else 42 | aO.push(v); 43 | }); 44 | diff(aO,aN); 45 | let os="", 46 | ns="", 47 | cs=""; 48 | aO.forEach(v=>{ 49 | if(v.text===undefined){ 50 | os+=`${v}`; 51 | } 52 | }); 53 | let openSpan=false, 54 | openA=false; 55 | aN.forEach(v=>{ 56 | if(v.text!==undefined){ 57 | if(openSpan) 58 | ns+=""; 59 | openSpan=false; 60 | ns+=v.text; 61 | if(openA&®[3].test(v.text)){ 62 | ns+=""; 63 | openA=false; 64 | } 65 | }else{ 66 | if(!reg[5].test(v)){ 67 | if(!openSpan) 68 | ns+=""; 69 | openSpan=true; 70 | }else if(reg[6].test(v)){ 71 | if(openSpan) 72 | ns+=""; 73 | openSpan=false; 74 | if(!openA) 75 | ns+=""; 76 | openA=true; 77 | }else if(reg[4].test(v)){ 78 | if(openSpan) 79 | ns+=""; 80 | openSpan=false; 81 | } 82 | ns+=v; 83 | if(reg[7].test(v)){ 84 | if(openA) 85 | ns+=""; 86 | openA=false; 87 | } 88 | cs+=v; 89 | } 90 | }); 91 | return{o:os,n:ns,c:cs}; 92 | } 93 | 94 | function diff(o,n){ 95 | let ns={}, 96 | os={}, 97 | nl=n.length, 98 | ol=o.length; 99 | Object.setPrototypeOf(ns,null); 100 | Object.setPrototypeOf(os,null); 101 | n.forEach((v,i)=>{ 102 | if(ns[v]===undefined) 103 | ns[v]={rows:[],o:null}; 104 | ns[v].rows.push(i); 105 | }); 106 | o.forEach((v,i)=>{ 107 | if(os[v]===undefined) 108 | os[v]={rows:[],n:null}; 109 | os[v].rows.push(i); 110 | }); 111 | for(let i in ns){ 112 | if(ns[i].rows.length===1&&typeof(os[i])!=="undefined"&&os[i].rows.length===1){ 113 | const a=ns[i].rows[0], 114 | b=os[i].rows[0]; 115 | n[a]={text:n[a],row:b}; 116 | o[b]={text:o[b],row:a}; 117 | } 118 | } 119 | for(let i=0;i0;i--){ 126 | if(n[i].text!==undefined&&n[i-1].text===undefined&&n[i].row>0&&o[n[i].row-1].text===undefined&&n[i-1]===o[n[i].row-1]){ 127 | n[i-1]={text:n[i-1],row:n[i].row-1}; 128 | o[n[i].row-1]={text:o[n[i].row-1],row:i-1}; 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/diffOld.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Javascript Diff Algorithm 3 | * By John Resig (http://ejohn.org/) 4 | * Modified by Chu Alan "sprite" 5 | * Modified by Waldemar B. 6 | * 7 | * Released under the MIT license. 8 | * 9 | * More Info: 10 | * http://ejohn.org/projects/javascript-diff-algorithm/ 11 | */ 12 | 13 | function diffString2old(o,n){ 14 | if(!n)return{o:o,n:"",c:""}; 15 | let reg=/[\n\f\r\u0020\u0009]*(<[^>]*>)[\n\f\r\u0020\u0009]*/, 16 | aN=n.split(reg).filter(v=>{if(v)return v;}), 17 | aO=o.split(reg).filter(v=>{if(v)return v;}), 18 | out=diffOld(aO,aN), 19 | os="", 20 | ns="", 21 | cs=""; 22 | out.o.forEach(v=>{ 23 | if(v.text==null){ 24 | os+=`${v}`; 25 | } 26 | }); 27 | out.n.forEach(v=>{ 28 | if(v.text!=null){ 29 | ns+=v.text; 30 | }else{ 31 | ns+=`${v}`; 32 | cs+=v; 33 | } 34 | }); 35 | return{o:os,n:ns,c:cs}; 36 | } 37 | 38 | function diffOld(o,n){ 39 | let ns={}, 40 | os={}, 41 | nl=n.length, 42 | ol=o.length; 43 | n.forEach((v,i)=>{ 44 | if(ns[v]==null) 45 | ns[v]={rows:[],o:null}; 46 | ns[v].rows.push(i); 47 | }); 48 | o.forEach((v,i)=>{ 49 | if(os[v]==null) 50 | os[v]={rows:[],n:null}; 51 | os[v].rows.push(i); 52 | }); 53 | for(let i in ns){ 54 | if(ns[i].rows.length===1&&typeof(os[i])!="undefined"&&os[i].rows.length===1){ 55 | const a=ns[i].rows[0], 56 | b=os[i].rows[0]; 57 | n[a]={text:n[a],row:b}; 58 | o[b]={text:o[b],row:a}; 59 | } 60 | } 61 | for(let i=0;i0;i--){ 68 | if(n[i].text!=null&&n[i-1].text==null&&n[i].row>0&&o[n[i].row-1].text==null&&n[i-1]==o[n[i].row-1]){ 69 | n[i-1]={text:n[i-1],row:n[i].row-1}; 70 | o[n[i].row-1]={text:o[n[i].row-1],row:i-1}; 71 | } 72 | } 73 | return{o:o,n:n}; 74 | } 75 | -------------------------------------------------------------------------------- /src/favicon.js: -------------------------------------------------------------------------------- 1 | function favicon64(url,mode){ 2 | return new Promise((resolve,reject)=>{ 3 | let img=new Image(); 4 | 5 | img.onload=e=>{ 6 | let canvas=document.createElement("canvas"), 7 | ctx=canvas.getContext("2d"); 8 | canvas.width=16; 9 | canvas.height=16; 10 | ctx.drawImage(e.target,0,0,16,16); 11 | let dataURL=canvas.toDataURL(); 12 | if(dataURL==="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACFElEQVQ4ja2TP2vbYBDGs+ZDeMqnyOIhg2dbTbbIqrM08h9oauPaVTFq2hpDaTZTPIQkeJCd4YVYJpVolYARuCUitIOEQWAkQ1KIBUKQkCEWT4cg1U7cqT246b3nx929zy0s/K9YXttZjMbqkTLfpfKvO8pGru2tMgf+KnPgp7JtL891lCLfpaKxemR5bWfxkXgl3ljKFUktlW4Z7z98cZrkHLvtMzTJOVTNRqUqO0lWMHIFUluJN5ZmINFYPZIrkNpG9nD0sdEDkXTIPRNj9xbWhQcAuLy6gdwzwbDCKFMgtWisHgkBRb5LJVnBUDUbRNJBJB2iMoCoDELAxAdO+kOc9oegWcEo8l0qBOS5jlKpys7ERwgI0ru+AwB413cgko4fxi9w7yRniztSQkAq2/ZUzQ6LHoqDDnRzDCLpUDUbTLrlhYAnyX3ftFwAgNwzoZvjGXEQJ/0hiKTDtFxQ63v+DODy6iZsNVjgPICoDGBaLhLTgKeZlqdq9kyxqtlhBnAAGLu3UDUbSVb4M0Ke6yh8VXamAQ/38f3nRfj2ku86z8tTSyy9ERPBN/4NQCQdE/++M3pTMEoVMfHISAwrjKYhpuWGYtNy78XP5hgpsHKmQGo0Kxjl7WNH1Wyc9ofYbZ/hU/MbytufHXpTMDLzrDx9TKWKmNjijhQm3fIoet9PrO/5SVbwXrzqfC2/PY7PPaZ/id9i4TQ7pxqOTwAAAABJRU5ErkJggg=="|| 13 | dataURL==="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAWUlEQVQ4jWNgwAKmTJmyffLkyYeQ8ZQpU7ZjU0tQI9EGEdKIjkm2Ga9L8NlC0BW4bCfGe1OmTNlO2AZCriQlsOhvAFFeoDgQKY5GqiQkipMyKS4hO1fi0ggAjtjR5IvLbM4AAAAASUVORK5CYII="){ 14 | dataURL=nativeFavicon(url); 15 | } 16 | resolve(dataURL); 17 | }; 18 | 19 | img.onerror=()=>{ 20 | resolve(nativeFavicon(url)); 21 | }; 22 | 23 | switch(mode){ 24 | case "google": 25 | img.src=`https://www.google.com/s2/favicons?domain=${url.split("://")[1]}`; 26 | break; 27 | case "duckduckgo": 28 | img.src=`https://proxy.duckduckgo.com/ip3/${url.split("://")[1]}.ico`; 29 | break; 30 | case "original": 31 | img.src=url; 32 | break; 33 | default: 34 | let u=url.split("/"); 35 | img.src=`${u[0]}//${u[2]}/favicon.ico`; 36 | } 37 | }); 38 | } 39 | 40 | function nativeFavicon(url){ 41 | let letter,letter2; 42 | if(url.startsWith("http")){ 43 | letter2=url.split("/")[2].split("."), 44 | letter=letter2[letter2.length-2][0].toUpperCase(); 45 | }else{ 46 | letter=url[0]; 47 | } 48 | let bgColors=["#0a84ff","#008ea4","#ed00b5","#058b00","#a47f00","#ff0039","#9400ff","#a44900","#363959","#737373"]; 49 | 50 | let canvas=document.createElement("canvas"), 51 | ctx=canvas.getContext("2d"); 52 | canvas.width=16; 53 | canvas.height=16; 54 | ctx.fillStyle=bgColors[Math.trunc(Math.random()*10)]; 55 | ctx.fillRect(0,0,16,16); 56 | ctx.font="11px Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif"; 57 | ctx.fillStyle="#fff"; 58 | ctx.textAlign="center"; 59 | ctx.fillText(letter,8,12); 60 | ctx.drawImage(canvas,0,0,16,16); 61 | let dataURL=canvas.toDataURL(); 62 | return dataURL; 63 | } 64 | -------------------------------------------------------------------------------- /src/icons/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/changelog.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/clear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/icons/clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/dropdown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/folder-add.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/folder-closed.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/folder-opened.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/gear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/icon2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/icons/information.svg: -------------------------------------------------------------------------------- 1 | 2 | > 3 | -------------------------------------------------------------------------------- /src/icons/management.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/pause.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/paused.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/play.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/radio.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/scan.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/select.svg: -------------------------------------------------------------------------------- 1 | > 2 | -------------------------------------------------------------------------------- /src/icons/sidebar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/support.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/icons/warn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/icons/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/import.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let bookmarksToAdd=[], 4 | bookmarksNotAdded, 5 | bookmarkSecondTry=false, 6 | folderListId, 7 | overlayText=document.getElementById("dropArea"); 8 | 9 | browser.runtime.onMessage.addListener(run); 10 | function run(m){ 11 | if(m.nextBookmark&&bookmarksToAdd.length){ 12 | let bookmarkId=m.nextBookmark; 13 | if(m.errorBookmark)bookmarksNotAdded.push(bookmarksToAdd[bookmarkId-1]); 14 | if(bookmarkId{},err=>{ 22 | console.warn(err); 23 | }); 24 | dropOverlay.classList.remove("none"); 25 | overlayText.textContent=i18n("importing",[bookmarkId+1,bookmarksToAdd.length,bookmarksToAdd[bookmarkId].title]) 26 | }else{ 27 | if(bookmarksNotAdded.length){ 28 | if(bookmarkSecondTry){ 29 | dropOverlay.classList.add("none"); 30 | statusbar(i18n("importOK")); 31 | bookmarksNotAdded=[]; 32 | bookmarksToAdd=[]; 33 | }else{ 34 | bookmarkSecondTry=true; 35 | bookmarksToAdd=bookmarksNotAdded; 36 | bookmarksNotAdded=[]; 37 | browser.runtime.sendMessage({ 38 | "addThis":true, 39 | "url":bookmarksToAdd[0].url, 40 | "title":bookmarksToAdd[0].title, 41 | "folder":folderListId, 42 | "addBookmark":0 43 | }).then(()=>{},err=>{ 44 | console.warn(err); 45 | }); 46 | } 47 | }else{ 48 | dropOverlay.classList.add("none"); 49 | statusbar(i18n("importOK")); 50 | bookmarksNotAdded=[]; 51 | bookmarksToAdd=[] 52 | } 53 | } 54 | } 55 | } 56 | 57 | function importingStart(folderId){ 58 | bookmarkSecondTry=false; 59 | bookmarksNotAdded=[]; 60 | browser.bookmarks.getSubTree(folderId).then(bookmarksTree=>{ 61 | bookmarksToAdd=flatBookmarks(bookmarksTree[0]); 62 | if(bookmarksToAdd.length){ 63 | dropOverlay.classList.remove("none"); 64 | overlayText.textContent=i18n("importing",[1,bookmarksToAdd.length,bookmarksToAdd[0].title]) 65 | browser.storage.local.get('sort').then(result=>{ 66 | let sort=result.sort; 67 | folderListId=`folder${new Date().getTime()}`; 68 | sort.push([folderListId,"root","folder",bookmarksTree[0].title,false]); 69 | browser.storage.local.set({sort}).then(()=>{ 70 | browser.runtime.sendMessage({ 71 | "addThis":true, 72 | "url":bookmarksToAdd[0].url, 73 | "title":bookmarksToAdd[0].title, 74 | "folder":folderListId, 75 | "addBookmark":0 76 | }).then(()=>{},err=>{ 77 | console.warn(err); 78 | }); 79 | },err=>{console.error(err);}); 80 | },err=>{ 81 | console.error(err); 82 | }); 83 | }else{ 84 | statusbar(i18n("emptyFolder")); 85 | } 86 | },err=>{ 87 | console.warn(err); 88 | }); 89 | } 90 | 91 | function flatBookmarks(folder){ 92 | let arr=[]; 93 | folder.children.forEach(e=>{ 94 | if(e.type==="bookmark"){ 95 | arr.push(e); 96 | }else if(e.type==="folder"){ 97 | let flat=flatBookmarks(e); 98 | arr.push(flat); 99 | } 100 | }); 101 | return arr.flat(Infinity); 102 | } 103 | -------------------------------------------------------------------------------- /src/inputs.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --input-text-color:#15141a; 3 | --input-text-background:#fff; 4 | --input-border:#15141a69; 5 | --input-background:#cfcfd854; 6 | --input-background-hover:#cfcfd8a8; 7 | --input-background-active:#cfcfd8; 8 | --accent-text:#fbfbfe; 9 | --accent-color:#0061e0; 10 | --accent-hover:#0250bb; 11 | --accent-active:#053e94; 12 | --checkbox-svg:url("icons/checked.svg#d"); 13 | --radio-svg:url("icons/radio.svg#d"); 14 | --neutral-background:#cfcfd854; 15 | --neutral-hover:#cfcfd8a8; 16 | --neutral-active:#cfcfd8; 17 | --dropdown:url("icons/dropdown.svg#d"); 18 | --negative-color:#fff; 19 | --negative-background:#ff0039; 20 | --negative-hover:#d70022; 21 | --negative-active:#a4000f; 22 | } 23 | 24 | .dark:root{ 25 | --input-text-color:#fbfbfe; 26 | --input-text-background:#23222b; 27 | --input-border:#fbfbfe69; 28 | --input-background:#2b2a33; 29 | --input-background-hover:#52525e; 30 | --input-background-active:#5b5b66; 31 | --accent-text:#2b2a33; 32 | --accent-color:#0df; 33 | --accent-hover:#80ebff; 34 | --accent-active:#aaf2ff; 35 | --checkbox-svg:url("icons/checked.svg#l"); 36 | --radio-svg:url("icons/radio.svg#l"); 37 | --neutral-background:#2b2a33; 38 | --neutral-hover:#52525e; 39 | --neutral-active:#5b5b66; 40 | --dropdown:url("icons/dropdown.svg#l"); 41 | --negative-color:#fff; 42 | --negative-background:#ff0039; 43 | --negative-hover:#d70022; 44 | --negative-active:#a4000f; 45 | } 46 | 47 | @media (prefers-color-scheme: dark) { 48 | .auto:root{ 49 | --input-text-color:#fbfbfe; 50 | --input-text-background:#23222b; 51 | --input-border:#fbfbfe69; 52 | --input-background:#2b2a33; 53 | --input-background-hover:#52525e; 54 | --input-background-active:#5b5b66; 55 | --accent-text:#2b2a33; 56 | --accent-color:#0df; 57 | --accent-hover:#80ebff; 58 | --accent-active:#aaf2ff; 59 | --checkbox-svg:url("icons/checked.svg#l"); 60 | --radio-svg:url("icons/radio.svg#l"); 61 | --neutral-background:#2b2a33; 62 | --neutral-hover:#52525e; 63 | --neutral-active:#5b5b66; 64 | --dropdown:url("icons/dropdown.svg#l"); 65 | --negative-color:#fff; 66 | --negative-background:#ff0039; 67 | --negative-hover:#d70022; 68 | --negative-active:#a4000f; 69 | } 70 | } 71 | 72 | input[type="checkbox"], 73 | input[type="radio"]{ 74 | -moz-appearance:none; 75 | width:16px; 76 | height:16px; 77 | border:1px solid var(--input-border); 78 | margin:2px 6px 2px 2px; 79 | background-color:var(--input-background); 80 | background-position:center center; 81 | background-repeat:no-repeat; 82 | vertical-align:text-top; 83 | box-sizing:border-box; 84 | } 85 | 86 | input[type="checkbox"]{ 87 | border-radius: 2px; 88 | } 89 | 90 | input[type="radio"]{ 91 | border-radius:50%; 92 | } 93 | 94 | input[type="checkbox"]:checked{ 95 | background-image:var(--checkbox-svg); 96 | background-color:var(--accent-color); 97 | border-color:transparent; 98 | } 99 | 100 | input[type="radio"]:checked{ 101 | background-image:var(--radio-svg); 102 | background-color:var(--accent-color); 103 | border-color:transparent; 104 | } 105 | 106 | input[type="checkbox"]:hover:not(:disabled):not(:checked), 107 | input[type="radio"]:hover:not(:disabled):not(:checked){ 108 | background-color:var(--input-background-hover); 109 | } 110 | 111 | input[type="checkbox"]:active:not(:disabled):not(:checked), 112 | input[type="radio"]:active:not(:disabled):not(:checked){ 113 | background-color:var(--input-background-active); 114 | } 115 | 116 | input[type="checkbox"]:checked:hover:not(:disabled), 117 | input[type="radio"]:checked:hover:not(:disabled){ 118 | background-color:var(--accent-hover); 119 | } 120 | 121 | input[type="checkbox"]:checked:active:not(:disabled), 122 | input[type="radio"]:checked:active:not(:disabled){ 123 | background-color:var(--accent-active); 124 | } 125 | 126 | input[type="number"], 127 | input[type="text"]{ 128 | -moz-appearance:none; 129 | box-sizing:border-box; 130 | margin:2px 8px; 131 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 132 | font-size:13px; 133 | padding:7px; 134 | min-height:33px; 135 | color:var(--input-text-color); 136 | border:1px solid var(--input-border); 137 | border-radius:4px; 138 | background-color:var(--input-text-background); 139 | } 140 | 141 | input[type="number"]:focus, 142 | input[type="text"]:focus{ 143 | border-color:transparent; 144 | outline:2px solid var(--accent-color); 145 | outline-offset:-1px; 146 | } 147 | 148 | button, 149 | select{ 150 | -moz-appearance:none; 151 | box-sizing:border-box; 152 | margin:0 4px; 153 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 154 | font-size:13px; 155 | font-weight:600; 156 | padding:7px 15px; 157 | min-height:33px; 158 | min-width:80px; 159 | border:1px solid transparent; 160 | border-radius:4px; 161 | background-color:var(--neutral-background); 162 | color:var(--input-text-color); 163 | } 164 | 165 | select{ 166 | margin:2px 8px; 167 | padding:7px 25px 7px 15px; 168 | background-image:var(--dropdown); 169 | background-repeat:no-repeat; 170 | background-position:right 14px center; 171 | } 172 | 173 | .fileInput{ 174 | box-sizing:border-box; 175 | margin:0 4px; 176 | font-size:13px; 177 | font-weight:600; 178 | padding:0; 179 | height:33px; 180 | display:inline-block; 181 | border:1px solid transparent; 182 | border-radius:4px; 183 | background-color:var(--neutral-background); 184 | overflow:hidden; 185 | vertical-align:-11px; 186 | } 187 | 188 | button:hover, 189 | select:hover, 190 | .fileInput:hover{ 191 | background-color:var(--neutral-hover); 192 | } 193 | 194 | button:active, 195 | select:active, 196 | select:focus, 197 | .fileInput:active{ 198 | background-color:var(--neutral-active); 199 | } 200 | 201 | input[type="range"]{ 202 | vertical-align:-6px; 203 | margin:0 8px; 204 | } 205 | 206 | button:focus-visible, 207 | select:focus-visible, 208 | input[type="checkbox"]:focus-visible, 209 | input[type="radio"]:focus-visible, 210 | input[type="range"]:focus-visible{ 211 | outline:2px solid var(--accent-color); 212 | outline-offset:2px; 213 | } 214 | 215 | .positive{ 216 | background-color:var(--accent-color) !important; 217 | color:var(--accent-text) !important; 218 | } 219 | 220 | .positive:hover{ 221 | background-color:var(--accent-hover) !important; 222 | } 223 | 224 | .positive:active{ 225 | background-color:var(--accent-active) !important; 226 | } 227 | 228 | .negative{ 229 | background-color:var(--negative-background) !important; 230 | color:var(--negative-color) !important; 231 | } 232 | 233 | .negative:hover{ 234 | background-color:var(--negative-hover) !important; 235 | } 236 | 237 | .negative:active{ 238 | background-color:var(--negative-active) !important; 239 | } 240 | 241 | .neutral{ 242 | background-color: var(--neutral-background) !important; 243 | color:var(--neutral-color) !important; 244 | } 245 | 246 | .neutral:hover{ 247 | background-color: var(--neutral-hover) !important; 248 | } 249 | 250 | .neutral:active{ 251 | background-color: var(--neutral-active) !important; 252 | } 253 | 254 | .ghost{ 255 | background-color:transparent !important; 256 | border-radius:4px; 257 | } 258 | 259 | .ghost:hover{ 260 | background-color:var(--neutral-background) !important; 261 | } 262 | 263 | .ghost:active{ 264 | background-color:var(--neutral-hover) !important; 265 | } 266 | 267 | .ghost:focus-visible{ 268 | outline:2px solid var(--accent-color); 269 | outline-offset:-2px; 270 | } 271 | -------------------------------------------------------------------------------- /src/inspect.css: -------------------------------------------------------------------------------- 1 | #__wps_inspectOverlay{ 2 | background-color:#ffe900; 3 | border:1px dashed #003eaa !important; 4 | opacity:.45 !important; 5 | position:absolute !important; 6 | z-index:2147483646 !important; 7 | pointer-events:none !important; 8 | display:inline-block !important; 9 | box-sizing:border-box !important; 10 | font-size:16px !important; 11 | font-weight:bold !important; 12 | line-height:18px !important; 13 | white-space:nowrap !important; 14 | color:#000 !important; 15 | overflow:hidden !important; 16 | padding-left:3px !important; 17 | } 18 | -------------------------------------------------------------------------------- /src/inspect.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let overlay,dialogTabId; 4 | 5 | function init(){ 6 | overlay=document.getElementById("__wps_inspectOverlay"); 7 | if(!overlay){ 8 | overlay=document.createElement("wps-overlay"); 9 | overlay.id="__wps_inspectOverlay"; 10 | document.documentElement.appendChild(overlay); 11 | addEvent(); 12 | } 13 | } 14 | 15 | function addEvent(){ 16 | document.body.addEventListener("mouseover",highlightElement); 17 | document.body.addEventListener("click",selectElement); 18 | } 19 | 20 | function removeEvent(){ 21 | document.body.removeEventListener("mouseover",highlightElement); 22 | document.body.removeEventListener("click",selectElement); 23 | } 24 | 25 | function highlightElement(e){ 26 | let rect=e.target.getBoundingClientRect(); 27 | overlay.textContent=e.target.tagName; 28 | overlay.style.height=rect.height+"px"; 29 | overlay.style.width=rect.width+"px"; 30 | overlay.style.left=rect.left+window.scrollX+"px"; 31 | overlay.style.top=rect.top+window.scrollY+"px"; 32 | } 33 | 34 | function selectElement(e){ 35 | e.preventDefault(); 36 | overlay.style.backgroundColor="#12bc00"; 37 | showDialog(e.target); 38 | removeEvent(); 39 | } 40 | 41 | function showDialog(e){ 42 | if(!document.getElementById("__wps_inspectDialog")){ 43 | browser.runtime.sendMessage({"executeCustom":true}).then(()=>{ 44 | let popup=document.createElement("wps-popup"); 45 | popup.id="__wps_inspectDialog"; 46 | popup.setAttribute("selector",uniqueSelector(e)); 47 | popup.setAttribute("dialogTabId",dialogTabId); 48 | popup.setAttribute("mode","inspect"); 49 | document.documentElement.appendChild(popup); 50 | },err=>{ 51 | console.warn(err); 52 | }); 53 | } 54 | } 55 | 56 | function uniqueSelector(e){ 57 | let selector="", 58 | cu=e, 59 | noID=true; 60 | if(e.tagName==="HTML"||e.tagName==="BODY"){ 61 | selector=e.tagName; 62 | }else{ 63 | while(cu.parentElement&&noID){ 64 | if(cu.id){ 65 | noID=false; 66 | selector=`> #${cu.id} ${selector}`; 67 | }else if(cu.tagName==="BODY"){ 68 | noID=false; 69 | selector=`> BODY ${selector}`; 70 | }else{ 71 | let nth=1; 72 | if(cu.previousElementSibling){ 73 | let prev=cu; 74 | if(cu.previousElementSibling.id){ 75 | selector=`> #${cu.previousElementSibling.id} + ${cu.tagName} ${selector}`; 76 | noID=false; 77 | }else{ 78 | while(prev.previousElementSibling){ 79 | prev=prev.previousElementSibling; 80 | nth++; 81 | } 82 | selector=`> ${cu.tagName}:nth-child(${nth}) ${selector}`; 83 | } 84 | }else{ 85 | selector=`> ${cu.tagName}:nth-child(1) ${selector}`; 86 | } 87 | cu=cu.parentElement; 88 | } 89 | } 90 | selector=selector.substr(2); 91 | } 92 | return selector; 93 | } 94 | 95 | function i18n(e,s1){ 96 | return browser.i18n.getMessage(e,s1); 97 | } 98 | 99 | browser.runtime.onMessage.addListener(run); 100 | function run(m,s){ 101 | if(m.initInspect){ 102 | dialogTabId=m.dialogTabId; 103 | init(); 104 | } 105 | if(m.toInspect){ 106 | if(m.addEvent){ 107 | addEvent(); 108 | } 109 | if(m.removeEvent){ 110 | removeEvent(); 111 | } 112 | if(m.removeInspectDialog){ 113 | document.getElementById("__wps_inspectDialog").remove(); 114 | } 115 | if(m.yellowOverlay){ 116 | overlay.style.backgroundColor="#ffe900"; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/inspectDialog.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --text-color:#15141a; 3 | --border-color:#d7d7db; 4 | --background-color:#fff; 5 | --titlebar-background:#fff; 6 | --icon:url("icons/icon.svg"); 7 | --overlay-background:#00000080; 8 | --select:url("icons/select.svg#l"); 9 | } 10 | 11 | .dark:root { 12 | --text-color:#fbfbfe; 13 | --border-color:#676670; 14 | --background-color:#1c1b22; 15 | --titlebar-background:#42414d; 16 | --icon:url("icons/icon.svg#w"); 17 | --overlay-background:#000c; 18 | --select:url("icons/select.svg#d"); 19 | } 20 | 21 | @media (prefers-color-scheme: dark) { 22 | .auto:root { 23 | --text-color:#fbfbfe; 24 | --border-color:#676670; 25 | --background-color:#1c1b22; 26 | --titlebar-background:#42414d; 27 | --icon:url("icons/icon.svg#w"); 28 | --overlay-background:#000c; 29 | --select:url("icons/select.svg#d"); 30 | } 31 | } 32 | 33 | *:-moz-focusring{ 34 | outline:none; 35 | } 36 | 37 | html, 38 | body{ 39 | height:100%; 40 | margin:0; 41 | padding:0; 42 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 43 | font-size:14px; 44 | color:var(--text-color); 45 | } 46 | 47 | body{ 48 | opacity:1; 49 | transform:scale(1); 50 | transition:opacity 200ms, transform 160ms; 51 | } 52 | 53 | h1{ 54 | font-size:14px; 55 | font-weight:600; 56 | line-height:36px; 57 | margin:0; 58 | } 59 | 60 | button{ 61 | margin:0 0 0 8px; 62 | } 63 | 64 | input[type="text"]{ 65 | margin:0; 66 | } 67 | 68 | #retryBtn{ 69 | background-image:var(--select); 70 | background-repeat:no-repeat; 71 | background-position:8px; 72 | padding-left:32px; 73 | } 74 | 75 | #inspectDialog{ 76 | background:var(--background-color); 77 | border:1px solid var(--border-color); 78 | border-radius:8px; 79 | box-shadow:0 0 0 2000px var(--overlay-background); 80 | padding:0 20px 20px 20px; 81 | position:fixed; 82 | box-sizing:border-box; 83 | z-index:2147483647; 84 | display:grid; 85 | grid-template-columns:400px; 86 | grid-column-gap:20px; 87 | grid-row-gap:10px; 88 | align-items:start; 89 | top:calc(50% - 95px); 90 | left:calc(50% - 221px); 91 | width:440px; 92 | } 93 | 94 | .popupFooter{ 95 | float:right; 96 | justify-self:right; 97 | } 98 | 99 | #titlebar{ 100 | background-color:var(--titlebar-background); 101 | background-image:var(--icon); 102 | background-repeat:no-repeat; 103 | height:36px; 104 | display:block; 105 | background-size: 24px 24px; 106 | background-position: 6px 6px; 107 | border-bottom:1px solid var(--border-color); 108 | margin:0px -20px; 109 | width:calc(100% + 38px); 110 | text-align:center; 111 | border-radius: 8px 8px 0 0; 112 | } 113 | 114 | .fade{ 115 | opacity:0; 116 | transform:scale(.6); 117 | transition:opacity 200ms, transform 600ms; 118 | } 119 | -------------------------------------------------------------------------------- /src/inspectDialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |

11 | 12 | 13 |
14 | 17 |
18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/inspectDialog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let dialogTabId; 4 | 5 | (async function(){ 6 | const result=browser.storage.local.get("settings"); 7 | const urlParams=new URLSearchParams(window.location.search+window.location.hash); 8 | dialogTabId=urlParams.get("dialogTabId")*1; 9 | document.getElementById("selectorInput").value=urlParams.get("selector"); 10 | document.getElementById("selectorInput").placeholder=i18n("selectorCSS"); 11 | document.getElementById("titlebarH1").textContent=i18n("extensionName"); 12 | document.getElementById("inspectText").textContent=i18n("inspectText"); 13 | 14 | let cancelBtn=document.getElementById("cancelBtn"); 15 | cancelBtn.textContent=i18n("cancel"); 16 | cancelBtn.addEventListener("click",cancel); 17 | let retryBtn=document.getElementById("retryBtn"); 18 | retryBtn.textContent=i18n("inspectRetry"); 19 | retryBtn.addEventListener("click",retry); 20 | let okBtn=document.getElementById("okBtn"); 21 | okBtn.textContent=i18n("ok"); 22 | okBtn.addEventListener("click",ok); 23 | 24 | const {settings}=await result; 25 | document.documentElement.className=settings.theme?settings.theme:"auto"; 26 | document.body.removeAttribute("class"); 27 | })(); 28 | 29 | function cancel(){ 30 | browser.runtime.sendMessage({"closeTab":true}).then(()=>{},err=>{console.warn(err);}); 31 | } 32 | 33 | function retry(){ 34 | browser.runtime.sendMessage({ 35 | "byBG":true, 36 | "toInspect":true, 37 | "removeInspectDialog":true, 38 | "yellowOverlay":true, 39 | "addEvent":true 40 | }).then(()=>{},err=>{ 41 | console.warn(err); 42 | }); 43 | } 44 | 45 | function ok(){ 46 | let cssSelector=document.getElementById("selectorInput").value; 47 | browser.runtime.sendMessage({ 48 | "returnToDialogTab":true, 49 | "cssSelector":cssSelector, 50 | "dialogTabId":dialogTabId 51 | }).then(()=>{},err=>{ 52 | console.warn(err); 53 | }); 54 | } 55 | 56 | function i18n(e){ 57 | return browser.i18n.getMessage(e); 58 | } 59 | -------------------------------------------------------------------------------- /src/inspectView.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/inspectView.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | document.title=browser.i18n.getMessage("extensionName")+" | "+browser.i18n.getMessage("inspectElement"); 4 | 5 | function loadPage(url,dialogTabId){ 6 | let xhr=new XMLHttpRequest(); 7 | xhr.open("GET",url); 8 | xhr.onload=function(){ 9 | let html_data=this.responseText; 10 | let parser=new DOMParser(), 11 | doc=parser.parseFromString(html_data,"text/html"), 12 | base=doc.getElementsByTagName("base")[0]; 13 | if(base){ 14 | if(base.getAttribute("href")=="/"){ 15 | let url2=url.split("/")[0]+"//"+url.split("/")[2]+"/"; 16 | base.href=url2; 17 | }else if(!base.href.startsWith("http")){ 18 | base.href=url; 19 | } 20 | }else{ 21 | base=document.createElement("base"); 22 | base.href=url; 23 | if(doc.head)doc.head.insertBefore(base,doc.head.firstElementChild); 24 | } 25 | document.documentElement.remove(); 26 | document.appendChild(doc.documentElement); 27 | browser.runtime.sendMessage({ 28 | "inspectMe":true, 29 | "dialogTabId":dialogTabId 30 | }).then(()=>{},err=>{console.warn(err);}); 31 | }; 32 | let error=function(e){ 33 | console.warn([url,e]); 34 | }; 35 | xhr.onerror=error; 36 | xhr.ontimeout=error; 37 | xhr.send(null); 38 | } 39 | 40 | browser.runtime.onMessage.addListener(run); 41 | function run(m,s){ 42 | if(m.loadXHR){ 43 | loadPage(m.inspectUrl,m.dialogTabId); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "__MSG_extensionName__", 4 | "description": "__MSG_extensionDescription__", 5 | "version": "2.1.5", 6 | "default_locale": "en", 7 | "icons": { 8 | "48": "icons/icon.svg", 9 | "24": "icons/icon2.svg" 10 | }, 11 | "developer": { 12 | "name": "WaldiPL", 13 | "url": "https://github.com/WaldiPL/webpageScanner" 14 | }, 15 | "applications": { 16 | "gecko": { 17 | "id": "webpageScanner@waldemar.b", 18 | "strict_min_version": "63.0a1" 19 | } 20 | }, 21 | "permissions": [ 22 | "tabs", 23 | "storage", 24 | "alarms", 25 | "", 26 | "notifications", 27 | "contextMenus" 28 | ], 29 | "optional_permissions": [ 30 | "bookmarks" 31 | ], 32 | "background": { 33 | "page": "bg.html" 34 | }, 35 | "sidebar_action": { 36 | "browser_style": false, 37 | "default_title": "__MSG_extensionName__", 38 | "default_panel": "sidebar.html", 39 | "default_icon": "icons/icon2.svg" 40 | }, 41 | "browser_action": { 42 | "browser_style": false, 43 | "default_title": "__MSG_extensionName__", 44 | "default_popup": "popup.html", 45 | "default_icon": { 46 | "19": "icons/icon2.svg", 47 | "38": "icons/icon.svg" 48 | } 49 | }, 50 | "commands": { 51 | "_execute_sidebar_action": { 52 | "suggested_key": { 53 | "default": "Alt+Q" 54 | } 55 | } 56 | }, 57 | "options_ui": { 58 | "browser_style": false, 59 | "page": "options.html#options", 60 | "open_in_tab": true 61 | }, 62 | "content_security_policy": "script-src 'self'; object-src 'self'" 63 | } 64 | -------------------------------------------------------------------------------- /src/md5.js: -------------------------------------------------------------------------------- 1 | !function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t),e=(n>>16)+(t>>16)+(r>>16);return e<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)+14]=r;var e,i,a,h,d,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e>5]>>>t%32&255);return r}function h(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(h(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="0123456789abcdef",o="";for(r=0;r>>4&15)+e.charAt(15&t);return o}function v(n){return unescape(encodeURIComponent(n))}function m(n){return d(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); -------------------------------------------------------------------------------- /src/notification.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/src/notification.opus -------------------------------------------------------------------------------- /src/notification2.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/src/notification2.opus -------------------------------------------------------------------------------- /src/options.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --text-color:#15141a; 3 | --border-color:#d7d7db; 4 | --background-color:#fff; 5 | --article-background:#fff; 6 | --article-shadow:#d7d7db; 7 | --icon:url("icons/icon.svg"); 8 | --overlay-background:#00000080; 9 | --gear:url("/icons/gear.svg#black"); 10 | --management:url("/icons/management.svg#black"); 11 | --changelog:url("/icons/changelog.svg#black"); 12 | --support:url("/icons/support.svg#black"); 13 | --gear-active:url("/icons/gear.svg#blue"); 14 | --management-active:url("/icons/management.svg#blue"); 15 | --changelog-active:url("/icons/changelog.svg#blue"); 16 | --support-active:url("/icons/support.svg#blue"); 17 | --nav-button-hover:#cfcfd8a8; 18 | --nav-button-active:#cfcfd8; 19 | --sidebar:url("/icons/sidebar.svg#black"); 20 | } 21 | 22 | .dark:root { 23 | --text-color:#fbfbfe; 24 | --border-color:#676670; 25 | --background-color:#1c1b22; 26 | --article-background:#23222b; 27 | --article-shadow:#4a4a4f; 28 | --icon:url("icons/icon.svg#w"); 29 | --overlay-background:#000c; 30 | --gear:url("/icons/gear.svg#white"); 31 | --management:url("/icons/management.svg#white"); 32 | --changelog:url("/icons/changelog.svg#white"); 33 | --support:url("/icons/support.svg#white"); 34 | --gear-active:url("/icons/gear.svg#blue2"); 35 | --management-active:url("/icons/management.svg#blue2"); 36 | --changelog-active:url("/icons/changelog.svg#blue2"); 37 | --support-active:url("/icons/support.svg#blue2"); 38 | --nav-button-hover:#52525e; 39 | --nav-button-active:#5b5b66; 40 | --sidebar:url("/icons/sidebar.svg#white"); 41 | } 42 | 43 | @media (prefers-color-scheme: dark) { 44 | .auto:root { 45 | --text-color:#fbfbfe; 46 | --border-color:#676670; 47 | --background-color:#1c1b22; 48 | --article-background:#23222b; 49 | --article-shadow:#4a4a4f; 50 | --icon:url("icons/icon.svg#w"); 51 | --overlay-background:#000c; 52 | --gear:url("/icons/gear.svg#white"); 53 | --management:url("/icons/management.svg#white"); 54 | --changelog:url("/icons/changelog.svg#white"); 55 | --support:url("/icons/support.svg#white"); 56 | --gear-active:url("/icons/gear.svg#blue2"); 57 | --management-active:url("/icons/management.svg#blue2"); 58 | --changelog-active:url("/icons/changelog.svg#blue2"); 59 | --support-active:url("/icons/support.svg#blue2"); 60 | --nav-button-hover:#52525e; 61 | --nav-button-active:#5b5b66; 62 | --sidebar:url("/icons/sidebar.svg#white"); 63 | } 64 | } 65 | 66 | html{ 67 | height:100%; 68 | padding:0; 69 | margin:0; 70 | } 71 | 72 | body{ 73 | display:grid; 74 | grid-template-columns:240px auto; 75 | grid-template-rows:auto; 76 | grid-template-areas:"nav content"; 77 | font-family: Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 78 | font-size:15px; 79 | padding:0; 80 | margin:0; 81 | height:100%; 82 | background-color:var(--background-color); 83 | color:var(--text-color); 84 | } 85 | 86 | section:not(:target){ 87 | display:none; 88 | } 89 | 90 | header{ 91 | position:fixed; 92 | top:8px; 93 | left:30px; 94 | min-width:193px; 95 | max-width:216px; 96 | height:52px; 97 | background-color:var(--article-background); 98 | display:flex; 99 | align-items:center; 100 | padding:0 8px 0 48px; 101 | background-image:var(--icon); 102 | background-size:32px; 103 | background-repeat:no-repeat; 104 | background-position:8px; 105 | box-sizing:border-box; 106 | border:1px solid var(--border-color) 107 | border-radius:4px; 108 | box-shadow:#0c0c0d1a 0px 1px 4px 0px; 109 | transition:box-shadow 150ms; 110 | } 111 | 112 | header h1{ 113 | line-height:18px; 114 | } 115 | 116 | nav{ 117 | grid-area:nav; 118 | padding-top:70px; 119 | background-color:var(--background-color); 120 | height:100%; 121 | box-sizing:border-box; 122 | } 123 | 124 | #optionsA{ 125 | background-image:var(--gear); 126 | } 127 | 128 | #managementA{ 129 | background-image:var(--management); 130 | } 131 | 132 | #changelogA{ 133 | background-image:var(--changelog); 134 | } 135 | 136 | #supportA{ 137 | background-image:var(--support); 138 | } 139 | 140 | #optionsA.active{ 141 | background-image:var(--gear-active); 142 | } 143 | 144 | #managementA.active{ 145 | background-image:var(--management-active); 146 | } 147 | 148 | #changelogA.active{ 149 | background-image:var(--changelog-active); 150 | } 151 | 152 | #supportA.active{ 153 | background-image:var(--support-active); 154 | } 155 | 156 | nav a{ 157 | color:var(--text-color); 158 | font-size:16px; 159 | text-decoration: none; 160 | margin-inline-start: 34px; 161 | transition: background-color 150ms; 162 | display:block; 163 | padding:12px 10px 13px 44px; 164 | background-position:left 10px center; 165 | background-repeat:no-repeat; 166 | background-size:24px 24px; 167 | white-space:nowrap; 168 | line-height:23px; 169 | width:185px; 170 | box-sizing:border-box; 171 | border-radius:4px; 172 | } 173 | 174 | @media (max-width:830px){ 175 | body{ 176 | grid-template-columns:82px auto; 177 | } 178 | nav a{ 179 | overflow:hidden; 180 | width:0 !important; 181 | padding-right:0 !important; 182 | } 183 | header{ 184 | min-width:52px; 185 | padding:0; 186 | } 187 | header h1{ 188 | display:none; 189 | } 190 | } 191 | 192 | nav a.active{ 193 | color:var(--accent-color); 194 | } 195 | 196 | nav a:hover,nav a:focus{ 197 | background-color:var(--nav-button-hover); 198 | } 199 | 200 | nav a:active{ 201 | background-color:var(--nav-button-active); 202 | } 203 | 204 | nav a.bottomLink{ 205 | font-size:14px; 206 | margin-inline-start: 34px; 207 | padding:8px 10px 10px 44px; 208 | background-position:left 14px center; 209 | background-size:16px 16px; 210 | line-height:18px; 211 | position:absolute; 212 | } 213 | 214 | #scanListA{ 215 | background-image:var(--sidebar); 216 | bottom:30px; 217 | } 218 | 219 | section{ 220 | grid-area:content; 221 | padding: 40px 28px; 222 | overflow:auto; 223 | } 224 | 225 | h1{ 226 | font-size:18px; 227 | font-weight:400; 228 | font-style:italic; 229 | margin:0; 230 | } 231 | 232 | h2{ 233 | font-size:22px; 234 | font-weight:300; 235 | margin:0; 236 | } 237 | 238 | h3{ 239 | font-size:17px; 240 | font-weight:600; 241 | margin:16px 0 4px; 242 | } 243 | 244 | .row{ 245 | padding:4px 0; 246 | white-space:nowrap; 247 | } 248 | 249 | .sub{ 250 | padding:5px 0 5px 25px; 251 | white-space:nowrap; 252 | } 253 | 254 | .false,.false+label{ 255 | opacity:.4; 256 | } 257 | 258 | button:first-child, 259 | select:first-child{ 260 | margin-left:0; 261 | } 262 | 263 | input[type="number"]{ 264 | max-width:80px; 265 | } 266 | 267 | #h2changelog+article{ 268 | border-color:var(--accent-color); 269 | } 270 | 271 | h2+article{ 272 | margin:16px 0 8px; 273 | } 274 | 275 | article{ 276 | background:var(--article-background); 277 | margin:16px 0; 278 | padding:0 16px; 279 | border:1px solid transparent; 280 | max-width:700px; 281 | border-radius:4px; 282 | box-shadow:#0c0c0d1a 0px 1px 4px 0px; 283 | transition:box-shadow 150ms; 284 | } 285 | 286 | article:hover{ 287 | box-shadow:#0c0c0d1a 0px 1px 4px 0px, var(--article-shadow) 0px 0px 0px 5px; 288 | } 289 | 290 | .share{ 291 | display:inline-block; 292 | padding:7px 10px 8px; 293 | margin: 0 8px 16px 0; 294 | border-radius: 2px; 295 | font-size:15px; 296 | font-weight: 600; 297 | line-height:15px; 298 | text-decoration:none; 299 | color:#fff; 300 | } 301 | 302 | .share:hover,.share:focus{ 303 | filter:brightness(1.15); 304 | } 305 | 306 | #twitter{ 307 | background-color:#1DA1F2; 308 | } 309 | 310 | #facebook{ 311 | background-color:#4267B2; 312 | } 313 | 314 | #amo{ 315 | background-color:#57BD35; 316 | } 317 | 318 | input[type="file"]+span{ 319 | padding:7px 15px; 320 | vertical-align:-5px; 321 | } 322 | 323 | input[type="file"]{ 324 | height:33px; 325 | width:200px; 326 | opacity:0; 327 | margin-right:-200px; 328 | } 329 | 330 | .none{ 331 | display:none !important; 332 | } 333 | 334 | .alertBox,.successBox,.errorBox{ 335 | padding:10px; 336 | margin:8px 0; 337 | max-width:800px; 338 | } 339 | 340 | .alertBox{ 341 | background:#ffe90080; 342 | } 343 | 344 | .alertBox h4, .successBox h4{ 345 | margin:0; 346 | } 347 | 348 | .errorBox{ 349 | background:#ff003980; 350 | } 351 | 352 | .successBox{ 353 | background:#12bc0080; 354 | } 355 | 356 | .alertBox ul,.successBox ul,.errorBox ul{ 357 | max-height:210px; 358 | overflow-y:auto; 359 | } 360 | 361 | section a{ 362 | color:var(--accent-color); 363 | text-decoration:none; 364 | } 365 | 366 | section a:hover,section a:focus{ 367 | text-decoration:underline; 368 | } 369 | 370 | label{ 371 | white-space:nowrap; 372 | display:inline-block; 373 | line-height:29px; 374 | } 375 | 376 | .subLabel{ 377 | color:#737373; 378 | font-size:85%; 379 | margin:0; 380 | } 381 | 382 | label + .subLabel{ 383 | padding:5px 0 0 28px; 384 | } 385 | 386 | #alertToolbar{ 387 | color:#15141a; 388 | position:fixed; 389 | top:0; 390 | left:0; 391 | padding:4px 15px; 392 | width:100%; 393 | border-bottom:1px solid #d7b600; 394 | background:#ffe900; 395 | box-sizing:border-box; 396 | } 397 | 398 | span+button{ 399 | margin-left:10px; 400 | } 401 | 402 | select+button, 403 | input+select, 404 | input+.fileInput{ 405 | margin-left:0 !important; 406 | } 407 | 408 | button+input{ 409 | margin-left:4px !important; 410 | } 411 | 412 | #revokePermission{ 413 | padding:0 7px; 414 | margin-left:10px; 415 | border:none; 416 | color:var(--accent-color); 417 | } 418 | 419 | #revokePermission:not(:hover){ 420 | background-color:transparent; 421 | } 422 | 423 | *:focus{ 424 | outline:none; 425 | } 426 | 427 | #shortcut3{ 428 | width:100px; 429 | } 430 | 431 | #optionsForm{ 432 | margin-bottom:35px; 433 | } 434 | 435 | #playSound{ 436 | padding:7px; 437 | min-width:33px; 438 | } 439 | 440 | #externalSound{ 441 | width:500px; 442 | } 443 | -------------------------------------------------------------------------------- /src/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 |

12 |
13 | 20 |
21 |

22 |
23 |

24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 |
43 | 44 |
45 |
46 | 47 |

48 |
49 |
50 | 56 |
57 |
58 | 64 |
65 |

66 |
67 | ++ 81 |
82 |
83 | 84 |
85 |

86 |
87 | 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 |
135 | s 137 |
138 |
139 | % 141 |
142 |
143 | 149 |
150 |
151 | 155 | 156 |
157 |

158 |
159 | 160 |
161 |
162 | 169 |
170 |
171 | 178 |
179 |
180 | 181 |
182 |
183 | 184 |
185 |
186 | 187 |
188 |
189 | 190 |
191 |
192 | 193 |
194 |
195 | 196 |
197 |
198 | 199 |
200 |
201 |
202 |
203 |

204 |

205 |
206 | 207 |
208 |
209 |

210 |
211 |
212 |

213 |
    214 | 215 |
    216 |
    217 | 218 |
    219 |
    220 |

    221 |
    222 |
    223 |

    224 |
      225 | 226 |
      227 |

      228 |
      229 |

      230 |

      231 | 232 |
      233 |
      234 | 238 | 239 |
      240 |
      241 |

      242 |

      243 | 244 |
      245 |

      246 |

      247 |

      248 |
      249 | 255 |
      256 |

      257 | 258 |
      259 |
      260 | 262 |
      263 |
      264 |

      265 | 268 |
        269 |
        270 |
        271 |

        272 |
          273 |
          274 |

          275 |

          276 |
          277 | 278 |
          279 |

          280 |
          281 |
          282 |
          283 |

          284 |
          285 |
          286 |

          287 | 291 | 295 | 302 |
          303 |
          304 | 305 | 306 | 307 | 308 | 309 | -------------------------------------------------------------------------------- /src/popup.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --background-color:#fff; 3 | --text-color:#15141a; 4 | --hover:#cfcfd8a8; 5 | --active:#cfcfd8; 6 | --shadow:#181a1b08; 7 | } 8 | 9 | .dark:root { 10 | --background-color:#42414d; 11 | --text-color:#fbfbfe; 12 | --hover:#52525e; 13 | --active:#5b5b66; 14 | --shadow:#181a1b08; 15 | } 16 | 17 | @media (prefers-color-scheme: dark) { 18 | .auto:root { 19 | --background-color:#42414d; 20 | --text-color:#fbfbfe; 21 | --hover:#52525e; 22 | --active:#5b5b66; 23 | --shadow:#181a1b08; 24 | } 25 | } 26 | 27 | body{ 28 | max-width:300px; 29 | margin:8px; 30 | background-color:var(--background-color); 31 | } 32 | 33 | div{ 34 | background:var(--background-color); 35 | } 36 | 37 | button{ 38 | background-color:transparent; 39 | color:var(--text-color); 40 | border:none; 41 | padding:8px; 42 | font-size:12px; 43 | text-align:left; 44 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 45 | width:100%; 46 | border-radius:4px; 47 | } 48 | 49 | button:hover{ 50 | background-color:var(--hover); 51 | } 52 | 53 | button:active{ 54 | background-color:var(--active); 55 | box-shadow: 0 1px 0 var(--shadow) inset; 56 | } 57 | 58 | .none{ 59 | display:none !important; 60 | } 61 | -------------------------------------------------------------------------------- /src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
          9 | 10 | 11 | 12 | 13 |
          14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/popup.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | (async function(){ 4 | document.getElementById("addThis").textContent=i18n("addThis"); 5 | document.getElementById("scanNow").textContent=i18n("scanNow"); 6 | document.getElementById("showList").textContent=i18n("showList"); 7 | document.getElementById("addThis").addEventListener("click",addThis); 8 | document.getElementById("scanNow").addEventListener("click",scanNow); 9 | document.getElementById("showList").addEventListener("click",showList); 10 | const result=browser.storage.local.get('settings'); 11 | const activeAlarm=browser.alarms.get("openSitesDelay"); 12 | const badgeText=browser.browserAction.getBadgeText({}); 13 | const {settings}=await result; 14 | document.documentElement.className=settings.theme?settings.theme:"auto"; 15 | let openSitesBtn=document.getElementById("openSites"); 16 | if(await badgeText&&!(await activeAlarm)){ 17 | openSitesBtn.textContent=i18n("openWebpage"); 18 | openSitesBtn.removeAttribute("class"); 19 | if(settings.autoOpen){ 20 | openSitesBtn.addEventListener("click",()=>{ 21 | browser.alarms.create("openSitesDelay",{delayInMinutes:0.01}); 22 | openSitesBtn.className="none"; 23 | }); 24 | }else{ 25 | openSitesBtn.addEventListener("click",openSites); 26 | } 27 | } 28 | })(); 29 | 30 | function addThis(){ 31 | browser.runtime.sendMessage({"showWpsPopup":true}).then(()=>{},err=>{console.warn(err);}); 32 | } 33 | 34 | function scanNow(){ 35 | browser.runtime.sendMessage({"scanSites":true,"force":true}).then(()=>{},err=>{console.warn(err);}); 36 | } 37 | 38 | function openSites(){ 39 | browser.runtime.sendMessage({"openSites":true}).then(()=>{},err=>{console.warn(err);}); 40 | openSitesBtn.className="none"; 41 | } 42 | 43 | function showList(){ 44 | browser.sidebarAction.open(); 45 | } 46 | 47 | function i18n(e){ 48 | return browser.i18n.getMessage(e); 49 | } 50 | -------------------------------------------------------------------------------- /src/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 19 | 28 | 36 | 44 | 53 |
          54 |
            55 | 56 |
            57 |
            58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/sortable.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const list=document.getElementById("lista"), 4 | nav=document.getElementById("navPanel"), 5 | searchBar=document.getElementById("searchBar"), 6 | dragIndicator=document.getElementById("dragIndicator"), 7 | dropOverlay=document.getElementById("dropOverlay"); 8 | 9 | let startY, 10 | enter, 11 | dragged, 12 | folderId, 13 | frag, 14 | hlFolder; 15 | 16 | (function(){ 17 | document.addEventListener('drop',dropBookmark); 18 | document.addEventListener('dragenter',dragBookmark); 19 | document.addEventListener('dragexit',removeOverlay); 20 | document.addEventListener('dragend',removeOverlay); 21 | document.addEventListener('dragover',dragOver); 22 | list.addEventListener('drop',drop); 23 | list.addEventListener('dragover',dragOver); 24 | list.addEventListener('dragenter',dragEnter); 25 | list.addEventListener('dragend',dragEnd); 26 | list.addEventListener('dragexit',dragExit); 27 | nav.addEventListener('drop',drop); 28 | nav.addEventListener('dragover',dragOver); 29 | nav.addEventListener('dragenter',dragEnter); 30 | nav.addEventListener('dragend',dragEnd); 31 | searchBar.addEventListener('drop',drop); 32 | searchBar.addEventListener('dragover',dragOver); 33 | searchBar.addEventListener('dragenter',dragEnter); 34 | searchBar.addEventListener('dragend',dragEnd); 35 | })(); 36 | 37 | function dragBookmark(e){ 38 | if(!bookmarksToAdd.length&&e.dataTransfer.getData("text/x-wps")!=="true"){ 39 | document.getElementById("dropArea").textContent=i18n("dropHere"); 40 | const dragData=e.dataTransfer.types.includes("text/x-moz-place")||e.dataTransfer.types.includes("text/x-moz-url"); 41 | if(dragData){ 42 | dropOverlay.classList.remove("none"); 43 | } 44 | } 45 | } 46 | 47 | function removeOverlay(){ 48 | dropOverlay.classList.add("none"); 49 | } 50 | 51 | function dropBookmark(e){ 52 | if(!bookmarksToAdd.length&&e.dataTransfer.getData("text/x-wps")!=="true"){ 53 | const dragData=e.dataTransfer.getData("text/x-moz-place"), 54 | dragURL=e.dataTransfer.getData("text/x-moz-url"); 55 | if(dragData){ 56 | const data=JSON.parse(dragData); 57 | if(data.type==="text/x-moz-place"&&data.uri.split("://").length>1){ 58 | browser.runtime.sendMessage({"addThis":true,url:data.uri,title:data.title}); 59 | }else if(data.type==="text/x-moz-place"&&data.concreteGuid){ 60 | importingStart(data.concreteGuid); 61 | }else if(data.type==="text/x-moz-place-container"){ 62 | importingStart(data.itemGuid); 63 | } 64 | }else if(dragURL){ 65 | const data=dragURL.split(/\n/); 66 | browser.runtime.sendMessage({"addThis":true,url:data[0],title:data[1]}); 67 | } 68 | } 69 | removeOverlay(); 70 | } 71 | 72 | function dragStart(e){ 73 | startY=e.clientY; 74 | e.dataTransfer.setData('text/x-wps',"true"); 75 | if(e.target.tagName==="LI"){ 76 | e.dataTransfer.setData('text/x-moz-url',`${extURL}view.html?${e.target.id.substring(4)} 77 | ${e.target.textContent}`); 78 | e.dataTransfer.setData('text/plain',`${extURL}view.html?${e.target.id.substring(4)}`); 79 | }else{ 80 | e.dataTransfer.setData('text/plain',e.target.firstElementChild.textContent); 81 | } 82 | dragIndicator.style.top=0; 83 | dragIndicator.removeAttribute("class"); 84 | dragged=e.target; 85 | } 86 | 87 | function dragOver(e){ 88 | if(e.preventDefault)e.preventDefault(); 89 | } 90 | 91 | function dragExit(e){ 92 | if(enter.firstElementChild.tagName==="A"&&(enter.firstElementChild.className==="indicator"||enter.parentElement.firstElementChild.className==="indicator")) 93 | hlFolder.removeAttribute("class"); 94 | } 95 | 96 | function dragEnter(e){ 97 | const toTop=e.clientYstartY; 151 | frag=document.createDocumentFragment(); 152 | frag.appendChild(dragged); 153 | if(enter.tagName==="HTML"||enter.tagName==="BODY"){ 154 | if(toTop)list.insertBefore(frag,list.firstElementChild); 155 | else list.appendChild(frag); 156 | }else if(dragged.classList.contains("folder")&&enter.dataset.folder!=="root"){ 157 | if(toTop)list.insertBefore(frag,enter.parentElement); 158 | else if(enter.parentElement.nextElementSibling)list.insertBefore(frag,enter.parentElement.nextElementSibling); 159 | else list.appendChild(frag); 160 | }else if(enter.classList.contains("folder")&&dragged.classList.contains("folder")){ 161 | if(toTop)list.insertBefore(frag,enter); 162 | else if(enter.nextElementSibling)list.insertBefore(frag,enter.nextElementSibling); 163 | else list.appendChild(frag); 164 | }else if(enter.classList.contains("folder")){ 165 | enter.appendChild(frag); 166 | updateHeight(enter,true); 167 | if(dragged.classList.contains("changed"))document.getElementById(enter.id).classList.add("changedFolder"); 168 | }else if(folderId!=="root"){ 169 | if(toTop)document.getElementById(folderId).insertBefore(frag,enter); 170 | else if(enter.nextElementSibling)document.getElementById(folderId).insertBefore(frag,enter.nextElementSibling); 171 | else document.getElementById(folderId).appendChild(frag); 172 | updateHeight(document.getElementById(folderId),true); 173 | if(dragged.classList.contains("changed"))document.getElementById(folderId).classList.add("changedFolder"); 174 | }else if(toTop)list.insertBefore(frag,enter); 175 | else if(enter.nextElementSibling&&toBottom)list.insertBefore(frag,enter.nextElementSibling); 176 | else if(!enter.nextElementSibling&&toBottom)list.appendChild(frag); 177 | if(dragged.dataset.folder!=="root"){ 178 | updateHeight(document.getElementById(dragged.dataset.folder),true); 179 | unchangeFolder(dragged.dataset.folder); 180 | } 181 | dragged.dataset.folder=folderId; 182 | const ulli=document.querySelectorAll("ul li,ul ul"); 183 | [...ulli].forEach((value,i)=>{ 184 | value.dataset.row="a"+i; 185 | }); 186 | saveSort(); 187 | } 188 | 189 | function dragEnd(e){ 190 | dragIndicator.className="none"; 191 | if(hlFolder)hlFolder.removeAttribute("class"); 192 | startY=0; 193 | enter=false; 194 | dragged=false; 195 | } 196 | 197 | function addFolder(name){ 198 | name=name?name:i18n("newFolder"); 199 | let lastChild=list.lastElementChild, 200 | lastId=lastChild?lastChild.dataset.row.substr(1):-1; 201 | if(lastChild&&lastChild.classList.contains("folder")&&lastChild.childElementCount>1) 202 | lastId=lastChild.lastElementChild.dataset.row.substr(1); 203 | let iLi=document.createElement('ul'); 204 | iLi.id=`folder${new Date().getTime()}`; 205 | iLi.dataset.row=`a${parseInt(lastId)+1}`; 206 | iLi.dataset.folder="root"; 207 | iLi.draggable=true; 208 | iLi.addEventListener('dragstart',dragStart); 209 | iLi.className="folder"; 210 | let iA=document.createElement('a'); 211 | iA.textContent=name; 212 | iLi.addEventListener("click",e=>{ 213 | e.target.parentElement.classList.toggle("collapsed"); 214 | saveSort(); 215 | }); 216 | iLi.appendChild(iA); 217 | list.appendChild(iLi); 218 | saveSort(); 219 | statusbar(i18n("addedWebpage",name)); 220 | } 221 | 222 | function saveSort(){ 223 | let ulli=document.querySelectorAll("ul li,ul ul"), 224 | sort=[]; 225 | [...ulli].forEach((value,i)=>{ 226 | let type=value.classList.contains("folder")?"folder":"item", 227 | name=value.classList.contains("folder")?value.firstElementChild.textContent:"", 228 | collapsed=value.classList.contains("collapsed")?true:false; 229 | sort.push([value.id,value.dataset.folder,type,name,collapsed]) 230 | }); 231 | browser.storage.local.set({sort}).then(()=>{ 232 | browser.runtime.sendMessage({"listSite":true}).then(()=>{},err=>{console.warn(err);}); 233 | },err=>{ 234 | console.error(err); 235 | }); 236 | } 237 | -------------------------------------------------------------------------------- /src/view.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --text-color:#0c0c0d; 3 | --border-color:#ccc; 4 | --background-color:#f5f6f7; 5 | --time-color:#777; 6 | 7 | --neutral-color:#0c0c0d; 8 | --neutral-background:#0c0c0d1a; 9 | --neutral-hover:#0c0c0d33; 10 | --neutral-active:#0c0c0d4d; 11 | 12 | --negative-color:#fff; 13 | --negative-background:#ff0039; 14 | --negative-hover:#d70022; 15 | --negative-active:#a4000f; 16 | 17 | --ghost-hover:#dddedf; 18 | --ghost-active:#c6c7c8; 19 | 20 | --icon:url("icons/icon.svg"); 21 | --dropdown:url("icons/dropdown.svg#d"); 22 | --arrow:url("icons/arrow.svg#d"); 23 | --close:url("icons/close.svg#d"); 24 | --open:url("icons/open.svg"); 25 | 26 | --invert:invert(0); 27 | --brightness:brightness(1.0); 28 | --shadow-color:#888; 29 | } 30 | 31 | .dark:root { 32 | --text-color:#f9f9fa; 33 | --border-color:#0c0c0d; 34 | --background-color:#323234; 35 | --time-color:#444; 36 | 37 | --neutral-color:#f9f9fa; 38 | --neutral-background:#474749; 39 | --neutral-hover:#5a5a5c; 40 | --neutral-active:#6e6e70; 41 | 42 | --negative-color:#f9f9fa; 43 | --negative-background:#d70022; 44 | --negative-hover:#ff0039; 45 | --negative-active:#a4000f; 46 | 47 | --ghost-hover:#474749; 48 | --ghost-active:#5a5a5c; 49 | 50 | --icon:url("icons/icon.svg#w"); 51 | --dropdown:url("icons/dropdown.svg#l"); 52 | --arrow:url("icons/arrow.svg#l"); 53 | --close:url("icons/close.svg#l"); 54 | --open:url("icons/open.svg#l"); 55 | 56 | --invert:invert(1); 57 | --brightness:brightness(1.5); 58 | --shadow-color:#333; 59 | } 60 | 61 | 62 | @media (prefers-color-scheme: dark) { 63 | .auto:root { 64 | --text-color:#f9f9fa; 65 | --border-color:#0c0c0d; 66 | --background-color:#323234; 67 | --time-color:#444; 68 | 69 | --neutral-color:#f9f9fa; 70 | --neutral-background:#474749; 71 | --neutral-hover:#5a5a5c; 72 | --neutral-active:#6e6e70; 73 | 74 | --negative-color:#f9f9fa; 75 | --negative-background:#d70022; 76 | --negative-hover:#ff0039; 77 | --negative-active:#a4000f; 78 | 79 | --ghost-hover:#474749; 80 | --ghost-active:#5a5a5c; 81 | 82 | --icon:url("icons/icon.svg#w"); 83 | --dropdown:url("icons/dropdown.svg#l"); 84 | --arrow:url("icons/arrow.svg#l"); 85 | --close:url("icons/close.svg#l"); 86 | --open:url("icons/open.svg#l"); 87 | 88 | --invert:invert(1); 89 | --brightness:brightness(1.5); 90 | --shadow-color:#333; 91 | } 92 | } 93 | 94 | html, 95 | body{ 96 | height:100%; 97 | margin:0; 98 | padding:0; 99 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 100 | font-size:14px; 101 | color:var(--text-color); 102 | } 103 | 104 | #content{ 105 | height:100%; 106 | margin:0; 107 | padding:61px 0 0 0; 108 | box-sizing:border-box; 109 | } 110 | 111 | body.hiddenHeader #content{ 112 | padding-top:0; 113 | } 114 | 115 | #__wps_iframe{ 116 | height:100%; 117 | width:100%; 118 | border:none; 119 | display:block; 120 | } 121 | 122 | #header{ 123 | background-image:var(--icon); 124 | background-repeat:no-repeat; 125 | background-position:6px 6px; 126 | background-color:var(--background-color); 127 | border-bottom:1px solid #0078d7; 128 | box-shadow:0px 0px 10px var(--shadow-color); 129 | box-sizing:border-box; 130 | display:grid; 131 | grid-template-columns:minmax(100px,max-content) minmax(max-content,auto) max-content; 132 | grid-template-rows:60% 40%; 133 | grid-template-areas:"title set tabs" 134 | "last last tabs"; 135 | height:61px; 136 | position:fixed; 137 | top:0; 138 | left:0; 139 | width:100%; 140 | z-index:2147483647; 141 | transition:top 300ms; 142 | padding-left:60px; 143 | } 144 | 145 | .hiddenHeader #header{ 146 | top:-61px; 147 | transition:top 300ms; 148 | } 149 | 150 | .hiddenHeader.autoHidden #header{ 151 | transition:none; 152 | } 153 | 154 | h1#title{ 155 | grid-area:title; 156 | font-size:20px; 157 | font-style:italic; 158 | font-weight:400; 159 | line-height:36px; 160 | max-width:700px; 161 | white-space:nowrap; 162 | overflow:hidden; 163 | text-overflow:""; 164 | margin:0; 165 | padding-right:2px; 166 | } 167 | 168 | #controls{ 169 | grid-area:set; 170 | padding:7px 2px; 171 | } 172 | 173 | button{ 174 | border-radius:2px; 175 | cursor:pointer; 176 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 177 | font-size:12px; 178 | line-height:18px; 179 | margin:0 0 0 4px; 180 | border:none; 181 | } 182 | 183 | .popupFooter button{ 184 | padding:0 20px; 185 | line-height: 32px; 186 | font-size:13px; 187 | } 188 | 189 | #controls button{ 190 | padding:0 8px; 191 | line-height: 24px; 192 | } 193 | 194 | #current{ 195 | display:inline-block; 196 | border-radius:2px; 197 | padding:6px; 198 | height:30px; 199 | width:30px; 200 | box-sizing:border-box; 201 | cursor:pointer; 202 | vertical-align:top; 203 | } 204 | 205 | #currentIcon{ 206 | background-image:var(--open); 207 | background-repeat:no-repeat; 208 | background-position:center center; 209 | display:block; 210 | height:16px; 211 | filter:var(--brightness); 212 | } 213 | 214 | select#viewMode{ 215 | border-radius:2px; 216 | height:30px; 217 | width:180px; 218 | box-sizing:border-box; 219 | padding:3px; 220 | margin-right:4px; 221 | font-size:14px; 222 | font-family:Segoe UI,Tahoma,Helvetica Neue,Lucida Grande,Ubuntu,sans-serif; 223 | -moz-appearance:none; 224 | background-image:var(--dropdown); 225 | background-repeat:no-repeat; 226 | background-position:right 6px center; 227 | border:none; 228 | } 229 | 230 | select#viewMode option[disabled]{ 231 | display:none; 232 | } 233 | 234 | .neutral{ 235 | background-color:var(--neutral-background) !important; 236 | color:var(--neutral-color) !important; 237 | } 238 | .neutral:hover{ 239 | background-color:var(--neutral-hover) !important; 240 | } 241 | .neutral:active{ 242 | background-color:var(--neutral-active) !important; 243 | } 244 | 245 | .negative{ 246 | background-color:var(--negative-background) !important; 247 | color:var(--negative-color) !important; 248 | } 249 | .negative:hover{ 250 | background-color:var(--negative-hover) !important; 251 | } 252 | .negative:active{ 253 | background-color:var(--negative-active) !important; 254 | } 255 | 256 | #versionTime{ 257 | grid-area:last; 258 | color:var(--time-color); 259 | font-size:13px; 260 | background-image:url("icons/clock.svg"); 261 | background-size:16px; 262 | background-repeat:no-repeat; 263 | background-position:0 1px; 264 | padding-left:18px; 265 | cursor:default; 266 | filter:var(--invert); 267 | } 268 | 269 | #tabs{ 270 | grid-area:tabs; 271 | padding:15px 7px 0 0; 272 | } 273 | 274 | #deletePopup{ 275 | background:var(--background-color); 276 | border:1px solid var(--border-color); 277 | box-shadow:0 0 0 2000px #000c; 278 | padding:10px; 279 | position:fixed; 280 | box-sizing:border-box; 281 | z-index:2147483647; 282 | top:calc(50% - 50px); 283 | left:calc(50% - 200px); 284 | width:400px; 285 | opacity:1; 286 | transform:scale(1); 287 | transition:opacity 200ms, transform 160ms; 288 | } 289 | 290 | h2{ 291 | font-size:17px; 292 | font-weight:600; 293 | line-height:20px; 294 | margin:0 0 7px 0; 295 | } 296 | 297 | .popupFooter{ 298 | margin-top:7px; 299 | float:right; 300 | grid-column:2/3; 301 | justify-self:right; 302 | } 303 | 304 | .hidden{ 305 | display:none !important; 306 | } 307 | 308 | #toggleHeader{ 309 | height:24px; 310 | width:32px; 311 | box-sizing:border-box; 312 | position:absolute; 313 | right:calc(50% - 16px); 314 | top:60px; 315 | margin:-24px 0 0; 316 | background:var(--arrow) no-repeat center center; 317 | background-size:20px; 318 | padding:6px; 319 | transform:scale(1,-1); 320 | z-index:2147483647; 321 | border:none; 322 | } 323 | 324 | #toggleHeader:hover{ 325 | top:58px; 326 | } 327 | 328 | .hiddenHeader #toggleHeader{ 329 | background-color:var(--background-color); 330 | border:1px solid #0078d7; 331 | position:fixed; 332 | top:-3px; 333 | margin:0; 334 | opacity:.9; 335 | transform:scale(1,1); 336 | transition:margin-top 200ms 350ms; 337 | } 338 | 339 | .hiddenHeader #toggleHeader:hover{ 340 | top:-1px; 341 | opacity:1; 342 | } 343 | 344 | #highlight{ 345 | position:absolute; 346 | right:25px; 347 | top:70px; 348 | background-color:var(--background-color); 349 | border:1px solid var(--border-color); 350 | border-radius:2px; 351 | height:28px; 352 | min-width:210px; 353 | z-index:2147483647; 354 | -moz-user-select:none; 355 | opacity:.9; 356 | } 357 | 358 | #highlight #xtext{ 359 | line-height:28px; 360 | padding-left:7px; 361 | white-space:nowrap; 362 | } 363 | 364 | #prev, 365 | #next{ 366 | background:var(--background-color) var(--arrow) no-repeat center center; 367 | background-size:14px; 368 | height:28px; 369 | width:28px; 370 | float:left; 371 | border:none; 372 | border-radius:0; 373 | margin:0; 374 | } 375 | 376 | #prev{ 377 | transform:scale(1,-1); 378 | } 379 | 380 | #next{ 381 | width:30px; 382 | border-left:1px solid var(--border-color); 383 | border-right:1px solid var(--border-color); 384 | } 385 | 386 | #prev:hover, 387 | #next:hover{ 388 | background-color:var(--ghost-hover); 389 | } 390 | #prev:active, 391 | #next:active{ 392 | background-color:var(--ghost-active); 393 | } 394 | 395 | #close{ 396 | height:20px; 397 | width:20px; 398 | background-image:var(--close); 399 | background-size:16px; 400 | background-repeat:no-repeat; 401 | background-position:50%; 402 | float:right; 403 | margin:4px; 404 | } 405 | 406 | .ghost{ 407 | background-color:var(--background-color) !important; 408 | border:none !important; 409 | border-radius:2px; 410 | } 411 | 412 | .ghost:hover{ 413 | background-color:var(--ghost-hover) !important; 414 | } 415 | 416 | .ghost:active{ 417 | background-color:var(--ghost-active) !important; 418 | } 419 | 420 | #__wps_scrollbarMarkers{ 421 | position:fixed; 422 | bottom:0; 423 | right:0px; 424 | height:calc(100% - 61px); 425 | padding:0; 426 | pointer-events:none; 427 | box-sizing:border-box; 428 | opacity:.6; 429 | } 430 | 431 | .hiddenHeader #__wps_scrollbarMarkers{ 432 | height:100%; 433 | } 434 | 435 | #messageBar{ 436 | border-radius:2px; 437 | font-size:13px; 438 | line-height:24px; 439 | padding:0 4px 0 24px; 440 | display:inline-block; 441 | vertical-align:bottom; 442 | margin-left:4px; 443 | } 444 | 445 | #messageBar.warning{ 446 | background:#ffe900 url("icons/warning.svg") no-repeat 4px center; 447 | background-size:16px; 448 | color:#3e2800; 449 | } 450 | 451 | #deletePopup.fade{ 452 | opacity:0; 453 | transform:scale(.6); 454 | transition:opacity 200ms, transform 600ms; 455 | } 456 | -------------------------------------------------------------------------------- /src/view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
            10 | 35 |
            36 |

            37 |
            38 |
            39 | 41 |
            42 |
            43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/view.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | let localId, 4 | highlighted, 5 | prevHighlighted, 6 | filteredChanges, 7 | viewMode, 8 | iframe, 9 | uniqId; 10 | 11 | const extURL=browser.runtime.getURL(""); 12 | 13 | (function(){ 14 | const urlString=window.location.search; 15 | localId=parseInt(urlString.substr(1)); 16 | iframe=document.createElement("iframe"); 17 | iframe.id="__wps_iframe"; 18 | document.getElementById("content").appendChild(iframe); 19 | browser.storage.local.get("settings").then(result=>{ 20 | let settings=result.settings; 21 | document.documentElement.className=settings.theme?settings.theme:"auto"; 22 | if(settings.hideHeader)toggleHeader(true); 23 | document.getElementById("viewMode").value=settings.defaultView; 24 | document.getElementById("header").removeAttribute("class"); 25 | },err=>{ 26 | console.error(err); 27 | }); 28 | load(); 29 | translate(); 30 | document.getElementById("viewMode").addEventListener("change",e=>{load(e.target.value);}); 31 | document.getElementById("deleteButton").addEventListener("click",showDelete); 32 | document.getElementById("deleteCancel").addEventListener("click",e=>{e.target.offsetParent.classList.add("fade");}); 33 | document.getElementById("editButton").addEventListener("click",showEdit); 34 | document.getElementById("toggleHeader").addEventListener("click",()=>{toggleHeader();}); 35 | document.getElementById("prev").addEventListener("click",()=>{nextPrev(false);}); 36 | document.getElementById("next").addEventListener("click",()=>{nextPrev(true);}); 37 | document.getElementById("close").addEventListener("click",toggleNextPrev); 38 | })(); 39 | 40 | function nextPrev(next){ 41 | if(!filteredChanges.length||(filteredChanges.length===1&&highlighted===0))return; 42 | if(next){ 43 | if(highlighted0){ 52 | prevHighlighted=prevHighlighted!==undefined?highlighted:0; 53 | highlighted=highlighted!==undefined?highlighted-1:0; 54 | }else{ 55 | prevHighlighted=0; 56 | highlighted=filteredChanges.length-1; 57 | } 58 | } 59 | document.getElementById("xtext").textContent=i18n("changeOf",[highlighted+1,filteredChanges.length]); 60 | filteredChanges[highlighted].classList.add("hlc"); 61 | if(prevHighlighted!==undefined)filteredChanges[prevHighlighted].classList.remove("hlc"); 62 | filteredChanges[highlighted].scrollIntoView({behavior:"smooth",block:"center"}); 63 | } 64 | 65 | function toggleNextPrev(show,autoScroll){ 66 | if(show===true){ 67 | document.getElementById("highlight").removeAttribute("class"); 68 | if(autoScroll)setTimeout(()=>{nextPrev(true);},500); 69 | }else{ 70 | document.getElementById("highlight").className="hidden"; 71 | if(highlighted!==undefined)filteredChanges[highlighted].classList.remove("hlc"); 72 | } 73 | } 74 | 75 | function showDelete(){ 76 | document.getElementById("deleteOk").addEventListener("click",deleteSite); 77 | document.getElementById("deletePopup").classList.remove("fade"); 78 | document.getElementById("deleteTitle").textContent=document.title; 79 | } 80 | 81 | function deleteSite(){ 82 | browser.storage.local.get(['sites','sort']).then(result=>{ 83 | let sites=result.sites, 84 | sort=result.sort, 85 | sSort; 86 | sites.splice(localId,1); 87 | if(sort){ 88 | sort.forEach((value,i)=>{ 89 | const id=parseInt(value[0].substr(4)); 90 | if(id===localId)sSort=i; 91 | else if(id>localId)sort[i][0]=`item${id-1}`; 92 | }); 93 | sort.splice(sSort,1); 94 | } 95 | browser.storage.local.set({sites,sort}).then(async()=>{ 96 | await deleteChanges(uniqId); 97 | browser.runtime.sendMessage({ 98 | "listSite":true, 99 | "deletedSite":true, 100 | "id":localId 101 | }).then(()=>{},err=>{ 102 | console.warn(err); 103 | }); 104 | browser.tabs.getCurrent().then(tab=>{browser.tabs.remove(tab.id);}); 105 | },err=>{ 106 | console.error(err); 107 | }); 108 | },err=>{ 109 | console.error(err); 110 | }); 111 | } 112 | 113 | function showEdit(){ 114 | document.getElementById("deletePopup").classList.add("fade"); 115 | browser.runtime.sendMessage({ 116 | "showWpsPopup":true, 117 | "mode":"edit", 118 | "editId":localId 119 | }).then(()=>{},err=>{ 120 | console.warn(err); 121 | }); 122 | } 123 | 124 | function partHtml(html,selectorCss){ 125 | let parser=new DOMParser(), 126 | doc=parser.parseFromString(html,"text/html"), 127 | selectedElement=doc.querySelector(selectorCss); 128 | if(selectedElement){ 129 | return selectedElement.outerHTML; 130 | }else{ 131 | return html; 132 | } 133 | } 134 | 135 | function load(type){ 136 | browser.storage.local.get(['sites','settings']).then(async result=>{ 137 | const sites=result.sites, 138 | settings=result.settings, 139 | sId=sites[localId], 140 | cId=await getChanges(sId.uniq), 141 | newHtml=cId.html, 142 | oldHtml=cId?cId.oldHtml:"", 143 | diffStringX=settings.diffOld?diffString2old:diffString2; 144 | 145 | const pageSettings={ 146 | defaultView:0, 147 | highlightOutsideChanges:0, 148 | showNextPrev:0, 149 | scrollToFirstChange:0, 150 | skipMinorChanges:0, 151 | scrollbarMarkers:0, 152 | hideHeader:0 153 | }; 154 | Object.entries(pageSettings).forEach(e=>{ 155 | if(typeof sId.settings==="undefined"||typeof sId.settings[e[0]]==="undefined"||sId.settings[e[0]]==="global"){ 156 | pageSettings[e[0]]=settings[e[0]]; 157 | }else{ 158 | pageSettings[e[0]]=sId.settings[e[0]] 159 | } 160 | }); 161 | type=type||pageSettings.defaultView; 162 | uniqId=sId.uniq; 163 | document.getElementById("favicon").href=sId.favicon; 164 | document.getElementById("current").href=sId.url; 165 | document.getElementById("title").textContent=sId.title; 166 | document.title=sId.title; 167 | 168 | let diffString; 169 | if((type==="raw"||type==="news"||type==="deleted")&&sId.paritialMode&&sId.cssSelector&&!pageSettings.highlightOutsideChanges){ 170 | diffString=diffStringX(partHtml(oldHtml,sId.cssSelector),partHtml(newHtml,sId.cssSelector)); 171 | }else{ 172 | diffString=diffStringX(oldHtml,newHtml); 173 | } 174 | 175 | const light=cId?diffString.n:newHtml, 176 | news=cId?diffString.c:"", 177 | deleted=cId?diffString.o:"", 178 | url=sId.url.split("/"), 179 | url2=url[0]+"//"+url[2]+"/", 180 | lastScan=[realDate(sId.date),realTime(sId.time)], 181 | oldTime=sId.oldTime?[realDate(sId.oldTime[0])," "+realTime(sId.oldTime[1])]:"", 182 | newTime=sId.newTime?[realDate(sId.newTime[0])," "+realTime(sId.newTime[1])]:""; 183 | let parser=new DOMParser(), 184 | doc; 185 | if(oldHtml)enableBtn("oldHtml"); 186 | if(news)enableBtn("news"); 187 | if(deleted)enableBtn("deleted"); 188 | toggleNextPrev(); 189 | toggleScrollbarMarkers(); 190 | highlighted=undefined; 191 | prevHighlighted=undefined; 192 | 193 | if(pageSettings.hideHeader){ 194 | toggleHeader(true); 195 | }else if(document.body.classList.contains("hiddenHeader")){ 196 | toggleHeader(); 197 | } 198 | document.getElementById("viewMode").value=type; 199 | switch(type){ 200 | case "light": 201 | doc=parser.parseFromString(light,"text/html"); 202 | let style=document.createElement("style"); 203 | let cssSelector=(!pageSettings.highlightOutsideChanges&&sId.paritialMode&&sId.cssSelector&&!sId.saveOnlyPart)?sId.cssSelector:""; 204 | if(sId.saveOnlyPart&&sId.settings.highlightOutsideChanges===false)cssSelector=sId.cssSelector; 205 | style.textContent=` 206 | ${cssSelector} .__wps_changes a{ 207 | background:#ffa !important; 208 | } 209 | ${cssSelector} .__wps_changes.hlc a, 210 | ${cssSelector} .__wps_changes.hlc a .__wps_changes{ 211 | background:#00feff !important; 212 | color:#000 !important; 213 | } 214 | ${cssSelector} .__wps_changes{ 215 | background:#ffe900 !important; 216 | color:#000 !important; 217 | border:0 !important; 218 | padding:0 !important; 219 | margin:0 !important; 220 | opacity:1 !important; 221 | overflow:visible !important; 222 | outline:none !important; 223 | } 224 | ${cssSelector} .__wps_changes a, 225 | ${cssSelector} a .__wps_changes{ 226 | color:#006abc !important; 227 | } 228 | ${cssSelector} .__wps_changes:hover a, 229 | ${cssSelector} a .__wps_changes:hover{ 230 | color:#00f !important; 231 | background:#ffe100 !important; 232 | } 233 | ${cssSelector} .__wps_changes.hlc{ 234 | background-color:#00feff !important; 235 | color:#000 !important; 236 | } 237 | `; 238 | doc.head.appendChild(style); 239 | toggleNextPrev(pageSettings.showNextPrev,pageSettings.scrollToFirstChange); 240 | if(pageSettings.scrollbarMarkers){ 241 | setTimeout(()=>{toggleScrollbarMarkers(true)},300); 242 | setTimeout(()=>{toggleScrollbarMarkers(true)},2000); 243 | } 244 | document.getElementById("versionTime").textContent=newTime?i18n("newVersion")+": "+newTime:i18n("lastScan",lastScan); 245 | break; 246 | case "news": 247 | doc=parser.parseFromString(news,"text/html"); 248 | document.getElementById("versionTime").textContent=newTime?i18n("newVersion")+": "+newTime:i18n("lastScan",lastScan); 249 | break; 250 | case "deleted": 251 | doc=parser.parseFromString(deleted,"text/html"); 252 | document.getElementById("versionTime").textContent=oldTime?i18n("oldVersion")+": "+oldTime:i18n("lastScan",lastScan); 253 | break; 254 | case "newHtml": 255 | doc=parser.parseFromString(newHtml,"text/html"); 256 | document.getElementById("versionTime").textContent=newTime?i18n("newVersion")+": "+newTime:i18n("lastScan",lastScan); 257 | break; 258 | case "oldHtml": 259 | doc=parser.parseFromString(oldHtml,"text/html"); 260 | document.getElementById("versionTime").textContent=oldTime?i18n("oldVersion")+": "+oldTime:i18n("lastScan",lastScan); 261 | break; 262 | case "raw": 263 | let css=document.createElement("link"); 264 | css.rel="stylesheet"; 265 | css.href=extURL+"viewIframe.css"; 266 | let divNews=document.createElement("div"), 267 | divDeleted=document.createElement("div"); 268 | divNews.id="__wps_rawNews"; 269 | divDeleted.id="__wps_rawDeleted"; 270 | divNews.textContent=news; 271 | divDeleted.textContent=deleted.replace(/|<\/del>/g,""); 272 | doc=document.implementation.createHTMLDocument(); 273 | doc.body.id="__wps_raw"; 274 | doc.body.appendChild(divDeleted); 275 | doc.body.appendChild(divNews); 276 | doc.head.appendChild(css); 277 | document.getElementById("versionTime").textContent=newTime?i18n("oldVersion")+": "+oldTime+" | "+i18n("newVersion")+": "+newTime:i18n("lastScan",lastScan); 278 | break; 279 | } 280 | let base=doc.getElementsByTagName("base")[0]; 281 | if(base){ 282 | if(base.getAttribute("href")=="/"){ 283 | base.href=url2; 284 | }else if(!base.href.startsWith("http")){ 285 | base.href=sId.url; 286 | } 287 | }else{ 288 | base=document.createElement("base"); 289 | base.href=sId.url; 290 | if(doc.head)doc.head.insertBefore(base,doc.head.firstElementChild); 291 | } 292 | base.target="_top"; 293 | if(doc.head){ 294 | const metaRefresh=doc.head.querySelector("meta[http-equiv=refresh]"); 295 | if(metaRefresh)metaRefresh.remove(); 296 | } 297 | iframe.contentDocument.documentElement.remove(); 298 | iframe.contentDocument.appendChild(doc.documentElement); 299 | 300 | let selectedElement; 301 | if(sId.paritialMode&&sId.cssSelector&&(type==="light"||type==="newHtml"||type==="oldHtml")&&sId.saveOnlyPart!==true&&sId.deleteScripts!==true){ 302 | selectedElement=iframe.contentDocument.querySelector(sId.cssSelector); 303 | if(!selectedElement){ 304 | let notification=document.getElementById("messageBar"); 305 | notification.textContent=i18n("warningPart"); 306 | notification.className="warning"; 307 | }else{ 308 | document.getElementById("messageBar").className="hidden"; 309 | } 310 | }else{ 311 | document.getElementById("messageBar").className="hidden"; 312 | } 313 | if(sId.broken>1){ 314 | let notification=document.getElementById("messageBar"); 315 | notification.textContent=i18n("warningBroken",sId.broken); 316 | notification.className="warning"; 317 | } 318 | 319 | viewMode=type; 320 | if(type==="light"){ 321 | const allChanges=iframe.contentDocument.getElementsByClassName("__wps_changes"); 322 | if(pageSettings.skipMinorChanges){ 323 | filteredChanges=[...allChanges].filter((element,index,array)=>{ 324 | return ((element.childNodes.length&&element.childNodes[0].length>1)||element.children.length); 325 | }); 326 | }else{ 327 | filteredChanges=allChanges; 328 | } 329 | if(!pageSettings.highlightOutsideChanges&&selectedElement){ 330 | filteredChanges=[...filteredChanges].filter((element,index,array)=>{ 331 | return (selectedElement.contains(element)); 332 | }); 333 | } 334 | document.getElementById("xtext").textContent=i18n("numberOfChanges",filteredChanges.length); 335 | } 336 | document.getElementById("versionTime").title=i18n("lastScan",lastScan)+"\u000d"+i18n("newVersion")+": "+newTime+"\u000d"+i18n("oldVersion")+": "+oldTime; 337 | },err=>{ 338 | console.error(err); 339 | }); 340 | } 341 | 342 | function realDate(e){ 343 | const m=Math.trunc(e), 344 | month=i18n("monthList").split(","), 345 | d=Math.round((e-m)*100); 346 | return `${d} ${month[m]}`; 347 | } 348 | 349 | function realTime(e){ 350 | e+=""; 351 | let h=e.split(".")[0], 352 | m=e.split(".")[1]; 353 | m=m?m:"00"; 354 | h=h.length===1?"0"+h:h; 355 | m=m.length===1?m+"0":m.substr(0,2); 356 | return `${h}:${m}`; 357 | } 358 | 359 | function i18n(e,s1){ 360 | return browser.i18n.getMessage(e,s1); 361 | } 362 | 363 | browser.runtime.onMessage.addListener(run); 364 | function run(m){ 365 | if(m.deletedSite){ 366 | let dId=parseInt(m.id); 367 | if(dId===localId){ 368 | browser.tabs.getCurrent().then(tab=>{browser.tabs.remove(tab.id);}); 369 | }else if(dIdiframe.contentDocument.body.clientHeight&&filteredChanges&&filteredChanges.length){ 415 | let canvas=document.getElementById("__wps_scrollbarMarkers"); 416 | if(!canvas){ 417 | canvas=document.createElement("canvas"); 418 | canvas.width=1; 419 | canvas.id="__wps_scrollbarMarkers"; 420 | canvas.style.width=window.innerWidth-iframe.contentDocument.body.scrollWidth+"px"; 421 | if(window.navigator.appVersion.includes("Windows")) 422 | canvas.style.padding="16px 0"; 423 | document.body.appendChild(canvas); 424 | } 425 | const ctx=canvas.getContext('2d'); 426 | ctx.clearRect(0,0,canvas.width,canvas.height); 427 | canvas.height=iframe.contentDocument.body.scrollHeight; 428 | ctx.fillStyle="rgb(0,144,255)"; 429 | [...filteredChanges].forEach(e=>{ 430 | const elm=e.getBoundingClientRect(); 431 | const top=elm.top+iframe.contentWindow.scrollY; 432 | const height=elm.height; 433 | ctx.fillRect(0,top,1,height); 434 | }); 435 | }else{ 436 | if(document.getElementById("__wps_scrollbarMarkers")){ 437 | document.getElementById("__wps_scrollbarMarkers").remove(); 438 | } 439 | } 440 | } 441 | -------------------------------------------------------------------------------- /src/viewIframe.css: -------------------------------------------------------------------------------- 1 | #__wps_raw{ 2 | display:grid; 3 | grid-template-columns:50% 50%; 4 | margin:0; 5 | } 6 | 7 | #__wps_rawNews{ 8 | background-color:#aeffae; 9 | padding:7px 15px; 10 | overflow-wrap:break-word; 11 | } 12 | 13 | #__wps_rawDeleted{ 14 | background-color:#fca2af; 15 | padding:7px 15px; 16 | overflow-wrap:break-word; 17 | } 18 | -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.0.2 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.0.2 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.0.4 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.0.4 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.1.2 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.1.2 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.2.1 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.2.1 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.2.5 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.2.5 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.3.6 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.3.6 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.4.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.4.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.5.1 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.5.1 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.5.2 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.5.2 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.5.5 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.5.5 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.5.6 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.5.6 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.6.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.6.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.6.5 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.6.5 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.6.6 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.6.6 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.6.7 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.6.7 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.7.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.7.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.7.2 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.7.2 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.7.3 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.7.3 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.7.4 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.7.4 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.8.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.8.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.8.1 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.8.1 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.8.5 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.8.5 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.8.6 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.8.6 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.1 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.1 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.2 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.2 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.3 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.3 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.4 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.4 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.5 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.5 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.6 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.6 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 1.9.6.1 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 1.9.6.1 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 2.0.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 2.0.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 2.0.1 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 2.0.1 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 2.1.0 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 2.1.0 signed.xpi -------------------------------------------------------------------------------- /xpi/Web Pages Scanner 2.1.5 signed.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WaldiPL/webpageScanner/63c77c4b62501b0b52e0a3dd384a141bca3ca3de/xpi/Web Pages Scanner 2.1.5 signed.xpi --------------------------------------------------------------------------------