kiến thức Tổng hợp những addon chất cho Firefox / Chromium

các bác cho em hỏi có addon nào tự động copy đoạn text và lưu hình ảnh của một bài báo về máy tính không ạ em cảm ơn
 
Cập nhập phiên bản 1.2, không có gì mới cả ngoài thêm sẵn 8 hướng và hướng dẫn bật 8 hướng: https://voz.vn/t/tong-hop-nhung-addon-chat-cho-firefox-pc-mobile.682181/post-27790639

Bật sẵn 8 hướng hay không thì các bạn @nhoxbuondkny @trym to nhat voz @vincvn @Kawaii93 @pTalent
cho ý kiến xem chứ mình mặc định để 4 hướng, bật rất dễ thôi.
4 hướng là đủ rồi, ai muốn 8 hướng thì để họ tự sửa lại script thôi.
 
Cập nhập thông tin về Floorp bản mới sắp tới 11.4.0, Private Container (chính là giống addon Temporary Container), nghĩa là cái container sẽ tự xóa trắng sau khi tắt đi mở lại:


Và Profile Switcher để không phải vào about:profiles nữa:


Đang hóng native tải đa luồng với PWA.

Cũng hóng tiếp Floorp nó lên Firefox 117 hay 118 để hưởng lợi vụ tăng tốc của Firefox, Floorp hiện tại là dựa trên Firefox ESR 115, và nó đã nhanh gấp x2 115, nếu nó hấp thụ tinh túy từ 117 và 118 thì khó mà tưởng tượng.
Hấp dẫn quá sếp ơi,
 
các bác cho em hỏi có addon nào tự động copy đoạn text và lưu hình ảnh của một bài báo về máy tính không ạ em cảm ơn
Cái copy đoạn text khi bôi đen mình nhớ trong thread này có bạn nào từng chia sẻ, bạn thử search thread với từ khóa copy script xem.

Còn cái lưu ảnh bài báo thì không cần addon do Firefox hỗ trợ sẵn:
  • Chuột phải
  • Take Screenshot
  • Save fullpage

1695010340112.png
 
@toi la gay :sosad: bác ơi bản 1.2 bị gì ấy e không xài được cop bản 1.1 thì oke
View attachment 2078427
Đã cập nhập bản 1.3, sửa lỗi này kèm với làm theo một số khuyến nghị từ Firemonkey (thằng này rất tuyệt khi dùng để code, nó chỉ tận răng mình làm gì sai):

JavaScript:
// ==UserScript==
// @name        Handlers Helper
// @namespace   Violentmonkey Scripts
// @include       http*://*/*
// @grant       none
// @version     1.3
// @author      -
// @description Helper for protocol_hook.lua
// ==/UserScript==

function attachDrag(elem) {

function GM_btoaUrl(url) {
    return btoa(url).replace(/\//g, "_").replace(/\+/g, "-").replace(/\=/g, "");
}

    function EA(attr, type) {
        console.log(attr, type);
        var url;
        if (attr.startsWith('http')) {
            url = attr;
        }
        if (url == '') {
            url = location.href;
        }
        var subs = '';
        var s = url;

            var app = 'play';
            if (type != 'vid') {
                var app = type.toLowerCase();
            }
            var bs = GM_btoaUrl(s);
            var url2 = 'mpv://' + app + '/' + bs + '/' + "?referer=" + GM_btoaUrl(location.href);
            if (subs != '') {
                url2 = url2 + '?subs=' + GM_btoaUrl(subs);
            }
            //alert(url2);
            location.href = url2;
    }

    function getDirection(x, y, cx, cy) {
        /*=================
        |                 |
        | 1↖   2↑   3↗ |
        |                 |
        | 4←    5    6→ |
        |                 |
        | 7↙   8↓   9↘ |
        |                 |
        |=================*/
        let d, t;
        if ((cx - x) >= -50 && (cx - x) <= 50 && (cy - y) >= -50 && (cy - y) <= 50) {return 5;}
        // Change (4 == 4) to (8 == 4) to enable 8 directions
        if (4 == 4) { //4 directions
            if (Math.abs(cx - x) < Math.abs(cy - y)) {
                d = cy > y ? "8" : "2";
            } else {
                d = cx > x ? "6" : "4";
            }
        } else { //8 directions
            t = (cy - y) / (cx - x);
            if (-0.4142 <= t && t < 0.4142) d = cx > x ? '6' : "4";
            else if (2.4142 <= t || t < -2.4142) d = cy > y ? '8' : '2';
            else if (0.4142 <= t && t < 2.4142) d = cx > x ? '9' : '1';
            else d = cy > y ? '7' : '3';
        }
        return d;
    }
    elem.addEventListener('dragstart', function (e) {
        //console.log(e.target);
        //console.log(e.target.shadowRoot);
        /*if (e.target.nodeName != "A") {
        e.stopPropagation();
        e.stopImmediatePropagation();
        //e.preventDefault();
        }*/
        console.log('dragstart');
        var x1 = e.clientX;
        var y1 = e.clientY;
        var dragend = elem.addEventListener('dragend', function doEA(e) {
            var x2 = e.clientX;
            var y2 = e.clientY;
            var direction = getDirection(x1, y1, x2, y2);
            //if ((x2 - x1) >= -50 && (x2 - x1) <= 50 && (y2 - y1) >= -50 && (y2 - y1) <= 50) {direction = 5;console.log(5);}
            //if (e.target.nodeName == "A" && e.target.href.match(/youtube.com|youtu.be|streamable.com/)) {
            if (direction == 6) { //right
                console.log('MPV :' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                EA(e.target.href, 'vid');
            } else if (direction == 4) { //left
                console.log('Streamlink: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                EA(e.target.href, 'stream');
            } else if (direction == 2) { //up
                console.log('Open: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                window.open(e.target.href, '_blank');
            } else if (direction == 8) { //down
                console.log('YTDL: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                EA(e.target.href, 'ytdl');
            } else if (direction == 1) { //up left
                console.log('DUMMY: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                //EA(e.target.href, 'ytdl');
            } else if (direction == 3) { //up right
                console.log('DUMMY: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                //EA(e.target.href, 'ytdl');
            } else if (direction == 7) { //down left
                console.log('DUMMY: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                //EA(e.target.href, 'ytdl');
            } else if (direction == 9) { //down right
                console.log('DUMMY: ' + e.target.href);
                console.log(x1, y1, x2, y2, direction);
                //EA(e.target.href, 'ytdl');
            }
            //}
            console.log(direction);
            this.removeEventListener('dragend', doEA);
        }, false);
    }, false);
}

attachDrag(document);
var attachedeles = [];
document.addEventListener('mouseover', function(e) {
  if (e.target.shadowRoot) {
    if (attachedeles.includes(e.target) == false) {
      console.log(attachedeles);
      attachedeles.push(e.target);
      attachDrag(e.target.shadowRoot);
    }
  }
});

Có nên upload lên Greasyfork.org cho tiện cập nhập không nhỉ ?
 
Góp ý cho Khầy Gây là nên chuyển về dạng switch case chứ nhìn script khầy if hell ghê quá
2avLY9u.gif
có chỉnh rồi, thầy Gầy @toi la gay :sosad: có xài thì xài

JavaScript:
// ==UserScript==
// @name        Handlers Helper
// @match       *://*/*
// @grant       none
// @version     1.2
// @author      -
// @description Helper for protocol_hook.lua
// ==/UserScript==


function attachDrag(elem) {

  function GM_btoaUrl(url) {
    return btoa(url).replace(/\//g, "_").replace(/\+/g, "-").replace(/\=/g, "");
  }

  function EA(attr, type) {
    console.log(attr, type)
    if (attr.startsWith('http')) {
      url = attr;
    }
    if (url == '') {
      var url = location.href;
    }
    var subs = '';
    var s = url;

    var app = 'play';
    if (type != 'vid') {
      var app = type.toLowerCase();
    }
    var bs = GM_btoaUrl(s);
    var url2 = 'mpv://' + app + '/' + bs + '/' + "?referer=" + GM_btoaUrl(location.href);
    if (subs != '') {
      url2 = url2 + '?subs=' + GM_btoaUrl(subs);
    }
    //alert(url2);
    location.href = url2;
  }

  // Define the enum-like directory
  const DirectionEnum = {
    RIGHT: 6,
    LEFT: 4,
    UP: 2,
    DOWN: 8,
    UP_LEFT: 1,
    UP_RIGHT: 3,
    DOWN_LEFT: 7,
    DOWN_RIGHT: 9
  };

  function getDirection(x, y, cx, cy) {
    /*=================
    |                 |
    | 1↖   2↑   3↗ |
    |                 |
    | 4←    5    6→ |
    |                 |
    | 7↙   8↓   9↘ |
    |                 |
    |=================*/
    let d, t;
    if ((cx - x) >= -50 && (cx - x) <= 50 && (cy - y) >= -50 && (cy - y) <= 50) {
      return 5;
    }
    // Change (4 == 4) to (8 == 4) to enable 8 directions
    if (4 == 4) { //4 directions
      if (Math.abs(cx - x) < Math.abs(cy - y)) {
        d = cy > y ? "8" : "2";
      } else {
        d = cx > x ? "6" : "4";
      }
    } else { //8 directions
      t = (cy - y) / (cx - x);
      if (-0.4142 <= t && t < 0.4142) d = cx > x ? '6' : "4";
      else if (2.4142 <= t || t < -2.4142) d = cy > y ? '8' : '2';
      else if (0.4142 <= t && t < 2.4142) d = cx > x ? '9' : '1';
      else d = cy > y ? '7' : '3';
    }
    return d;
  }
  elem.addEventListener('dragstart', function(e) {
    //console.log(e.target);
    //console.log(e.target.shadowRoot);
    /*if (e.target.nodeName != "A") {
    e.stopPropagation();
    e.stopImmediatePropagation();
    //e.preventDefault();
    }*/
    console.log('dragstart');
    var x1 = e.clientX;
    var y1 = e.clientY;
    var dragend = elem.addEventListener('dragend', function doEA(e) {
      var x2 = e.clientX;
      var y2 = e.clientY;
      var direction = getDirection(x1, y1, x2, y2);
      //if ((x2 - x1) >= -50 && (x2 - x1) <= 50 && (y2 - y1) >= -50 && (y2 - y1) <= 50) {direction = 5;console.log(5);}
      //if (e.target.nodeName == "A" && e.target.href.match(/youtube.com|youtu.be|streamable.com/)) {
      console.log('Direction: ' + direction);
      console.log(x1, y1, x2, y2, direction);

      const targetHref = e.target.href || e.target.src;

      switch (+direction) {
        case DirectionEnum.RIGHT:
          console.log('MPV: ' + targetHref);
          EA(targetHref, 'vid');
          break;
        case DirectionEnum.LEFT:
          console.log('Streamlink: ' + targetHref);
          EA(targetHref, 'stream');
          break;
        case DirectionEnum.UP:
          console.log('Open: ' + targetHref);
          window.open(targetHref, '_blank');
          break;
        case DirectionEnum.DOWN:
          console.log('YTDL: ' + targetHref);
          EA(targetHref, 'ytdl');
          break;

        case DirectionEnum.UP_LEFT:
        case DirectionEnum.UP_RIGHT:
        case DirectionEnum.DOWN_LEFT:
        case DirectionEnum.DOWN_RIGHT:
        default:
          break;
      }
      //}
      console.log(direction);
      this.removeEventListener('dragend', doEA);
    }, false);
  }, false);
}

attachDrag(document);
var attachedeles = [];
document.addEventListener('mouseover', function(e) {
  if (e.target.shadowRoot) {
    if (attachedeles.includes(e.target) == false) {
      console.log(attachedeles);
      attachedeles.push(e.target);
      attachDrag(e.target.shadowRoot);
    }
  }
});
 
Last edited:
có chỉnh rồi, thầy Gầy @toi la gay :sosad: có xài thì xài
Code đẹp đó, để mình sửa lại chút phần match -> include cho đúng chuẩn Greasemonkey tại Firemonkey nó không nhận (nếu không dùng script phức tạp quá thì Firemonkey hiệu năng vô đối) rồi bắn lên Greasyfork :D

JavaScript:
// ==UserScript==
// @name        Handlers Helper
// @include       *://*/*
// @grant       none
// @version     1.4
// @author      -
// @description Helper for protocol_hook.lua
// ==/UserScript==


function attachDrag(elem) {

  function GM_btoaUrl(url) {
    return btoa(url).replace(/\//g, "_").replace(/\+/g, "-").replace(/\=/g, "");
  }

  function EA(attr, type) {
    console.log(attr, type)
    if (attr.startsWith('http')) {
      url = attr;
    }
    if (url == '') {
      var url = location.href;
    }
    var subs = '';
    var s = url;

    var app = 'play';
    if (type != 'vid') {
      var app = type.toLowerCase();
    }
    var bs = GM_btoaUrl(s);
    var url2 = 'mpv://' + app + '/' + bs + '/' + "?referer=" + GM_btoaUrl(location.href);
    if (subs != '') {
      url2 = url2 + '?subs=' + GM_btoaUrl(subs);
    }
    //alert(url2);
    location.href = url2;
  }

  // Define the enum-like directory
  const DirectionEnum = {
    RIGHT: 6,
    LEFT: 4,
    UP: 2,
    DOWN: 8,
    UP_LEFT: 1,
    UP_RIGHT: 3,
    DOWN_LEFT: 7,
    DOWN_RIGHT: 9
  };

  function getDirection(x, y, cx, cy) {
    /*=================
    |                 |
    | 1↖   2↑   3↗ |
    |                 |
    | 4←    5    6→ |
    |                 |
    | 7↙   8↓   9↘ |
    |                 |
    |=================*/
    let d, t;
    if ((cx - x) >= -50 && (cx - x) <= 50 && (cy - y) >= -50 && (cy - y) <= 50) {
      return 5;
    }
    // Change (4 == 4) to (8 == 4) to enable 8 directions
    if (4 == 4) { //4 directions
      if (Math.abs(cx - x) < Math.abs(cy - y)) {
        d = cy > y ? "8" : "2";
      } else {
        d = cx > x ? "6" : "4";
      }
    } else { //8 directions
      t = (cy - y) / (cx - x);
      if (-0.4142 <= t && t < 0.4142) d = cx > x ? '6' : "4";
      else if (2.4142 <= t || t < -2.4142) d = cy > y ? '8' : '2';
      else if (0.4142 <= t && t < 2.4142) d = cx > x ? '9' : '1';
      else d = cy > y ? '7' : '3';
    }
    return d;
  }
  elem.addEventListener('dragstart', function(e) {
    //console.log(e.target);
    //console.log(e.target.shadowRoot);
    /*if (e.target.nodeName != "A") {
    e.stopPropagation();
    e.stopImmediatePropagation();
    //e.preventDefault();
    }*/
    console.log('dragstart');
    var x1 = e.clientX;
    var y1 = e.clientY;
    var dragend = elem.addEventListener('dragend', function doEA(e) {
      var x2 = e.clientX;
      var y2 = e.clientY;
      var direction = getDirection(x1, y1, x2, y2);
      //if ((x2 - x1) >= -50 && (x2 - x1) <= 50 && (y2 - y1) >= -50 && (y2 - y1) <= 50) {direction = 5;console.log(5);}
      //if (e.target.nodeName == "A" && e.target.href.match(/youtube.com|youtu.be|streamable.com/)) {
      console.log('Direction: ' + direction);
      console.log(x1, y1, x2, y2, direction);

      const targetHref = e.target.href || e.target.src;

      switch (+direction) {
        case DirectionEnum.RIGHT:
          console.log('MPV: ' + targetHref);
          EA(targetHref, 'vid');
          break;
        case DirectionEnum.LEFT:
          console.log('Streamlink: ' + targetHref);
          EA(targetHref, 'stream');
          break;
        case DirectionEnum.UP:
          console.log('Open: ' + targetHref);
          window.open(targetHref, '_blank');
          break;
        case DirectionEnum.DOWN:
          console.log('YTDL: ' + targetHref);
          EA(targetHref, 'ytdl');
          break;

        case DirectionEnum.UP_LEFT:
        case DirectionEnum.UP_RIGHT:
        case DirectionEnum.DOWN_LEFT:
        case DirectionEnum.DOWN_RIGHT:
        default:
          break;
      }
      //}
      console.log(direction);
      this.removeEventListener('dragend', doEA);
    }, false);
  }, false);
}

attachDrag(document);
var attachedeles = [];
document.addEventListener('mouseover', function(e) {
  if (e.target.shadowRoot) {
    if (attachedeles.includes(e.target) == false) {
      console.log(attachedeles);
      attachedeles.push(e.target);
      attachDrag(e.target.shadowRoot);
    }
  }
});
 
Back
Top