add and remove elements from watch list

This commit is contained in:
2024-03-06 13:33:11 +01:00
parent 7d77005edb
commit 99ac0c4925
14 changed files with 235 additions and 17 deletions

View File

@@ -1,4 +1,4 @@
{
"version": "4.2.5",
"version": "4.3.1",
"resolveLibs": "scoped"
}

View File

@@ -3,6 +3,13 @@
-cp externs
-cp src
-dce full
--main template.Main
--each
--main refresh.Main
--js bin/main.js
-cmd cp node_modules/webextension-polyfill/dist/browser-polyfill.js* bin/ && zip -r template.zip . -x *.git* -x *.hxml -x *.zip -x src/\* -x node_modules/\* -x libs/\* -x test.sh -x externs/\*
--next
--main refresh.BackgroundMain
--js bin/background.js
-cmd cp node_modules/webextension-polyfill/dist/browser-polyfill.js* bin/ && zip -r refresh.zip . -x *.git* -x *.hxml -x *.zip -x src/\* -x node_modules/\* -x libs/\* -x test.sh -x externs/\*

View File

@@ -1,5 +1,5 @@
# @install: lix --silent download "haxelib:/haxe-strings#7.0.2" into haxe-strings/7.0.2/haxelib
-cp ${HAXE_LIBCACHE}/haxe-strings/7.0.2/haxelib/src/
-D haxe-strings=7.0.2
--macro hx.strings.internal.Macros.addDefines()
--macro hx.strings.internal.Macros.configureNullSafety()
# @install: lix --silent download "haxelib:/haxe-strings#7.0.3" into haxe-strings/7.0.3/haxelib
-cp ${HAXE_LIBCACHE}/haxe-strings/7.0.3/haxelib/src/
-D haxe-strings=7.0.3
--macro hx.strings.internal.Macros.addDefines()
--macro hx.strings.internal.Macros.configureNullSafety()

View File

@@ -1,4 +1,4 @@
# @install: lix --silent download "gh://github.com/kiss-lang/kiss-firefox#097ee02954f9ff4240a4615fbb36d6445f36bb63" into kiss-firefox/0.0.0/github/097ee02954f9ff4240a4615fbb36d6445f36bb63
# @install: lix --silent download "gh://github.com/kiss-lang/kiss-firefox#34e188a49594a932fe684814f523b2e05c8ec4a5" into kiss-firefox/0.0.0/github/34e188a49594a932fe684814f523b2e05c8ec4a5
-lib kiss
-cp ${HAXE_LIBCACHE}/kiss-firefox/0.0.0/github/097ee02954f9ff4240a4615fbb36d6445f36bb63/src/
-cp ${HAXE_LIBCACHE}/kiss-firefox/0.0.0/github/34e188a49594a932fe684814f523b2e05c8ec4a5/src/
-D kiss-firefox=0.0.0

View File

@@ -1,12 +1,12 @@
# @install: lix --silent download "gh://github.com/kiss-lang/kiss#a6c0cf88c6a02aa7845dca7c5c5025b915b78fbc" into kiss/0.0.1/github/a6c0cf88c6a02aa7845dca7c5c5025b915b78fbc
# @run: haxelib run-dir kiss "${HAXE_LIBCACHE}/kiss/0.0.1/github/a6c0cf88c6a02aa7845dca7c5c5025b915b78fbc"
# @install: lix --silent download "gh://github.com/kiss-lang/kiss#771652b7535881726b003882d23c25b0322ca8e2" into kiss/0.0.1/github/771652b7535881726b003882d23c25b0322ca8e2
# @run: haxelib run-dir kiss "${HAXE_LIBCACHE}/kiss/0.0.1/github/771652b7535881726b003882d23c25b0322ca8e2"
-lib haxe-strings
-lib hscript
-lib tink_json
-lib tink_macro
-lib tink_syntaxhub
-lib uuid
-cp ${HAXE_LIBCACHE}/kiss/0.0.1/github/a6c0cf88c6a02aa7845dca7c5c5025b915b78fbc/src/
-cp ${HAXE_LIBCACHE}/kiss/0.0.1/github/771652b7535881726b003882d23c25b0322ca8e2/src
-D kiss=0.0.1
-w -WUnusedPattern
--macro kiss.KissFrontend.use()

BIN
icons/spiral-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
icons/spiral-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,5 +1,4 @@
{
"manifest_version": 2,
"name": "refresh",
"version": "0.0",
@@ -10,10 +9,37 @@
"48": "icons/icon-48.png"
},
"browser_specific_settings": {
"gecko": {
"id": "{d0aa92ad-6c04-4fdb-9981-a8fec1c3a93f}"
}
},
"background": {
"scripts": [
"bin/browser-polyfill.js",
"bin/background.js"
]
},
"browser_action": {
"default_icon": {
"16": "icons/spiral-16.png",
"32": "icons/spiral-32.png"
},
"default_title": "RefreshAll"
},
"content_scripts": [
{
"matches": [],
"matches": ["<all_urls>"],
"js": ["bin/browser-polyfill.js", "bin/main.js"]
}
],
"permissions": [
"<all_urls>",
"storage",
"menus"
]
}

View File

@@ -0,0 +1,11 @@
package refresh;
import haxe.Constraints;
import haxe.io.Path;
import js.lib.Promise;
class BackgroundMain {
static function main() {
BackgroundMain_.main();
}
}

View File

@@ -0,0 +1,104 @@
(import kiss_firefox.API)
(import refresh.WatchList)
(import refresh.Message)
(API.browser.menus.create
(object
id "watch_element"
title "Watch this element"
contexts ["link" "page"]))
(API.browser.menus.create
(object
id "unwatch_element"
title "Unwatch this element"
contexts ["link" "page"]))
// function source: https://stackoverflow.com/a/30484878 CC-BY-SA 3.0
(var getSelectorFunction "
function getSelector(node) {
var id = node.getAttribute('id');
if (id) {
return '#'+id;
}
var path = '';
while (node) {
var name = node.localName;
var parent = node.parentNode;
if (!parent) {
path = name + ' > ' + path;
continue;
}
if (node.getAttribute('id')) {
path = '#' + node.getAttribute('id') + ' > ' + path;
break;
}
var sameTagSiblings = [];
var children = parent.childNodes;
children = Array.prototype.slice.call(children);
children.forEach(function(child) {
if (child.localName == name) {
sameTagSiblings.push(child);
}
});
// if there are more than one children of that type use nth-of-type
if (sameTagSiblings.length > 1) {
var index = sameTagSiblings.indexOf(node);
name += ':nth-of-type(' + (index + 1) + ')';
}
if (path) {
path = name + ' > ' + path;
} else {
path = name;
}
node = parent;
}
return path;
}
")
(API.browser.menus.onClicked.addListener ->[info tab] {
(case info.menuItemId
("watch_element"
(API.browser.tabs.executeScript tab.id
(object
frameId info.frameId
code "
$getSelectorFunction
var element = browser.menus.getTargetElement(${info.targetElementId});
browser.runtime.sendMessage({'action': 'addToWatchList', 'url': window.location.href, 'selector': getSelector(element), 'innerHTML': element.innerHTML});
")))
("unwatch_element"
(API.browser.tabs.executeScript tab.id
(object
frameId info.frameId
code "
$getSelectorFunction
var element = browser.menus.getTargetElement(${info.targetElementId});
browser.runtime.sendMessage({'action': 'removeFromWatchList', 'url': window.location.href, 'selector': getSelector(element)});
"
)))
(never otherwise))
})
(API.browser.runtime.onMessage.addListener ->[:Message message sender sendResponse] {
(case message
((objectWith [action "addToWatchList"] url selector innerHTML)
(WatchList.add url selector innerHTML))
((objectWith [action "removeFromWatchList"] url selector)
(WatchList.remove url selector))
(never otherwise))
null
})

View File

@@ -1,4 +1,4 @@
package template;
package refresh;
class Main {
static function main() {

View File

@@ -1,2 +1,20 @@
(import kiss_firefox.API)
(set js.Lib.global.document.body.style.border "5px solid red")
(import js.Browser)
(import refresh.WatchList)
(Browser.window.addEventListener "load" ->{
(let [url Browser.window.location.href]
(WatchList.forEach url
->selector {
(whenLet [element (Browser.window.document.querySelector selector)]
(WatchList.update url selector element.innerHTML
// changed
->[oldHTML newHTML] {
}
// no change
->{
(set element.style.color "gray")
}))
}))
})

8
src/refresh/Message.hx Normal file
View File

@@ -0,0 +1,8 @@
package refresh;
typedef Message = {
action:String,
url:String,
selector:String,
?innerHTML:String
};

View File

@@ -0,0 +1,44 @@
(import kiss_firefox.API)
(import haxe.Serializer)
(import haxe.Unserializer)
(defMacro withWatchList [listSymbol &body body]
`(awaitLet [_listObj (API.browser.storage.sync.get (object watchList (new Map<String,Array<Dynamic>>)))
&sync :haxe.DynamicAccess<Dynamic> ,listSymbol (dictGet _listObj "watchList")]
,@body
(API.browser.storage.sync.set (object watchList ,listSymbol))
null))
(function :Void add [:String url :String selector :String innerHTML]
(withWatchList wl
(ifLet [urlList (dictGet wl url)]
(urlList.push (objectWith selector innerHTML))
(dictSet wl url [(objectWith selector innerHTML)]))))
(function :Void remove [:String url :String selector]
(withWatchList wl
(whenLet [urlList (dictGet wl url)]
(doFor [idx obj] (enumerate (cast urlList Array<Dynamic>))
(when (= obj.selector selector)
(urlList.splice idx 1)
(break))))))
(function :Void forEach [:String url :String->Void operation]
(withWatchList wl
(whenLet [urlList (dictGet wl url)]
(doFor obj (cast urlList Array<Dynamic>)
(operation obj.selector)))))
(function :Void update [:String url :String selector :String innerHTML :(String,String)->Void onChange :Void->Void onSame]
(withWatchList wl
(whenLet [urlList (dictGet wl url)]
(print urlList)
(doFor obj (cast urlList Array<Dynamic>)
(when (= obj.selector selector)
(if (= innerHTML obj.innerHTML)
(onSame)
{
(onChange obj.innerHTML innerHTML)
(set obj.innerHTML innerHTML)
})
(break))))))