>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Сustom Buttons http://forum.mozilla-russia.org/viewforum.php?id=34 >[CB]Сортировка закладок по типу, названию и домену. http://forum.mozilla-russia.org/viewtopic.php?id=55049 |
bunda1 > 23-05-2012 20:46:25 |
Сортировка закладок по типу, названию и домену( Firefox 12 + ) Использование: положите код в любую Custom Buttons кнопку, в инициализацию. Не обязательно создавать новую CB кнопку, можно использовать уже существующую. Выделить код Код:// Добавить новый пункт "Сортировать по типу, названию и домену" в меню папок закладок, от 05.07.2014. ................................ (function() { var menuitem = document.createElement("menuitem"); menuitem.id = "placesContext_sortBy:locationAndName"; menuitem.setAttribute("label", "Сортировать по домену и названию"); menuitem.setAttribute("selection", "folder"); menuitem.setAttribute("closemenu", "single"); menuitem.setAttribute("oncommand", "this.run(document)"); // если клик или команда на пункте меню menuitem.run = function(doc) { // получить Id и контент папки закладок var node = PlacesUIUtils.getViewForNode( doc.popupNode ).selectedNode; var folderId = node.folderItemId ? node.folderItemId : node.itemId; var contents = PlacesUtils.getFolderContents( folderId, false, false ).root; // удалить разделители из папки закладок, создать массив с закладками и массив c подпапками закладок for ( var primaryList = [], foldersList = [], i = 0; i < contents.childCount; ++i ) { var item = contents.getChild(i); item.type == 7 ? (PlacesUtils.bookmarks.removeItem( item.itemId ), i--) // удалить разделители : (!item.type ? primaryList : foldersList).push( item ); // заполнить массивы } // создать массив с закладками у которых есть одинаковые домены и массив c обычными закладками primaryList.forEach(function(item) { var domain = item.uri.split(/\/+/g)[1]; primaryList[domain] = domain in primaryList; }); var domainList = [], placesList = []; primaryList.forEach(function(item) ( primaryList[item.uri.split(/\/+/g)[1]] ? domainList : placesList ).push(item) ); // создать функцию сортировки var sort = function(arr, prop, mod) { mod = mod || function(arg) arg; arr.sort(function(a, b) mod(a[prop]).localeCompare(mod(b[prop]), "en")); } // отсортировать все массивы по названию и массив с одинаковыми доменам по доменам sort( foldersList, "title"); sort( placesList, "title"); sort( domainList, "title"); sort( domainList, "uri", function(uri) uri.split(/\/+/g)[1] ); // соединить в нужном порядке все массивы в новом массиве var newPlacesList = foldersList.concat( placesList ).concat( domainList ); // изменить меню закладок в соответствии с новым массивом let callback = { runBatched: function() { for( let i = 0; i < newPlacesList.length; ++i ) PlacesUtils.bookmarks.setItemIndex( newPlacesList[i].itemId, i ); } } PlacesUtils.bookmarks.runInBatchMode( callback, null ); }; // добавить новый пункт во все меню папок закладок .... function handlePopup(e) { var node = e.target; if ( node.id !== 'placesContext' ) return; var sortByName = node.getElementsByAttribute("id", "placesContext_sortBy:name")[0]; setTimeout(function() { menuitem.setAttribute("disabled", sortByName.disabled ) }, 50 ); // отключать, если 'Сортировать по имени' отключено if ( node.getElementsByAttribute("id", "placesContext_sortBy:locationAndName")[0] ) return; // блокировать дублирование node.insertBefore( menuitem, sortByName ); }; addEventListener("popupshowing", handlePopup, true, window ); addDestructor(function() menuitem.parentNode && menuitem.parentNode.removeChild(menuitem) ); // Добавить новый пункт во все меню папок закладок библиотеки .... function winObs( subject ) { subject.addEventListener("load", function(e) { this.removeEventListener( e.type, arguments.callee ); if ( subject.location.href !== 'chrome://browser/content/places/places.xul' ) return; // стоп, если не библиотека // добавлять и удалять обработчик для добавления в меню папок закладок новый пункт addEventListener("popupshowing", handlePopup, true, subject ); this.addEventListener("unload", function(e) { this.removeEventListener(e.type, arguments.callee ); removeEventListener("popupshowing", handlePopup, true, subject ); }) }) }; Services.ww.registerNotification(winObs); addDestructor(function() { Services.ww.unregisterNotification(winObs) }); })(); |
hydrolizer > 23-05-2012 21:34:27 |
Странно. Почему-то у меня в кнопке popupshowing, повешенный на placesContext, отрабатывает только в случае вызова контекстного меню на папке панели закладок; в сайдбаре и в управлении закладками этот листенер просто не срабатывает. В расширении, из которого код для кнопки, листенер вешается в onLoad() главного окна, и отрабатывает в любом месте вызова. В чем разница - так и не понял. |
bunda1 > 23-05-2012 21:44:49 |
hydrolizer |
hydrolizer > 23-05-2012 22:18:11 |
bunda1 |
bunda1 > 23-05-2012 22:48:17 |
hydrolizer |
k1net1k > 24-05-2012 07:17:35 |
Что-то я не совсем понял как ей пользоваться. Можно попродробней? |
hydrolizer > 24-05-2012 10:22:15 |
k1net1k |
k1net1k > 24-05-2012 14:39:03 |
Нажал добавить кнопку -> положил верхний код в инициализацию -> нажал "Ок" ЧЯДНТ? |
voqabuhe > 24-05-2012 15:13:45 |
k1net1k пишет
Перезагружаться пробовал? |
Inko7 > 24-05-2012 15:15:35 |
k1net1k |
k1net1k > 24-05-2012 15:17:42 |
Inko7 voqabuhe |
hydrolizer > 24-05-2012 15:30:46 |
k1net1k пишет
Всё так. Просто пока кнопка не готова. overlay chrome://browser/content/places/placesOverlay.xul chrome://uithings/content/places-overlay.xul далее в chrome://uithings/content/places-overlay.xul Выделить код Код:<overlay id="places-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <script type="application/javascript" src="chrome://uithings/content/sortplaces.js"/> <menupopup id="placesContext"> <menuitem id="uithings-places-sort" label="&uithings.placessort.menuitem;" closemenu="single" selection="folder" insertafter="placesContext_sortBy:name" oncommand="uithings.placessort.sort()"/> </menupopup> </overlay> Тут нюанс в том, что chrome://browser/content/places/placesOverlay.xul, как и chrome://uithings/content/places-overlay.xul (это оверлей моего расширения) - не DOM-документы, это именно оверлеи. Из этих оверлеев конструируются документы при запуске браузера и загрузке расширений - происходит слияние оверлеев (подробнее прочитать можно, например, здесь). Поскольку у меня пункт меню уже жестко вписан в оверлей, то он в нем и находится, и при слиянии оверлеев копируется во все документы, структура которых сливается с оверлеем places. Поэтому пункт из моего расширения есть везде, где используется placesContext. В случае кнопки мы ищем placesContext по document.getElementById; т.к. документ у нас - главное окно, то и находим то, что в нем есть - placesContext панели закладок (и меню закладок). Управление закладками и сайдбар - это совсем другие документы, поэтому в их placesContext наш пункт меню просто не попадает. Нужно думать, как внедриться в них - на момент старта браузера мы в общем случае к ним не сможем получить доступа, т.к. сайдбар будет закрыт, как и управление закладками. |
bunda1 > 24-05-2012 19:10:28 |
hydrolizer Выделить код Код:window.addEventListener("dblclick", function(event){ if(event.button !== 0) return; var target = event.originalTarget; if ( target.localName == "toolbarbutton" && !!target._placesNode && !PlacesUtils.nodeIsURI(target._placesNode) ) { alert(?????) } },true); |
hydrolizer > 25-05-2012 03:57:38 |
bunda1 пишет
Тут нужно не название, а id этой папки. Примерно так: Выделить код Код:document.getElementById("PlacesToolbar").addEventListener("dblclick", function(event) { if(event.button !== 0) return; var target = event.originalTarget; Cu.import("resource://gre/modules/PlacesUtils.jsm"); if (!(target.localName == "toolbarbutton" && !!target._placesNode && PlacesUtils.nodeIsFolder(target._placesNode) && !PlacesUtils.nodeIsReadOnly(target._placesNode))) return; var folderId=PlacesUtils.getConcreteItemId(target._placesNode); var currentDocURI = Services.io.newURI(gBrowser.contentDocument.location.href,null,null); let callback = { runBatched: function() { PlacesUtils.bookmarks.insertBookmark(folderId, currentDocURI, Ci.nsINavBookmarksService.DEFAULT_INDEX, null); } } PlacesUtils.bookmarks.runInBatchMode(callback, null); Services.console.logStringMessage("bookmark created"); }, false); |
bunda1 > 25-05-2012 18:46:38 |
hydrolizer |
hydrolizer > 26-05-2012 19:32:03 |
bunda1 пишет
В PlacesUtils.bookmarks.insertBookmark последним параметром передавайте не null, а gBrowser.contentTitle. |
bunda1 > 26-05-2012 21:42:13 |
hydrolizer |
k1net1k > 30-05-2012 09:19:11 |
Эм теперь то можно сортировать по домену или нет? |
bunda1 > 30-05-2012 09:23:51 |
k1net1k пишет
Можно, но нужный пункт меню есть только в папках закладок на панели закладок . |
hydrolizer > 30-05-2012 10:33:53 |
bunda1 пишет
Должен быть еще в меню закладок (т.е. контекстное меню пунктов меню закладок). |
bunda1 > 30-05-2012 20:31:46 |
hydrolizer пишет
Нету, и мне кажется не должно быть, потому что в контекстном меню пунктов меню закладок нету пункта Сортировать по имени: |
hydrolizer > 31-05-2012 03:39:33 |
bunda1 скрытый текст Да, кстати: чтобы при вызове операции таким вот образом - из контекстного меню на пункте другого меню - не схлопывалось основное меню, а только контекстное, для menuitem нужен еще один атрибут: closemenu="single". |
bunda1 > 31-05-2012 20:33:19 |
hydrolizer
Ok. |
LongLogin > 02-06-2012 13:18:43 |
Очень хорошая кнопка, я правда и не думал все закладки сваливать в одну папку, но всё же скрытый текст |
bunda1 > 02-06-2012 13:41:29 |
LongLogin пишет
|
k1net1k > 09-06-2012 08:38:13 |
Сколько не пытаюсь создать эту кнопку все равно нечего невыходит - даже на новом профиле. |
hydrolizer > 09-06-2012 09:16:31 |
k1net1k |
bunda1 > 20-06-2012 22:31:55 |
hydrolizer Выделить код Код:window.addEventListener("mouseup", function(event) { var target = event.originalTarget; if ( event.button == 2 && target.localName == "menuitem" && target._placesNode && PlacesUtils.nodeIsURI(target._placesNode) ){ var itemId = ????? PlacesUtils.bookmarks.removeItem(itemId); } }, false); Двойной правый клик потом приделаю с таймером а то "dblclick" не работает на закладках. |
hydrolizer > 21-06-2012 07:00:46 |
bunda1 |
LBra > 21-06-2012 17:21:01 |
bunda1 пишет
Не совсем понятно кого спрашивать? Автор: hydrolizer, а публикует bunda1 ? Но есть вопросы. 2. Существующая стандартная сортировка по имени меня вполне устраивает и польза от нее очевидна - удаление дубликатов. 3. Что я бы хотел иметь и использовать? |
LongLogin > 21-06-2012 17:28:58 |
LBra пишет
|
LBra > 21-06-2012 17:39:43 |
LongLogin |
Infocatcher > 21-06-2012 18:14:58 |
Эээ... а почему бы не открыть управление закладками? Там же и поиск есть, и сортировка. Можно вбить в поиск «:» и отсортировать результаты. |
LBra > 21-06-2012 18:42:58 |
Infocatcher пишет
Да, действительно. Спасибо Infocatcher. 21-06-2012 18:45:25 bunda1 пишет
Да нет, это не так. Так будет только в том случае если ты не упорядочивал записи после добавления, накидал их в кучу и так оставил... а если нет - то нужно выбирать "Не сортировать"... я не проверял, правда... и скорее всего эта опция касается только менеджера, но не всех других случаев. |
LBra > 21-06-2012 18:57:09 |
LBra пишет
Проверил. Так и есть, если ты уже нарушил сортировку, то ее с помощью Менеджера закладок не вернешь. Точнее - не вернешь вообще. 21-06-2012 19:02:24 |
LongLogin > 21-06-2012 19:05:30 |
LBra пишет
да, но каким образом они там смогут образоваться если человек не страдает альц-геймером или рассеянным склерозом |
hydrolizer > 21-06-2012 19:06:02 |
LBra пишет
Если что: менеджер сортирует только по имени, кнопка - сначала по домену, потом по имени. |
LBra > 21-06-2012 19:42:39 |
hydrolizer Но за эту тему спасибо, заставила задуматься... убрал сейчас у себя и ту стандартную сортировку из контекстного меню (пункт меню и сепаратор) чтобы не сбивала с толку. Выделить код Код:document.getElementById("placesContext_sortBy:name").collapsed = true; document.getElementById("placesContext_sortSeparator").collapsed = true; |
bunda1 > 23-06-2012 08:20:22 |
hydrolizer пишет
Извини, я имел ввиду удаление одной закладки(не папки) на которой будет происходить двойной клик, чтобы не открывать контекстное меню закладки и не нажимать "Удалить" |
hydrolizer > 19-09-2012 07:08:29 |
bunda1 Выделить код Код:var match = view.selectedNode.uri.match(/^place\:folder=(\w+)/); var bs=Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService); if (match) switch(match[1]) { case "BOOKMARKS_MENU": folderId=bs.bookmarksMenuFolder; break; case "TOOLBAR": folderId=bs.toolbarFolder; break; case "UNFILED_BOOKMARKS": folderId=bs.unfiledBookmarksFolder; break; } |
bunda1 > 19-09-2012 18:14:38 |
Я исправил: 23-05-2012 19:46:25 |
difabor > 21-04-2014 01:20:54 |
Infocatcher пишет
А можно как-то добавить поиск по полю Description? |