add and remove elements from watch list
This commit is contained in:
2
.haxerc
2
.haxerc
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "4.2.5",
|
||||
"version": "4.3.1",
|
||||
"resolveLibs": "scoped"
|
||||
}
|
||||
11
build.hxml
11
build.hxml
@@ -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/\*
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
@@ -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
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
BIN
icons/spiral-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
11
src/refresh/BackgroundMain.hx
Normal file
11
src/refresh/BackgroundMain.hx
Normal 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();
|
||||
}
|
||||
}
|
||||
104
src/refresh/BackgroundMain_.kiss
Normal file
104
src/refresh/BackgroundMain_.kiss
Normal 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
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
package template;
|
||||
package refresh;
|
||||
|
||||
class Main {
|
||||
static function main() {
|
||||
|
||||
@@ -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
8
src/refresh/Message.hx
Normal file
@@ -0,0 +1,8 @@
|
||||
package refresh;
|
||||
|
||||
typedef Message = {
|
||||
action:String,
|
||||
url:String,
|
||||
selector:String,
|
||||
?innerHTML:String
|
||||
};
|
||||
44
src/refresh/WatchList.kiss
Normal file
44
src/refresh/WatchList.kiss
Normal 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))))))
|
||||
Reference in New Issue
Block a user