• Cọc VF3 thì vào đây, dùng mã LEBAOLONG thì giảm thêm mớ nữa ;)

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

@toi la gay :sosad: Mong bác Gay chỉ cách Handlers Helper mở luôn cả link mpv://play/**** cho tiện :burn_joss_stick:
Thử bản mod lại sau (chưa hề test chỉ code):

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

var collected_urls = {};
function GM_getParentByTagName(el, tagName) {
  tagName = tagName.toLowerCase();
  if (el.tagName.toLowerCase() == tagName) {
    return el;
  }
  while (el && el.parentNode) {
    el = el.parentNode;
    if (el.tagName && el.tagName.toLowerCase() == tagName) {
      return el;
    }
  }
  return "undefined";
}

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;
    } else if (attr.startsWith('mpv://')) {
        location.href = attr;
    }
    if (url == '') {
      var url = location.href;
    }
    var subs = '';
    console.log(collected_urls);
    var s = '';
    if (Object.keys(collected_urls).length > 0) {
        for (link in collected_urls) {
            console.log(link, collected_urls[link]);
            collected_urls[link].style.boxSizing = 'unset';
            collected_urls[link].style.border = 'unset';
            s += link + ' ';
        }
        s = s.trim(' ');
        console.log(s);
        //var s = collected_urls.join(" ");
    } else {
        var s = url;
    }

    collected_urls = {};

    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);
          EA(targetHref, 'list');
          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);
}

var count = 0;
var mouseIsDown = false;
var held = false;
document.addEventListener("mousedown", function (e) {
    var link = GM_getParentByTagName(e.target, 'A');
    if (link.nodeName == 'A') {

      mouseIsDown = true;
      document.addEventListener("mouseup", function mouseup(e) {
          mouseIsDown = false;
          this.removeEventListener('mouseup', mouseup);
      });
      document.addEventListener("contextmenu", function contextmenu(e) {
          if (held == true) {
              held = false;
              e.preventDefault();
          }
          held = false;
          this.removeEventListener('contextmenu', contextmenu);
      });
      if (e.button === 2) {
          setTimeout(function () {
              if (mouseIsDown) {
                      if (collected_urls[link.href] == undefined) {
                          //var ele = GM_eleTOPele(e.target);
                          //document.body.appendChild(ele);
                          //collected_urls[link.href] = ele;
                          collected_urls[link.href] = e.target;
                          e.target.style.boxSizing = 'border-box';
                          e.target.style.border = 'solid yellow 4px';
                          //popup('Added: ' + link.href, e.clientX, e.clientY)
                      } else {
                          //collected_urls[link.href].parentNode.removeChild(collected_urls[link.href]);
                          collected_urls[link.href].style.boxSizing = 'unset';
                          collected_urls[link.href].style.border = 'unset';
                          delete collected_urls[link.href];
                          //e.target.style.boxSizing = 'unset';
                          //e.target.style.border = 'unset';
                      }
                  console.log(collected_urls);
                  count = 0;
                  mouseIsDown = false;
              held = true;
              }
          }, 200);
      }
    }

});

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);
    }
  }
});
 
Fen cũng khẩm dô thế. Đã "Click on video thumbnail to play in MPV" rồi còn kéo nữa
IsF1dJF.gif
Do quen tay fen ơi. Giờ xem các clip Youtube được nhúng trong Voz cũng phải kéo để mở = MPV chứ script "Click on video thumbnail to play in MPV" đâu có hoạt động. Nên mình thấy nếu kết hợp được cả 2 sẽ cực tiện dụng
 
Thử bản mod lại sau (chưa hề test chỉ code):

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

var collected_urls = {};
function GM_getParentByTagName(el, tagName) {
  tagName = tagName.toLowerCase();
  if (el.tagName.toLowerCase() == tagName) {
    return el;
  }
  while (el && el.parentNode) {
    el = el.parentNode;
    if (el.tagName && el.tagName.toLowerCase() == tagName) {
      return el;
    }
  }
  return "undefined";
}

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;
    } else if (attr.startsWith('mpv://')) {
        location.href = attr;
    }
    if (url == '') {
      var url = location.href;
    }
    var subs = '';
    console.log(collected_urls);
    var s = '';
    if (Object.keys(collected_urls).length > 0) {
        for (link in collected_urls) {
            console.log(link, collected_urls[link]);
            collected_urls[link].style.boxSizing = 'unset';
            collected_urls[link].style.border = 'unset';
            s += link + ' ';
        }
        s = s.trim(' ');
        console.log(s);
        //var s = collected_urls.join(" ");
    } else {
        var s = url;
    }

    collected_urls = {};

    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);
          EA(targetHref, 'list');
          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);
}

var count = 0;
var mouseIsDown = false;
var held = false;
document.addEventListener("mousedown", function (e) {
    var link = GM_getParentByTagName(e.target, 'A');
    if (link.nodeName == 'A') {

      mouseIsDown = true;
      document.addEventListener("mouseup", function mouseup(e) {
          mouseIsDown = false;
          this.removeEventListener('mouseup', mouseup);
      });
      document.addEventListener("contextmenu", function contextmenu(e) {
          if (held == true) {
              held = false;
              e.preventDefault();
          }
          held = false;
          this.removeEventListener('contextmenu', contextmenu);
      });
      if (e.button === 2) {
          setTimeout(function () {
              if (mouseIsDown) {
                      if (collected_urls[link.href] == undefined) {
                          //var ele = GM_eleTOPele(e.target);
                          //document.body.appendChild(ele);
                          //collected_urls[link.href] = ele;
                          collected_urls[link.href] = e.target;
                          e.target.style.boxSizing = 'border-box';
                          e.target.style.border = 'solid yellow 4px';
                          //popup('Added: ' + link.href, e.clientX, e.clientY)
                      } else {
                          //collected_urls[link.href].parentNode.removeChild(collected_urls[link.href]);
                          collected_urls[link.href].style.boxSizing = 'unset';
                          collected_urls[link.href].style.border = 'unset';
                          delete collected_urls[link.href];
                          //e.target.style.boxSizing = 'unset';
                          //e.target.style.border = 'unset';
                      }
                  console.log(collected_urls);
                  count = 0;
                  mouseIsDown = false;
              held = true;
              }
          }, 200);
      }
    }

});

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);
    }
  }
});
Perfect. E iu bác Gay :sweet_kiss:
 
Vừa đổi font mặc định thành Noto Sans xong, trông nuột như Ngọc Tờ Rinh nhỉ :D

HUOWEFt.png

Hiện tượng răng cưa không còn nữa, tụi Google hóa ra cũng làm ra được cái font ra trò.

Cách cài đặt:

Tất cả trang web từ nay sẽ dùng Noto Sans kèm theo lợi ích liệt kê ở bài đó luôn.
 
View attachment 2099110
Có tải thêm đâu fen. Nếu chọn cái kia theo khầy thì nó sẽ sài font set trong firefox. Còn cái config của fen là chặn tải luôn font của icon
P5P1Om6.gif
đúng r fen ý mình là vẫn tải font của icon đó, mà cách chặn triệt để thì hơi bdsm :D

nên mới có 1 cách khác là
Dùng youBlock chặn remote font globally, trang nào hỏng thì lại cho phép remote font locally
sẽ flexible hơn

[edit] cách youBlock này và nếu đã có sẵn LocalCDN thì có thể yên tâm là các trang dùng font awesome hoặc material icon sẽ không bị hỏng, rất hiếm trang phải whitelist
 
Last edited:
Vừa đổi font mặc định thành Noto Sans xong, trông nuột như Ngọc Tờ Rinh nhỉ :D

HUOWEFt.png

Hiện tượng răng cưa không còn nữa, tụi Google hóa ra cũng làm ra được cái font ra trò.

Cách cài đặt:

Tất cả trang web từ nay sẽ dùng Noto Sans kèm theo lợi ích liệt kê ở bài đó luôn.
fen xài thử font Inter xem, theo cá nhân t là đẹp hơn font noto này
t0KQRtQ.png
 
đúng r fen ý mình là vẫn tải font của icon đó, mà cách chặn triệt để thì hơi bdsm :D
Chặn font hoàn toàn có thể khiến trang web load trắng xóa nghĩa là một số trang họ dùng Javascript để load font rồi mới hiển thị nội dung, nếu font bị chặn script sẽ báo đỏ chót rồi trả về trang trắng bóc hoặc trả về một phần và bỏ qua hết phần khi báo lỗi font, nên kệ nó thôi vừa tăng trải nghiệm mà quan trọng nhất là không phải render font, không phải tìm một lô font hệ thống sẽ cải thiện tốc độ render trang web.

Trước từng gặp vài trang mà quên không lưu lại, nhưng mà tỉ lệ nhỏ.
 
fen xài thử font Inter xem, theo cá nhân t là đẹp hơn font noto này
t0KQRtQ.png
Để thử xem, nhẹ và không răng cưa, thậm chí không răng cưa khi không bật ClearType nữa thì ngon :D

Lát tắt luôn ClearType trên Firefox rồi test mới ra được ngọc thô.

Code:
user_pref("gfx.text.disable-aa", true);//Completely disable font cleartype anti-alias
user_pref("gfx.font_rendering.ahem_antialias_none", true);
 
Ngoài lề, các bác cho mình hỏi có nên dùng mấy cái vd như thằng này không nhỉ :big_smile:
https://github.com/IgorMundstein/WinMemoryCleaner
tùy máy nhiều ram thì ko cần xài, window ko giải phóng ram là do có vấn đề của nó vì window theo dõi hành động của fen, thấy app đó fen bật đi bật lại nhiều lần nên nó cache vào ram không giải phóng ram. Xài app này fen phải load tới load lui nhiều lần trên ổ cứng => tốc độ chậm hơn. Có nhiều app tối ưu ram còn bẩn bựa hơn là nó đem cái cache ram quăng lên page file nhằm lòe người dùng ít tốn ram => làm hệ thống chậm sml ra, vì chạy trên page file không phải trên ram.
ps/ nhìn code app này chạy .net là thấy tốn ram rồi đó chưa nói gì đến chuyện tối ưu ram
lhCKIs0.gif
 
Last edited:
tùy máy nhiều ram thì ko cần xài, window ko giải phóng ram là do có vấn đề của nó vì window theo dõi hành động của fen, thấy app đó fen bật đi bật lại nhiều lần nên nó cache vào ram không giải phóng ram. Xài app này fen phải load tới load lui nhiều lần trên ổ cứng => tốc độ chậm hơn. Có nhiều app tối ưu ram còn bẩn bựa hơn là nó đem cái cache ram quăng lên page file nhằm lòe người dùng ít tốn ram => làm hệ thống chậm sml ra, vì chạy trên page file không phải trên ram.
giờ dùng ram 16 đã bắt đầu bị kì thị rồi, nên lên 32 cho nó dư dả
NzxNXMw.png
 
Để review luôn khi tắt Anti Alias và ClearType, cứ hiểu là chế độ mà Firefox làm mịn font mà tác vụ này thường nặng cũng như bật Smoothing Text trên Windows đó, không tự nhiên người ta cho nó vào mục Performance Settings và nói tắt đi để tăng tốc Windows, cơ mà tắt xong thì là mình ở riêng một thế giới luôn. :D

Kết quả:

1695966148135.png

1695966503277.png

1695966589605.png

Sẽ thấy có vẻ như Inter ngon hơn Noto một chút, còn SF Pro Display thì mỏng manh quá.

Nói chung tắt AA và CT đi thì mới thấy hiện thực nó phũ phàng đến nhường nào, đây là cái giá của đánh đổi lấy tốc độ. :D

Còn đây là AA+CT:

1695968138435.png

1695967970126.png

1695968251787.png

Tuy nhiên có một điều mình dám chắc là các font trên đều trên Arial một đẳng:
1695969325357.png
 
Last edited:
tùy máy nhiều ram thì ko cần xài, window ko giải phóng ram là do có vấn đề của nó vì window theo dõi hành động của fen, thấy app đó fen bật đi bật lại nhiều lần nên nó cache vào ram không giải phóng ram. Xài app này fen phải load tới load lui nhiều lần trên ổ cứng => tốc độ chậm hơn. Có nhiều app tối ưu ram còn bẩn bựa hơn là nó đem cái cache ram quăng lên page file nhằm lòe người dùng ít tốn ram => làm hệ thống chậm sml ra, vì chạy trên page file không phải trên ram.
ps/ nhìn code app này chạy .net là thấy tốn ram rồi đó chưa nói gì đến chuyện tối ưu ram
lhCKIs0.gif
thank bác khai sáng :beauty:
 
ps/ nhìn code app này chạy .net là thấy tốn ram rồi đó chưa nói gì đến chuyện tối ưu ram
lhCKIs0.gif
Cứ .NET là nó ăn kha khá RAM và việc nó chạy nền để liên tục theo dõi và dập các ứng dụng nổi loạn khác là sẽ nặng hơn một ứng dụng C/C++ nó làm điều tương tự rồi.

Hiện tại có Mem Reduct của Henry Đại Đế từng viết ra SimpleWall nổi tiếng một thời ấy ngon và nhẹ, nhưng mà không nên dùng nếu như thừa RAM: https://www.portablefreeware.com/index.php?sc=215
 
Back
Top