Полезная информация

В мире Mozilla происходит много интересных событий. Но вам не нужно постоянно посещать новостные сайты, чтобы быть в курсе всех изменений. Зайдите на ленту новостей Mozilla Россия.

№1632605-03-2022 13:54:25

ALEX_45_ORP
Участник
 
Группа: Members
Зарегистрирован: 18-01-2018
Сообщений: 162
UA: Firefox 93.0

Re: Custom Buttons

ВВП, друже почему не отвечаешь в личку, может не видишь?


Win 10х64

Отсутствует

 

№1632705-03-2022 22:36:17

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2148
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

папки на панели тоже надо предупреждать. Из-за них и геммор этот замутил.

Весьма неожиданный поворот, чего сразу не сказал.
Хорошо, изменил код, чтобы подпадали папки и квери (также, только прямые потомки).

скрытый текст

Выделить код

Код:

(async repl => {
	var obj = `{\n  ${
		(await (await fetch("chrome://browser/content/places/controller.js")).text())
			.match(/async _removeRange\(.+?\n\ +}(?=,\n)/s)[0]
			.replace("// This is a common bookmark item.", repl)
	}\n}`
	var ps = await ChromeUtils.compileScript("data:,(" + encodeURIComponent(`${obj => {
		var patch = async ctor => {
			var proto = ctor.prototype, meth = proto?._removeRange;
			meth && Object.assign(proto, obj);
		}
		var key = "PlacesController";
		var desc = Object.getOwnPropertyDescriptor(window, key);
		if (!desc) return;

		var {get} = desc;
		if (get)
			desc.get = () => {
				var val = get();
				patch(val);
				return val;
			},
			Object.defineProperty(window, key, desc);
		else
			patch(desc.value);
	}})(${obj});`));

	var obs = doc => "PlacesController" in doc.ownerGlobal && ps.executeInGlobal(doc);
	var topic = "chrome-document-loaded";
	Services.obs.addObserver(obs, topic);
	Services.obs.addObserver(function quit(s, t) {
		Services.obs.removeObserver(quit, t);
		Services.obs.removeObserver(obs, topic);
	}, "quit-application-granted");
})(
		`$&
        if (!removedFolders.ignore) {
          let info = await PlacesUtils.bookmarks.fetch(node.bookmarkGuid);
          if (
            info?.parentGuid == "${PlacesUtils.bookmarks.toolbarGuid}" &&
            !(removedFolders.ignore ??= Services.prompt.confirm(
              null, null, "Удалять с панели закладок?"
            ))
          ) {
            totalItems--;
            continue;
          }
        }`
);

Отсутствует

 

№1632805-03-2022 23:22:06

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 93.0

Re: Custom Buttons

Dumby
Класс ! А то пришлось controler рихтовать. Теперь кашерно.

Отсутствует

 

№1632906-03-2022 01:30:50

Dobrov
Участник
 
Группа: Members
Зарегистрирован: 04-10-2011
Сообщений: 411
UA: Firefox 97.0

Re: Custom Buttons

Dumby пишет

Удалять с панели закладок?

А как вернуть ошибочно удалённую одну закладку или папку - есть для этого какой-либо скрипт, user-script или расширение ?


Подтверждение на удаление - это конечно полезная вешь, но не у всех этот код будет установлен…

Отсутствует

 

№1633006-03-2022 03:52:44

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 97.0

Re: Custom Buttons

Dobrov
№9

Отсутствует

 

№1633106-03-2022 14:38:03

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 97.0

Re: Custom Buttons

Dumby

voqabuhe пишет

№9

Как бы в этот скрипт closemenu="single" вставить? Ну, чтобы popup закладок не исчезал при возврате ?
Извиняюсь closemenu: "single", и все дела. Да, иконку не могу вставить "восстановить"

скрытый текст

Выделить код

Код:

// ==/UserScript==
if (typeof window.undobookmarksmenu == "undefined") {
  window.undobookmarksmenu = {
    popup: null,

    handleEvent: function(event) {
      switch (event.type) {
        case 'unload':
          this.uninit();
          break;
        case 'popupshown':
          this.popupshown(event);
          break;
      }
    },

    init: function() {
      window.addEventListener('unload', this, false);
      this.popup = document.getElementById("placesContext");
      if (!this.popup)
        return;
      this.popup.addEventListener('popupshown', this, false);
      let template = (location.href == "chrome://browser/content/browser.xul")  ?
                [
                  
                  
                ] : [
                  ["menuitem", {id: "undobookmarksmenuUndo",
                                disabled: "true",
                                label: "Восстановить удаленное",
                                key: "key_undo",
                                oncommand: "PlacesTransactions.undo().catch(Cu.reportError);",
                                closemenu: "single",
                                selection: "any"
              
                  
                  }]
                ];

      let ref = document.getElementById("placesContext_deleteSeparator");
      ref.parentNode.insertBefore(this.jsonToDOM(template, document, {}), ref);
    },

    uninit: function() {
      window.removeEventListener('unload', this, false);
      if (!this.popup)
        return;
      this.popup.removeEventListener('popupshown', this, false);
    },

    popupshown: function(event){
      var menuitem = document.getElementById("undobookmarksmenuUndo");
      if (menuitem)
        menuitem.setAttribute('disabled', PlacesTransactions.topUndoEntry == null);
      menuitem = document.getElementById("undobookmarksmenuRedo");
      if (menuitem)
        menuitem.setAttribute('disabled', PlacesTransactions.topRedoEntry == null);
    },

    jsonToDOM: function(jsonTemplate, doc, nodes) {
      jsonToDOM.namespaces = {
      html: "http://www.w3.org/1999/xhtml",
      xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
      };
      jsonToDOM.defaultNamespace = jsonToDOM.namespaces.xul;
      function jsonToDOM(jsonTemplate, doc, nodes) {
        function namespace(name) {
            var reElemNameParts = /^(?:(.*):)?(.*)$/.exec(name);
            return { namespace: jsonToDOM.namespaces[reElemNameParts[1]], shortName: reElemNameParts[2] };
        }

        // Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation
        function tag(elemNameOrArray, elemAttr) {
          // Array of elements?  Parse each one...
          if (Array.isArray(elemNameOrArray)) {
            var frag = doc.createDocumentFragment();
            Array.prototype.forEach.call(arguments, function(thisElem) {
              frag.appendChild(tag.apply(null, thisElem));
            });
            return frag;
          }

          // Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element
          var elemNs = namespace(elemNameOrArray);
          var elem = doc.createElementNS(elemNs.namespace || jsonToDOM.defaultNamespace, elemNs.shortName);

          // Set element's attributes and/or callback functions (eg. onclick)
          for (var key in elemAttr) {
            var val = elemAttr[key];
            if (nodes && key == "key") {
                nodes[val] = elem;
                continue;
            }

            var attrNs = namespace(key);
            if (typeof val == "function") {
              // Special case for function attributes; don't just add them as 'on...' attributes, but as events, using addEventListener
              elem.addEventListener(key.replace(/^on/, ""), val, false);
            } else {
              // Note that the default namespace for XML attributes is, and should be, blank (ie. they're not in any namespace)
              elem.setAttributeNS(attrNs.namespace || "", attrNs.shortName, val);
            }
          }

          // Create and append this element's children
          var childElems = Array.prototype.slice.call(arguments, 2);
          childElems.forEach(function(childElem) {
            if (childElem != null) {
              elem.appendChild(
                  childElem instanceof doc.defaultView.Node ? childElem :
                      Array.isArray(childElem) ? tag.apply(null, childElem) :
                          doc.createTextNode(childElem));
            }
          });
          return elem;
        }
        return tag.apply(null, jsonTemplate);
      }

      return jsonToDOM(jsonTemplate, doc, nodes);
    }
  }

  window.undobookmarksmenu.init();
}

Отредактировано ВВП (06-03-2022 20:26:33)

Отсутствует

 

№1633207-03-2022 01:02:55

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2148
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

closemenu: "single", и все дела. Да, иконку не могу вставить "восстановить"

Да так же, как closemenu: "single", только два:
class: "menuitem-iconic",
image: "chrome://browser/content/robot.ico"


И чего там за browser.xul недоудалён, тогда уж сразу
let template = ["menuitem", {…}];


Ну и label лучше просто "Отменить".
Транзакции в topUndoEntry не обязательно на удаление,
может быть добавление, редактирование, сортировка, перемещение.
То есть, добавил закладку, и пункт станет взведён отменить это добавление,
но название в меню всё равно будет торчать "Восстановить удаленное".

Отсутствует

 

№1633307-03-2022 01:37:41

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 98.0

Re: Custom Buttons

Dumby
Что let template = ["menuitem", {…}];  Или от xul избавиться ?

Отсутствует

 

№1633407-03-2022 08:35:40

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2148
UA: Firefox 78.0

Re: Custom Buttons

ВВП
Да необязательно, можно и оставить.

скрытый текст

Выделить код

Код:

data:image/png;base64,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

Отсутствует

 

№1633507-03-2022 10:16:05

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 98.0

Re: Custom Buttons

Хочу чтобы пункт "восстановить" не появлялся раньше времени... Только после удаления.

скрытый текст

Выделить код

Код:

// ==/UserScript==
if (typeof window.undobookmarksmenu == "undefined") {
  window.undobookmarksmenu = {
    popup: null,

    handleEvent: function(event) {
      switch (event.type) {
        case 'unload':
          this.uninit();
          break;
        case 'popupshown':
          this.popupshown(event);
          break;
      }
    },

    init: function() {
      window.addEventListener('unload', this, false);
      this.popup = document.getElementById("placesContext");
      if (!this.popup)
        return;
      this.popup.addEventListener('popupshown', this, false);
      let template = 
                  ["menuitem", {id: "undobookmarksmenuUndo",
                                disabled: "false",
                                label: "Восстановить удаленное",
                                class: "menuitem-iconic",
                                image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAsROwGLETskSxE7O4sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs7ixE7JEsROwGLETskCxE7P8sROz/LETs/yxE7P8sROz/LETs/0tg7/9bbvD/LETs/xaZ9v8A7f//AO3//wDt//8Wmfb/LETsiSxE7O0sROz/LETs/yxE7P8sROz/bHzy/9/i/P///////////yxE7P8A7f//LETs/wDt//8A7f//AO3//yxE7O0sROz/LETs/yxE7P8sROz/eIfz//7+//////////////////8sROz/AO3//yxE7P8sROz/LETs/wDt//8sROz/LETs/yxE7P8sROz/PVPt//P1/v//////////////////////LETs/wDt//8sROz/AO3//yxE7P8A7f//LETs/yxE7P8sROz/LETs/4CO9P///////////////////////////yxE7P8A7f//LETs/yxE7P8sROz/AO3//yxE7P8sROz/LETs/yxE7P+hq/f///////P1/v+osvf/zNL6//////9BVu7/Fpn2/wDt//8A7f//AO3//xaZ9v8sROz/LETs/yxE7P8sROz/kp71//////9jdfH/LETs/y1F7P/K0Pr/w8n6/0FW7v8sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs/1Vp8P//////PVPt/yxE7P8sROz/o673/////////////////+/x/v8wSOz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/uMD5/6mz9/81TO3/VWjw/+7w/v////////////////+CkPT/LETs/yxE7P8sROz/LETs/yxE7P+lr/f/9/j+/5+q9v++xfn///////////////////////z8//+hq/f/vsX5/0FW7v8sROz/LETs/yxE7P8wSOz//v7////////29/7/OE/t/4qX9P+dqPb/rLb4/5Gd9f+Zpfb/m6b2/6y2+P89U+7/LETs/yxE7P8sROz/LETs/6y2+P/8/P//nqn2/9ba+///////hZP0/93h/P/Dyvr/yM/6/+Xo/f8sROz/LETs/yxE7P8sROz/LETs7SxE7P8sROz/LkXs/yxE7P/T2Pv//////4aU9P/w8v7/3OD8/zRL7f85UO3/LETs/yxE7P8sROz/LETs7SxE7JAsROz/LETs/yxE7P8sROz/N07t/1Bk7/8sROz/OE7t/zNK7f8sROz/LETs/yxE7P8sROz/LETs/yxE7IgsROwGLETskSxE7O0sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs7ixE7JEsROwGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
                                oncommand: "PlacesTransactions.undo().catch(Cu.reportError);",
                                closemenu: "single"
                               
              
                  
                  }]
                ;

      let ref = document.getElementById("placesContext_deleteSeparator");
      ref.parentNode.insertBefore(this.jsonToDOM(template, document, {}), ref);
    },

    uninit: function() {
      window.removeEventListener('unload', this, false);
      if (!this.popup)
        return;
      this.popup.removeEventListener('popupshown', this, false);
    },

    popupshown: function(event){
      var menuitem = document.getElementById("undobookmarksmenuUndo");
      if (menuitem)
        menuitem.setAttribute('disabled', PlacesTransactions.topUndoEntry == null);
      menuitem = document.getElementById("undobookmarksmenuRedo");
      if (menuitem)
        menuitem.setAttribute('disabled', PlacesTransactions.topRedoEntry == null);
    },

    jsonToDOM: function(jsonTemplate, doc, nodes) {
      jsonToDOM.namespaces = {
      html: "http://www.w3.org/1999/xhtml",
      xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
      };
      jsonToDOM.defaultNamespace = jsonToDOM.namespaces.xul;
      function jsonToDOM(jsonTemplate, doc, nodes) {
        function namespace(name) {
            var reElemNameParts = /^(?:(.*):)?(.*)$/.exec(name);
            return { namespace: jsonToDOM.namespaces[reElemNameParts[1]], shortName: reElemNameParts[2] };
        }

        // Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation
        function tag(elemNameOrArray, elemAttr) {
          // Array of elements?  Parse each one...
          if (Array.isArray(elemNameOrArray)) {
            var frag = doc.createDocumentFragment();
            Array.prototype.forEach.call(arguments, function(thisElem) {
              frag.appendChild(tag.apply(null, thisElem));
            });
            return frag;
          }

          // Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element
          var elemNs = namespace(elemNameOrArray);
          var elem = doc.createElementNS(elemNs.namespace || jsonToDOM.defaultNamespace, elemNs.shortName);

          // Set element's attributes and/or callback functions (eg. onclick)
          for (var key in elemAttr) {
            var val = elemAttr[key];
            if (nodes && key == "key") {
                nodes[val] = elem;
                continue;
            }

            var attrNs = namespace(key);
            if (typeof val == "function") {
              // Special case for function attributes; don't just add them as 'on...' attributes, but as events, using addEventListener
              elem.addEventListener(key.replace(/^on/, ""), val, false);
            } else {
              // Note that the default namespace for XML attributes is, and should be, blank (ie. they're not in any namespace)
              elem.setAttributeNS(attrNs.namespace || "", attrNs.shortName, val);
            }
          }

          // Create and append this element's children
          var childElems = Array.prototype.slice.call(arguments, 2);
          childElems.forEach(function(childElem) {
            if (childElem != null) {
              elem.appendChild(
                  childElem instanceof doc.defaultView.Node ? childElem :
                      Array.isArray(childElem) ? tag.apply(null, childElem) :
                          doc.createTextNode(childElem));
            }
          });
          return elem;
        }
        return tag.apply(null, jsonTemplate);
      }

      return jsonToDOM(jsonTemplate, doc, nodes);
    }
  }

  window.undobookmarksmenu.init();
}

Отредактировано ВВП (07-03-2022 10:52:53)

Отсутствует

 

№1633607-03-2022 13:06:49

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 1164
UA: Firefox 97.0

Re: Custom Buttons

У меня во всех версиях скрипта _zt, ВВП и исходного с сайта alice0775 при наведении на пункт меню он становится "невидимым". Это у меня только так?

Отсутствует

 

№1633707-03-2022 19:24:11

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 98.0

Re: Custom Buttons

Dumby

Приморила псевдосессия. На пустую вкладку , как newtab прет сессия. Старый код не того. Или в модулях копать ?
Нашел код,снят вопрос. Хотя, хотелось бы рихтануть в модулях SessionFile.jsm и SessionStore.jsm... Или этого мало ?

Отредактировано ВВП (07-03-2022 22:30:28)

Отсутствует

 

№1633807-03-2022 19:39:56

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 97.0

Re: Custom Buttons

xrun1 пишет

при наведении на пункт меню он становится "невидимым". Это у меня только так?

У меня ничего не исчезает.

Отсутствует

 

№1633907-03-2022 20:11:31

Азат55555
Участник
 
Группа: Members
Зарегистрирован: 01-11-2018
Сообщений: 28
UA: Yandex 22

Re: Custom Buttons

Добрый вечер. Помогите отправить запрос в нужную мне песочницу. У меня открыто 3 вкладки (песочницы), нужно отправить запрос во 2-ю вкладку (песочницу).

Отсутствует

 

№1634008-03-2022 09:23:21

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2148
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

Хочу чтобы пункт "восстановить" не появлялся раньше времени... Только после удаления.

Вот, появление только при наличии в topUndoEntry транзакции удаления.

скрытый текст

Выделить код

Код:

(async sep => {
	if (!sep) return;

	var key = "hasRemoveTransaction";
	var g = Cu.import("resource://gre/modules/PlacesTransactions.jsm", {});
	if (!g[key]) {
		Services.scriptloader.loadSubScript(
			`data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g
		);
		var raws = g[key];
		g[key] = entry => {
			for(var tr of entry)
				if (raws.get(tr) instanceof PlacesTransactions.Remove)
					return true;
		}
	}
	var menuitem = document.createXULElement("menuitem");
	for(var args of Object.entries({
		closemenu: "single",
		class: "menuitem-iconic",
		id: "placesCmd_undoRemove",
		label: "Восстановить удалённое",
		oncommand: "PlacesTransactions.undo().catch(Cu.reportError);",
		image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAsROwGLETskSxE7O4sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs7ixE7JEsROwGLETskCxE7P8sROz/LETs/yxE7P8sROz/LETs/0tg7/9bbvD/LETs/xaZ9v8A7f//AO3//wDt//8Wmfb/LETsiSxE7O0sROz/LETs/yxE7P8sROz/bHzy/9/i/P///////////yxE7P8A7f//LETs/wDt//8A7f//AO3//yxE7O0sROz/LETs/yxE7P8sROz/eIfz//7+//////////////////8sROz/AO3//yxE7P8sROz/LETs/wDt//8sROz/LETs/yxE7P8sROz/PVPt//P1/v//////////////////////LETs/wDt//8sROz/AO3//yxE7P8A7f//LETs/yxE7P8sROz/LETs/4CO9P///////////////////////////yxE7P8A7f//LETs/yxE7P8sROz/AO3//yxE7P8sROz/LETs/yxE7P+hq/f///////P1/v+osvf/zNL6//////9BVu7/Fpn2/wDt//8A7f//AO3//xaZ9v8sROz/LETs/yxE7P8sROz/kp71//////9jdfH/LETs/y1F7P/K0Pr/w8n6/0FW7v8sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs/1Vp8P//////PVPt/yxE7P8sROz/o673/////////////////+/x/v8wSOz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/uMD5/6mz9/81TO3/VWjw/+7w/v////////////////+CkPT/LETs/yxE7P8sROz/LETs/yxE7P+lr/f/9/j+/5+q9v++xfn///////////////////////z8//+hq/f/vsX5/0FW7v8sROz/LETs/yxE7P8wSOz//v7////////29/7/OE/t/4qX9P+dqPb/rLb4/5Gd9f+Zpfb/m6b2/6y2+P89U+7/LETs/yxE7P8sROz/LETs/6y2+P/8/P//nqn2/9ba+///////hZP0/93h/P/Dyvr/yM/6/+Xo/f8sROz/LETs/yxE7P8sROz/LETs7SxE7P8sROz/LkXs/yxE7P/T2Pv//////4aU9P/w8v7/3OD8/zRL7f85UO3/LETs/yxE7P8sROz/LETs7SxE7JAsROz/LETs/yxE7P8sROz/N07t/1Bk7/8sROz/OE7t/zNK7f8sROz/LETs/yxE7P8sROz/LETs/yxE7IgsROwGLETskSxE7O0sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs/yxE7P8sROz/LETs7ixE7JEsROwGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
	}))
		menuitem.setAttribute(...args);

	var desc = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden");
	var {set} = desc;
	desc.set = () => {
		var entry = PlacesTransactions.topUndoEntry;
		var vis = entry && g[key](entry);
		vis && menuitem.removeAttribute("disabled");
		set.call(menuitem, !vis);
	}
	Object.defineProperty(menuitem, "hidden", desc);
	sep.before(menuitem);
})(document.getElementById("placesContext_deleteSeparator"));

Отредактировано Dumby (08-03-2022 22:24:01)

Отсутствует

 

№1634108-03-2022 10:01:10

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 93.0

Re: Custom Buttons

Dumby

Dumby пишет

Вот, появление только при наличии в topUndoEntry транзакции удаления.

Высший класс ! Нужная фича, однозначно. А, как бы дорихтовать фишку ? Удалил и не хочу восстанавливать, а пункт "восстановить" висит дальше. Сброс бы сделать ?

Отредактировано ВВП (08-03-2022 11:43:05)

Отсутствует

 

№1634208-03-2022 17:31:41

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1433
UA: Firefox 91.0

Re: Custom Buttons

Dumby
В корне панели закладок пункт неактивный.
Еще скрипт создает в конт.меню панели закладок лишний разделитель, в нижней части меню, хотя сам пункт появляется в секции "изменить/удалить".

Отсутствует

 

№1634308-03-2022 22:22:24

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2148
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

Удалил и не хочу восстанавливать, а пункт "восстановить" висит дальше. Сброс бы сделать ?

В смысле удалить topUndoEntry?
Если да, то по какому действию?
Иными словами, что укажет на произволение «не хочу восстанавливать»,
чтобы сделать сброс.


И, чисто теоретически,
если topUndoEntry займёт предыдущая операция (if any),
и если она тоже содержит транзакцию удаления,
то «пункт "восстановить"» продолжит висеть. Это окей?


_zt пишет

В корне панели закладок пункт неактивный.

Да, вижу. И на шевроне тоже.
Добавил принудительное удаление атрибута "disabled".

скрипт создает в конт.меню панели закладок лишний разделитель, в нижней части меню

Нет, этого не вижу. Ну, не «создает» — это стопроцентно.
Может как-то приводит к его появлению (что интересно).
Есть чистый профиль с UCF, чтобы проверить?

Отредактировано Dumby (08-03-2022 22:22:45)

Отсутствует

 

№1634408-03-2022 22:40:06

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 98.0

Re: Custom Buttons

Dumby
Нет. Просто код (вставлю в другую кнопку) , который сбросит пункт "восстановить" . А то он висит до перезапуска. Если это возможно .

Отсутствует

 

№1634509-03-2022 01:31:25

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1433
UA: Firefox 91.0

Re: Custom Buttons

Dumby
Да, не создает. Похоже что возвращает безID-ишный разделитель отделяющий пункты расширений от основного меню.
..
Меню переупорядочено и сепаратор был скрыт как #placesContext > menuseparator:nth-child(x2) (с этим скриптом - который создает два пункта), а тут теперь #placesContext > menuseparator:nth-child(x1) нужен, так как пункт всего один. (похоже что так)

Отредактировано _zt (09-03-2022 01:47:32)

Отсутствует

 

№1634609-03-2022 23:39:35

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2148
UA: Firefox 78.0

Re: Custom Buttons

ВВП пишет

Нет.

Нет так нет. PlacesTransactions.clearTransactionsHistory();
сбросит вообще всё, в том числе и пункт.

Отсутствует

 

№1634710-03-2022 00:25:38

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 332
UA: Firefox 98.0

Re: Custom Buttons

Dumby
Годится. Класс !

Отсутствует

 

№1634810-03-2022 09:04:00

vv07
Участник
 
Группа: Members
Зарегистрирован: 07-11-2007
Сообщений: 672
UA: Firefox 54.0

Re: Custom Buttons

Здравствуйте! для старых FF, была отличная кнопка для переключения Proxy
С таким

Выделить код

Код:

// Proxy, от 25.02.2016.


// Настройка функций кликов мыши для кнопки ...................
this.onmousedown =e=> {
   
   this.onmouseup =e=>{                  // левый клик
        if ( e.button ) return;
        clearTimeout(self.timer);           

        switch( cbu.getPrefs("network.proxy.type") ) {
           case 0:  var data = 1; break;            
           case 1:  var data = 2; break; 
           case 2:  var data = 0; break;
           default: var data = 0; 
        }
        cbu.setPrefs("network.proxy.type", data);  
   }

   if ( e.button == 0 )                  // длинный левый клик
        self.timer = setTimeout(()=>{     
           self.onmouseup = '';
           cbu.getPrefs("CB.Proxy.connectionsInTab") ? openConnectionsInTab() : openConnections();
        }, 500);
   
   if ( e.button == 2 )                  // правый клик
        menuPopup.showPopup(self, -1, -1, "popup", "bottomleft", "topleft");
};
self.onclick =e=> e.preventDefault();



// Подсказка для кнопки ...................
this.onmouseover =()=> {
   this.tooltipText = "Proxy \nЛ: Переключить прокси \nДЛ: Открыть настройки прокси"
                    + "\nП: Mеню кнопки \n\nТекущие настройки прокси: " 
                    + "\nIP: " + Services.prefs.getComplexValue("network.proxy.http", Ci.nsISupportsString).data
                    + "\nПорт: "+ cbu.getPrefs("network.proxy.http_port");                                                    
};



// Создать меню для кнопки ...................
var array = [
   { label: "Добавление прокси в контекстом меню", value: 'CB.Proxy.inContextMenu' },
   { label: "Открывать настройки прокси как вкладку", value: 'CB.Proxy.connectionsInTab' },
   { label: "Переключать на режим 'Без прокси' при закрытии браузера ", value: 'CB.Proxy.reset' }    
];

var menuPopup = document.getElementById('mainPopupSet').appendChild(document.createElement("menupopup"));
array.forEach((m)=> {
   var mItem = document.createElement("menuitem");
   mItem.setAttribute("label", m.label);
   mItem.setAttribute('type', 'checkbox');
   mItem.setAttribute('checked', cbu.getPrefs(m.value) );
   mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));  
   menuPopup.appendChild(mItem);
});
addDestructor(()=> menuPopup.remove() );

// добавить стандартное контекстное меню 
menuPopup.appendChild(document.createElement("menuseparator"));
menuPopup.appendChild(document.createElement("menu")).setAttribute("label", "Меню кнопки");
var clone = menuPopup.lastChild.appendChild(document.getElementById("custombuttons-contextpopup").cloneNode(true));
clone.setAttribute("onpopupshowing", "document.popupNode = document.getElementById('" + _id + "')");



// Функция открывает настройки прокси в окне ...................
function openConnections() {
   for ( var win, nm = Services.wm.getEnumerator(null); win = nm.getNext(); ) 
         if ( win.name == 'Proxy') {
              win.focus();  
              break;
              }
   var win = openDialog("chrome://browser/content/preferences/connection.xul", "Proxy", "centerscreen");

   // добавить атрибут "prefwindow"
   win.addEventListener("load", function f(e) {
       this.removeEventListener("load", f, true); 
       e.target.documentElement.setAttribute("type", "prefwindow");
   }, true );
   
   // закрыть настройки прокси по клику на странице 
   gBrowser.addEventListener("click", function c() {
      this.removeEventListener("click", c );
      try { win.close() } catch(e) {}; 
   }, true );
};



// Функция открывает настройки прокси в вкладке ...................
function openConnectionsInTab() { 
   var connections = gBrowser.getBrowserForTab( gBrowser.selectedTab = gBrowser.addTab("chrome://browser/content/preferences/connection.xul") ); 
          
   // oбработчик ждет пока откроется прокси, удаляет себя и добавляет атрибут
   connections.addEventListener("pageshow", function c(e) {         
      this.removeEventListener(e.type, c);         
      e.originalTarget.documentElement.setAttribute("type", "prefwindow");
   })   
};



// Установливать нужную иконку кнопки при старте баузера или при изменениях в 'about:config' ...................
var s = "network.proxy.type";
function toggleImage() {
   var icon = self.ownerDocument.getAnonymousElementByAttribute(self, "class", "toolbarbutton-icon");
   switch( cbu.getPrefs(s) ) {
      case 0: icon.src = self.image; break;          
      case 1: icon.src = 'data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAQAAAAAIAA4GQAAnFmkAHQ5fAAQAKAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEBAQECAgICAgICAgICAgMBAQEAAAQBJBFQOLQ+nX38ecev/mu6of8gfFvtAyUXewAAAAsAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEBAAAAAAMLUza7PKd//3S7oP2849X9zuvh/mW4mf4XiV7/AB4QZwAAAAAAAAAAAQEBAQAAAAAZGhgTKSwnLyYqJDErKCUnID8vXgaAUP9BlnH8b7ea/ojHrv+q2sf/a7CT+zGWbf8PakXGAAIAAAEBAQMHBwcbAAAAD2BiXn76/ff/4ebg/Onm4f+DtZ7/A31L/j2Wb/+Fwaj/ls23/7rh0v9+vaT+M5du/xKGWO0DIxIdAAAAAAEBAQEAAAABBgYFEaSmorbP08z239vX/4OwnP4ail3/RJlz/5HHsP/T7+X/ms64/3K2mP40k2r/D3tM7AUiExwhIx8meXt1mXt+eKJ3eXSce353n6esouDMysf/o7eq/kOdeP92uZv/vuPT/9Hs4P/C4tT/eLWa+juWbv8bcEq7AAYBAF1gWn7//////f39/P//////////////////////////lcKx/3i9pf/K7OD/2O/l/7ndzf6Fw6n/VK+I/AsxHj8AAAAAXF5bf+Ln2P+AnU/4fZ1N+4WiV/yKp13+jKlh/5CsZf+GpFj/Zpxh/4C5nf+i0L7+k8ex/1udf+UTOCZFAAAAAAEBAQJfYF5/3uXR/16IIPxciiH/Z5Iv/26YOP9ymz3/cpw+/3OcPf9wlzb/YI80/1mKNPu707X/YmZjiAAAAAAEBAQGAAAAAF9gXoDg5tT/cJU6/HGaPf9/pE3/hqtX/4uvXf+NsF7/iKxZ/4KoU/9+o0r/cpY6+9zjyf9ubm2JAAAAAAMEAwQAAAAAX2BegODm1P94nEX8e6JJ/4quXP+Vt2n/nb1z/6LBef+jwXz/ob96/527d/+NrGP71+HG/2praogAAAAABAQDBAAAAABfYF2A4ObU/4WlVvyPsmP/osB7/7HMj/+81J3/wdik/8DXo/+60pz/tc6X/6G6ffvY4sf/amtqiAAAAAAEBAMEAAAAAF9gXn/e5dL/n7l7/LLMk//B16X/zuG2/9jpwv/b68b/2enE/9Pkvv/Q4bv/uMud+9jhyP9qa2mHAAAAAAQEAwQAAAAAX2Bef97k0v+gt335sceT/LrNnfzC1Kj8ydmx/MzatfzK2bP8xtav/MbVr/ywwpL41+HH/2tsaokAAAAABAQDBAAAAABZW1Z3+fz1/+Dm1Pzj6db/5u3b/+nv3v/r8eD/6vDe/+ft2//k69j/4efT/9ngzPv7//b/ZGdhfwAAAAADBAMEAAAAABcZFRpZW1Z6YGFfgWBiYIBhYmGAYmJhgGJjYoBiY2KAYmJhgGFiYYBgYWCAX2BegF1fWoAbHRkeAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; break;
      case 2: icon.src = 'data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAQAAAAAIAAcHQAAYGGkAEBBfAAEBKAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAgICAAICAgACAgMBAQEAAAEBJAA6OrQAf3/8ALCw/gCiov8AXl7tABkZewAAAAsAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEBAAAAAAMAOTm7AIOD/wCjo/0A1tb9AOHh/gCcnP4AY2P/ABISZwAAAAAAAAAAAAEBAQAAAAAAGBgTACgoLwAmJjEAJiYnADIyXgBWVv8Adnb8AJ2d/gCxsf8Aycn/AJeX+wBycv8ASkrGAAACAAABAQMABwcbAAAADwBfX34A+fn/AOHh/ADj4/8AoaH/AFJS/gB1df8Aq6v/ALm5/wDT0/8Ap6f+AHNz/wBeXu0AFRUdAAAAAAABAQEAAAABAAUFEQCjo7YAzs72ANnZ/wCfn/4AY2P/AHl5/wCzs/8A5ub/ALu7/wCcnP4AcHD/AFNT7AAVFRwAICAmAHd3mQB6eqIAdXWcAHl5nwClpeAAyMj/AK2t/gB9ff8An5//ANXV/wDh4f8A1tb/AJ6e+gB0dP8AUFC7AAEGAABcXH4A////AP39/AD///8A////AP///wD///8A////ALOz/wCnp/8A4eH/AObm/wDPz/4ArKz/AI2N/AAhIT8AAAAAAFxcfwDd3f8Aa2v4AGpq+wBycvwAeHj+AHt7/wB/f/8Ac3P/AHNz/wCiov8AwMD+ALS0/wCEhOUAKSlFAAAAAAABAQIAXl5/ANjY/wBGRvwARkb/AFJS/wBaWv8AX1//AF9f/wBfX/8AWVn/AFRU/wBRUfsAvr7/AGNjiAAAAAAABAQGAAAAAABeXoAA2tr/AFtb/ABeXv8AbGz/AHV1/wB6ev8Ae3v/AHd3/wBxcf8Aamr/AFtb+wDS0v8AbW2JAAAAAAADAwQAAAAAAF5egADa2v8AZGT8AGlp/wB5ef8AhYX/AI2N/wCTk/8AlJT/AJKS/wCPj/8AfX37AM/P/wBqaogAAAAAAAMDBAAAAAAAXl6AANra/wBycvwAf3//AJOT/wClpf8AsLD/ALa2/wC1tf8Ar6//AKqq/wCTk/sA0ND/AGpqiAAAAAAAAwMEAAAAAABeXn8A2dn/AJGR/ACnp/8At7f/AMXF/wDQ0P8A09P/ANHR/wDLy/8AyMj/AK2t+wDR0f8AaWmHAAAAAAADAwQAAAAAAF5efwDY2P8AkpL5AKWl/ACurvwAuLj8AL+//ADCwvwAwMD8AL29/AC8vPwAo6P4ANDQ/wBqaokAAAAAAAMDBAAAAAAAV1d3APf3/wDa2vwA3d3/AOHh/wDk5P8A5ub/AOTk/wDh4f8A39//ANra/wDT0/sA+fn/AGNjfwAAAAAAAwMEAAAAAAAWFhoAV1d6AF9fgQBgYIAAYWGAAGFhgABiYoAAYmKAAGFhgABhYYAAYGCAAF5egABbW4AAGhoeAAAAAAABAQEAAAAA/oOAQeEAgEH6AIBBoACAQQAAAEGAAABBAACAQQAAgEEAAQBBAAKAQQACgEEAAoBBAAKAQQACgEEAAoBBAAKAQQACgEE='; break;
      default:icon.src = self.image; 
   }
};  
toggleImage();
gPrefService.addObserver(s, toggleImage, false);
addDestructor(()=> gPrefService.removeObserver(s, toggleImage) );



// Переключать на режим 'Без прокси' при закрытии браузера если это разрешено в 'about:config' ...................
var switchOffProxy = {
    observe: function(subject, topic, data) {
       if ( data == "shutdown" && cbu.getPrefs("CB.Proxy.reset") ) cbu.setPrefs("network.proxy.type", 0);  
    }
};
Services.obs.addObserver(switchOffProxy, "quit-application", false);



// Создаем меню для добавление прокси в контекстном меню выделенного текста на странице ...................
((contextMenu)=> {

  // создать новый пункт меню
  var menuitem = contextMenu.appendChild( document.createElement("menuitem") );      
  menuitem.setAttribute("label", "Добавить прокси"); 
  menuitem.setAttribute("class", "menuitem-iconic");
  menuitem.setAttribute("image", self.image);
  menuitem.onclick =()=> addNewProxy();
  addDestructor(()=> menuitem.remove() );
  
  // устанавливаем где показывать пункт меню 
  addEventListener("popupshowing", ()=>{
     menuitem.hidden = !cbu.getPrefs("CB.Proxy.inContextMenu") || !gContextMenu.isContentSelected; // !gContextMenu.isTextSelected;
  }, false, contextMenu);
  
  
  // добавление прокси
  function addNewProxy(sel) {  
     var selection = document.commandDispatcher.focusedWindow.getSelection().toString();
     var sel = ( sel == undefined ) ? selection : sel.toString();
     sel = sel.replace(/^\s+|\s+$/g, ""); // удалить пробелы, слева и справа от строки
     sel = sel.replace(/\s+/g,":"); // заменить пробелы внутри строки

     // если только порт ...
     if ( sel.length < 6 && isFinite(sel) ) { 
          sel = sel.replace(/:/g, "");
          var lab = 'порт';
          cbu.setPrefs("network.proxy.http_port", +sel);                    
          }
     
     // если только адрес ...
     if ( sel.length > 5 && !/:/.test(sel) && sel.split(".").length == 4 ) {   
          var lab = 'адрес';
          cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", sel));  
          }   
     
     // если адрес и порт ...    
     if ( sel.length > 5 && /:/.test(sel) && sel.split(":").length == 2 && sel.split(".").length == 4 ) {
          var lab = 'адрес и порт';
          var array = sel.split(":");  
          array.forEach((str)=> addNewProxy(str) );          
          }     

     if ( lab == undefined ) return;

     // всплывающая подсказка рядом с выделенным текстом ...     
     function showTooltip() {
        var tooltip = gBrowser.appendChild( document.createElement("tooltip") );
        tooltip.style.cssText = "color: red !important; font-weight: bold !important; font-size: 14px !important; -moz-box-orient: horizontal; text-align: center;";
   
        var image = tooltip.appendChild( document.createElement("image") );
        image.setAttribute("src", self.image);
   
        var label = tooltip.appendChild( document.createElement("label"));
        label.setAttribute("value", "Установлен " + lab + " прокси: " + sel);
    
        var focused = document.commandDispatcher.focusedWindow;
        var selection = focused.getSelection().getRangeAt(0).getBoundingClientRect();
        var posX = focused.mozInnerScreenX + selection.left;
        var posY = focused.mozInnerScreenY + selection.bottom - 5;   

        tooltip.showPopup(gBrowser, posX, posY);
        setTimeout(()=> gBrowser.removeChild(tooltip), 3000);
     };
     showTooltip();    
  };
   
})(document.getElementById("contentAreaContextMenu"));

К сожалению на FF 84 и выше, перестала работать.
Помогите пожалуйста. Поправьте

Отсутствует

 

№1634910-03-2022 12:10:51

sonyas75
Участник
 
Группа: Members
Откуда: Ставрополь
Зарегистрирован: 22-03-2011
Сообщений: 557
UA: Firefox 91.0

Re: Custom Buttons

vv07
я что-то там менял, не помню что, то ли цвета кнопки, то ли еще что-то по-мелочи

скрытый текст

Выделить код

Код:

/*Initialization Code*/
/* https://forum.mozilla-russia.org/viewtopic.php?pid=783830#p783830 */
// Настройка функций кликов мыши для кнопки ...................
this.onmousedown = e => {

    if (e.button == 0) // длинный левый клик
        self.timer = setTimeout(() => {
            self.onmouseup = null;
            cbu.getPrefs("CB.Proxy.connectionsInTab")
                ? openConnectionsInTab() : openConnections();
        }, 500);

    this.onmouseup = e => { // левый клик
        if (e.button) return;
        clearTimeout(self.timer);

        switch(cbu.getPrefs("network.proxy.type")) {
            case 0:  var data = 1; break;
            case 1:  var data = 2; break;
            case 2:  var data = 0; break;
            default: var data = 0; 
        }
        cbu.setPrefs("network.proxy.type", data);
    }
}
// правый клик
this.oncontextmenu = e => e.detail == 2 && !menuPopup.hidePopup()
    || e.ctrlKey || !!menuPopup.openPopup(this, "after_start");


// Подсказка для кнопки ...................
this.onmouseover = () => this.tooltipText =
    "Proxy \nЛ:  Переключить прокси \nДЛ: Открыть настройки прокси" +
    "\nП:  Mеню кнопки \nДП: CB меню \n\nТекущие настройки прокси: " +
    "\nIP: " + cbu.getPrefs("network.proxy.http") + "\nПорт: " +
    cbu.getPrefs("network.proxy.http_port");


// Создать меню для кнопки ...................
var array = [
    {label: "Добавление прокси в контекстом меню", value: 'CB.Proxy.inContextMenu'},
    {label: "Открывать настройки прокси как вкладку", value: 'CB.Proxy.connectionsInTab'},
    {label: "Переключать на режим 'Без прокси' при закрытии браузера ", value: 'CB.Proxy.reset'}
];

var menuPopup = document.getElementById('mainPopupSet').appendChild(document.createElementNS(xulns, "menupopup"));
array.forEach(m => {
    var mItem = document.createElementNS(xulns, "menuitem");
    mItem.setAttribute("label", m.label);
    mItem.setAttribute("type", "checkbox");
    mItem.setAttribute("checked", cbu.getPrefs(m.value));
    mItem.onclick = () => cbu.setPrefs(m.value, !cbu.getPrefs(m.value));  
    menuPopup.appendChild(mItem);
});
addDestructor(() => menuPopup.remove());


var listenClick = win => {
    var args = ["click", win.close.bind(win), true];
    var unload = () => gBrowser.removeEventListener(...args);
    gBrowser.addEventListener(...args);
    win.addEventListener("unload", unload, {once: true});
}
var version = parseInt(Services.appinfo.platformVersion);
var url = `chrome://browser/content/preferences/${version >= 77 ? "dialogs/" : ""}connection.x${version >= 72 ? "htm" : "u"}l`;

var fox73 = version >= 73, noop = () => {};
if (fox73) var grid = win => {
    var url = "data:text/css;charset=utf-8," + encodeURIComponent(`
        #proxy-grid, #dnsOverHttps-grid {
            display: grid;
            grid-template-columns: auto 1fr;
            align-items: center;
        }
        #proxy-grid > .thin {
            grid-column-end: 3;
            height: 20px;
        }
        #dnsOverHttps-grid.custom-container-hidden #networkCustomDnsOverHttpsInput,
        #dnsOverHttps-grid.custom-container-hidden #networkCustomDnsOverHttpsInputLabelContainer {
            display: none;
        }
    `);
    (grid = win => win.windowUtils.loadSheetUsingURIString(url, win.windowUtils.AUTHOR_SHEET))(win);
}
var winOpen = win => win.addEventListener("readystatechange", winReady, {once: true, capture: true});
var winReady = e => {
    var win = e.target.ownerGlobal, cw = win.isChromeWindow;
    if (cw || (win.location == url && !win.docShell.name)) winPatch(win, cw);
}
var winPatch = (win, cw) => {
    win.opener = {gSubDialog: {_dialogs: [{
        _frame: {get contentDocument() {
            cw && listenClick(win);
            delete this.contentDocument;
            return this.contentDocument = win.document;
        }},
        resizeVertically: cw ? () => win.sizeToContent() : noop
    }]}};
    fox73 && grid(win);
}
addEventListener("MozBeforeInitialXULLayout", winReady, false, gBrowser.tabpanels || 1);

for(var {contentWindow: win} of gBrowser.browsers)
    win && win.location == url && !win.opener && winPatch(win);


// Функция открывает настройки прокси в окне ...................  
function openConnections() {
    var win = [...Services.wm.getEnumerator(null)].find(w => w.location == url);
    win ? win.focus() : winOpen(openDialog(url, "Proxy", "centerscreen"));
}

// Функция открывает настройки прокси в вкладке ...................
function openConnectionsInTab() {
    var connections = gBrowser.getBrowserForTab(
        gBrowser.selectedTab = gBrowser.addTrustedTab(url)
    );

    // oбработчик ждет пока откроется прокси, удаляет себя и добавляет атрибут
    connections.addEventListener("pageshow",
        e => e.target.documentElement.setAttribute("type", "prefwindow")
    , {once: true});
}


// Установливать нужную иконку кнопки при старте баузера или при изменениях в 'about:config' ...................
var s = "network.proxy.type";
function toggleImage() {
    var {icon} = self;
    switch( cbu.getPrefs(s) ) {
        //case 0: icon.src = self.image; break;
        case 2: icon.src = 'data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAQAAAAAIAA4GQAAnFmkAHQ5fAAQAKAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEBAQECAgICAgICAgICAgMBAQEAAAQBJBFQOLQ+nX38ecev/mu6of8gfFvtAyUXewAAAAsAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEBAAAAAAMLUza7PKd//3S7oP2849X9zuvh/mW4mf4XiV7/AB4QZwAAAAAAAAAAAQEBAQAAAAAZGhgTKSwnLyYqJDErKCUnID8vXgaAUP9BlnH8b7ea/ojHrv+q2sf/a7CT+zGWbf8PakXGAAIAAAEBAQMHBwcbAAAAD2BiXn76/ff/4ebg/Onm4f+DtZ7/A31L/j2Wb/+Fwaj/ls23/7rh0v9+vaT+M5du/xKGWO0DIxIdAAAAAAEBAQEAAAABBgYFEaSmorbP08z239vX/4OwnP4ail3/RJlz/5HHsP/T7+X/ms64/3K2mP40k2r/D3tM7AUiExwhIx8meXt1mXt+eKJ3eXSce353n6esouDMysf/o7eq/kOdeP92uZv/vuPT/9Hs4P/C4tT/eLWa+juWbv8bcEq7AAYBAF1gWn7//////f39/P//////////////////////////lcKx/3i9pf/K7OD/2O/l/7ndzf6Fw6n/VK+I/AsxHj8AAAAAXF5bf+Ln2P+AnU/4fZ1N+4WiV/yKp13+jKlh/5CsZf+GpFj/Zpxh/4C5nf+i0L7+k8ex/1udf+UTOCZFAAAAAAEBAQJfYF5/3uXR/16IIPxciiH/Z5Iv/26YOP9ymz3/cpw+/3OcPf9wlzb/YI80/1mKNPu707X/YmZjiAAAAAAEBAQGAAAAAF9gXoDg5tT/cJU6/HGaPf9/pE3/hqtX/4uvXf+NsF7/iKxZ/4KoU/9+o0r/cpY6+9zjyf9ubm2JAAAAAAMEAwQAAAAAX2BegODm1P94nEX8e6JJ/4quXP+Vt2n/nb1z/6LBef+jwXz/ob96/527d/+NrGP71+HG/2praogAAAAABAQDBAAAAABfYF2A4ObU/4WlVvyPsmP/osB7/7HMj/+81J3/wdik/8DXo/+60pz/tc6X/6G6ffvY4sf/amtqiAAAAAAEBAMEAAAAAF9gXn/e5dL/n7l7/LLMk//B16X/zuG2/9jpwv/b68b/2enE/9Pkvv/Q4bv/uMud+9jhyP9qa2mHAAAAAAQEAwQAAAAAX2Bef97k0v+gt335sceT/LrNnfzC1Kj8ydmx/MzatfzK2bP8xtav/MbVr/ywwpL41+HH/2tsaokAAAAABAQDBAAAAABZW1Z3+fz1/+Dm1Pzj6db/5u3b/+nv3v/r8eD/6vDe/+ft2//k69j/4efT/9ngzPv7//b/ZGdhfwAAAAADBAMEAAAAABcZFRpZW1Z6YGFfgWBiYIBhYmGAYmJhgGJjYoBiY2KAYmJhgGFiYYBgYWCAX2BegF1fWoAbHRkeAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; break;
        case 1: icon.src = 'data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAQAAAAAIAAcHQAAYGGkAEBBfAAEBKAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAgICAAICAgACAgMBAQEAAAEBJAA6OrQAf3/8ALCw/gCiov8AXl7tABkZewAAAAsAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEBAAAAAAMAOTm7AIOD/wCjo/0A1tb9AOHh/gCcnP4AY2P/ABISZwAAAAAAAAAAAAEBAQAAAAAAGBgTACgoLwAmJjEAJiYnADIyXgBWVv8Adnb8AJ2d/gCxsf8Aycn/AJeX+wBycv8ASkrGAAACAAABAQMABwcbAAAADwBfX34A+fn/AOHh/ADj4/8AoaH/AFJS/gB1df8Aq6v/ALm5/wDT0/8Ap6f+AHNz/wBeXu0AFRUdAAAAAAABAQEAAAABAAUFEQCjo7YAzs72ANnZ/wCfn/4AY2P/AHl5/wCzs/8A5ub/ALu7/wCcnP4AcHD/AFNT7AAVFRwAICAmAHd3mQB6eqIAdXWcAHl5nwClpeAAyMj/AK2t/gB9ff8An5//ANXV/wDh4f8A1tb/AJ6e+gB0dP8AUFC7AAEGAABcXH4A////AP39/AD///8A////AP///wD///8A////ALOz/wCnp/8A4eH/AObm/wDPz/4ArKz/AI2N/AAhIT8AAAAAAFxcfwDd3f8Aa2v4AGpq+wBycvwAeHj+AHt7/wB/f/8Ac3P/AHNz/wCiov8AwMD+ALS0/wCEhOUAKSlFAAAAAAABAQIAXl5/ANjY/wBGRvwARkb/AFJS/wBaWv8AX1//AF9f/wBfX/8AWVn/AFRU/wBRUfsAvr7/AGNjiAAAAAAABAQGAAAAAABeXoAA2tr/AFtb/ABeXv8AbGz/AHV1/wB6ev8Ae3v/AHd3/wBxcf8Aamr/AFtb+wDS0v8AbW2JAAAAAAADAwQAAAAAAF5egADa2v8AZGT8AGlp/wB5ef8AhYX/AI2N/wCTk/8AlJT/AJKS/wCPj/8AfX37AM/P/wBqaogAAAAAAAMDBAAAAAAAXl6AANra/wBycvwAf3//AJOT/wClpf8AsLD/ALa2/wC1tf8Ar6//AKqq/wCTk/sA0ND/AGpqiAAAAAAAAwMEAAAAAABeXn8A2dn/AJGR/ACnp/8At7f/AMXF/wDQ0P8A09P/ANHR/wDLy/8AyMj/AK2t+wDR0f8AaWmHAAAAAAADAwQAAAAAAF5efwDY2P8AkpL5AKWl/ACurvwAuLj8AL+//ADCwvwAwMD8AL29/AC8vPwAo6P4ANDQ/wBqaokAAAAAAAMDBAAAAAAAV1d3APf3/wDa2vwA3d3/AOHh/wDk5P8A5ub/AOTk/wDh4f8A39//ANra/wDT0/sA+fn/AGNjfwAAAAAAAwMEAAAAAAAWFhoAV1d6AF9fgQBgYIAAYWGAAGFhgABiYoAAYmKAAGFhgABhYYAAYGCAAF5egABbW4AAGhoeAAAAAAABAQEAAAAA/oOAQeEAgEH6AIBBoACAQQAAAEGAAABBAACAQQAAgEEAAQBBAAKAQQACgEEAAoBBAAKAQQACgEEAAoBBAAKAQQACgEE='; break;
        default: icon.src = self.image;
    }
}
toggleImage();
Services.prefs.addObserver(s, toggleImage, false);
addDestructor(() => Services.prefs.removeObserver(s, toggleImage));


// Переключать на режим 'Без прокси' при закрытии браузера если это разрешено в 'about:config' ...................
var toggleButton = {
    observe(s, t, data) {
        cbu.getPrefs("CB.Proxy.reset") && data == "shutdown" && cbu.setPrefs("network.proxy.type", 0);
    }
};
Services.obs.addObserver(toggleButton, "quit-application", false);


// Создаем меню для добавление прокси в контекстном меню выделенного текста на странице ...................
var contextMenu = document.getElementById("contentAreaContextMenu");
var menuitem = document.createElementNS(xulns,"menuitem");
menuitem.setAttribute("label", "Добавить прокси");
menuitem.setAttribute("class", "menuitem-iconic");
menuitem.setAttribute("image", self.image);
menuitem.onclick =()=> addNewProxy(menuitem);
contextMenu.appendChild(menuitem); // как последний пункт меню
addDestructor(() => menuitem.remove());
addEventListener("popupshowing", () => {
    menuitem.hidden = !cbu.getPrefs("CB.Proxy.inContextMenu") || !gContextMenu.isContentSelected; // !gContextMenu.isTextSelected;
}, false, contextMenu);


// добавление прокси ...................
function addNewProxy(menuitem) {
    var sel = gBrowser.contentDocument
        ? gBrowser.contentDocument.defaultView.getSelection().toString() // Pale Moon  
        : gContextMenu.selectionInfo.fullText; // Firefox

    sel = sel.replace(/^\s+|\s+$/g, ""); // удалить пробелы, слева и справа от строки
    sel = sel.replace(/\s+/g, ":");      // заменить пробелы внутри строки

    // если только порт ...
    if (sel.length < 6 && isFinite(sel)) { 
        var lab = 'порт';
        cbu.setPrefs("network.proxy.http_port", +sel);                    
    }

    // если только адрес ...
    if (sel.length > 5 && !/:/.test(sel) && sel.split(".").length == 4) {
        var lab = 'адрес';
        cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", sel));  
    }

    // если адрес и порт ...    
    if (sel.length > 5 && /:/.test(sel) && sel.split(":").length == 2 && sel.split(".").length == 4) {
        var lab = 'адрес и порт';
        var arr = sel.split(":"), IP = arr[0], port = arr[1];
        cbu.setPrefs("network.proxy.http_port", +port);
        cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", IP));
    }

    // всплывающая подсказка рядом с выделенным текстом ...
    var mainPopupSet = document.getElementById('mainPopupSet');
    var tooltip = mainPopupSet.appendChild(document.createElementNS(xulns,"tooltip"));
    tooltip.style.cssText = "color: red !important; font-weight: bold !important; font-size: 14px !important; -moz-box-orient: horizontal; text-align: center;";

    var image = tooltip.appendChild(document.createElementNS(xulns, "image"));
    image.setAttribute("src", self.image);

    var label = tooltip.appendChild(document.createElementNS(xulns, "label"));
    label.setAttribute("value", "Установлен " + lab + " прокси: " + sel);

    tooltip.openPopup(menuitem.parentNode, "before_start");
    setTimeout(() => mainPopupSet.removeChild(tooltip), 3000);
};


// Конвертировать текст в юникод .............  
function convertFromUnicode(charset, str) {
    var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    converter.charset = charset;
    str = converter.ConvertFromUnicode(str);
    return str + converter.Finish();
}

а... ну в коде есть ссылка, откуда я эту кнопку выкопал и чуть ниже скрипт, сделанный из этой кнопки

Отредактировано sonyas75 (10-03-2022 12:13:40)

Отсутствует

 

№1635010-03-2022 12:19:55

vv07
Участник
 
Группа: Members
Зарегистрирован: 07-11-2007
Сообщений: 672
UA: Firefox 54.0

Re: Custom Buttons

sonyas75
Сработало. Благодарю

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]