From 07a4f2e4ea06aac054780eee9e3b7e50915841cb Mon Sep 17 00:00:00 2001 From: Jonathan Kingston Date: Fri, 13 Jan 2017 03:17:07 +0000 Subject: [PATCH] WIP for #52 --- data/chrome.css | 45 ++++++++++++++++++++ data/filters.svg | 9 ++++ data/usercontext.css | 99 ++++++++++++++++++++++++++++++++++++++++++++ index.js | 92 +++++++++++++++++++++++++++++++++------- 4 files changed, 229 insertions(+), 16 deletions(-) create mode 100644 data/filters.svg create mode 100644 data/usercontext.css diff --git a/data/chrome.css b/data/chrome.css index 9785ce9..eb9bbd0 100644 --- a/data/chrome.css +++ b/data/chrome.css @@ -114,3 +114,48 @@ background-repeat: repeat-x; } /* end containers experiment */ + +.tabs-newtab-button .toolbarbutton-icon[type="menu"] { + margin-inline-end: 0; +} + +.tabs-newtab-button .toolbarbutton-menu-dropmarker { + display: none; +} + +.new-tab-overlay { + visibility: visible; + block-size: 200px; + inline-size: auto; + display: block; + background: transparent; + position: absolute; + -moz-appearance: none; + offset-block-start: 29px; +} +.new-tab-overlay[hidden=true] { + display: none; +} + +.new-tab-overlay menuitem { + background: white; + margin-block-end: 12px; + border-radius: 20px; + -moz-appearance: none; + color: #4b4b4b; + padding: 6px; + font-size: 1.2rem; + box-shadow: 3px 7px 7px #0006; + --icon-size: 26px; + /* Limited width to 8chars roughly */ + inline-size: calc(calc(8*0.68em) + var(--icon-size) + 3px); +} + +.new-tab-overlay .menuitem-iconic[data-usercontextid] > .menu-iconic-left > .menu-iconic-icon { + block-height: var(--icon-size); + block-width: var(--icon-size); +} + +.menuitem-iconic[data-usercontextid] > .menu-iconic-left { + visibility: visible; +} diff --git a/data/filters.svg b/data/filters.svg new file mode 100644 index 0000000..1f377b9 --- /dev/null +++ b/data/filters.svg @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/data/usercontext.css b/data/usercontext.css new file mode 100644 index 0000000..09e5484 --- /dev/null +++ b/data/usercontext.css @@ -0,0 +1,99 @@ +[data-identity-color="blue"] { + --identity-tab-color: #0996f8; + --identity-icon-color: #00a7e0; +} + +[data-identity-color="turquoise"] { + --identity-tab-color: #01bdad; + --identity-icon-color: #01bdad; +} + +[data-identity-color="green"] { + --identity-tab-color: #57bd35; + --identity-icon-color: #7dc14c; +} + +[data-identity-color="yellow"] { + --identity-tab-color: #ffcb00; + --identity-icon-color: #ffcb00; +} + +[data-identity-color="orange"] { + --identity-tab-color: #ff9216; + --identity-icon-color: #ff9216; +} + +[data-identity-color="red"] { + --identity-tab-color: #d92215; + --identity-icon-color: #d92215; +} + +[data-identity-color="pink"] { + --identity-tab-color: #ea385e; + --identity-icon-color: #ee5195; +} + +[data-identity-color="purple"] { + --identity-tab-color: #7a2f7a; + --identity-icon-color: #7a2f7a; +} + +[data-identity-icon="fingerprint"] { + /*--identity-icon: url("chrome://browser/content/usercontext.svg#fingerprint"); */ + --identity-icon: url("resource://testpilot-containers/data/usercontext.svg#fingerprint"); +} + +[data-identity-icon="briefcase"] { + /* --identity-icon: url("chrome://browser/content/usercontext.svg#briefcase"); */ + --identity-icon: url("resource://testpilot-containers/data/usercontext.svg#briefcase"); +} + +[data-identity-icon="dollar"] { + /* --identity-icon: url("chrome://browser/content/usercontext.svg#dollar"); */ + --identity-icon: url("resource://testpilot-containers/data/usercontext.svg#dollar"); +} + +[data-identity-icon="cart"] { + /* --identity-icon: url("chrome://browser/content/usercontext.svg#cart"); */ + --identity-icon: url("resource://testpilot-containers/data/usercontext.svg#cart"); +} + +[data-identity-icon="circle"] { + /* --identity-icon: url("chrome://browser/content/usercontext.svg#circle"); */ + --identity-icon: url("resource://testpilot-containers/data/usercontext.svg#circle"); +} + +#userContext-indicator { + height: 16px; + width: 16px; +} + +#userContext-label { + margin-inline-end: 3px; + color: var(--identity-tab-color); +} + +#userContext-icons { + -moz-box-align: center; +} + +.tabbrowser-tab[usercontextid] { + background-image: linear-gradient(to right, transparent 20%, var(--identity-tab-color) 30%, var(--identity-tab-color) 70%, transparent 80%); + background-size: auto 2px; + background-repeat: no-repeat; +} + +.userContext-icon, +.menuitem-iconic[data-usercontextid] > .menu-iconic-left > .menu-iconic-icon, +.subviewbutton[usercontextid] > .toolbarbutton-icon, +#userContext-indicator { + background-image: var(--identity-icon); + /*filter: url(chrome://global/skin/filters.svg#fill);*/ + filter: url(/img/filters.svg#fill); + filter: url(resource://testpilot-containers/data/filters.svg#fill); + fill: var(--identity-icon-color); + background-size: contain; + background-repeat: no-repeat; + background-position: center center; +} + diff --git a/index.js b/index.js index a751559..8cb67fd 100644 --- a/index.js +++ b/index.js @@ -436,37 +436,97 @@ let ContainerService = { var tabsElement = window.document.getElementById("tabbrowser-tabs"); var button = window.document.getAnonymousElementByAttribute(tabsElement, "anonid", "tabs-newtab-button"); - while (button.firstChild) { - button.removeChild(button.firstChild); + function getTabOverlay() { + button.parentElement.querySelector('new-tab-overlay'); + } + while (getTabOverlay()) { + button.parentElement.removeChild(getTabOverlay()); } - button.setAttribute("type", "menu"); - let popup = window.document.createElementNS(XUL_NS, "menupopup"); + let panelElement = window.document.createElementNS(XUL_NS, "panel"); + panelElement.className = "new-tab-overlay"; + //panelElement.setAttribute("side", "top"); + button.after(panelElement); + panelElement.hidden = true; - popup.setAttribute("anonid", "newtab-popup"); - popup.className = "new-tab-popup"; - popup.setAttribute("position", "after_end"); + function repositionPopup() { + //let panelElementSize = panelElement.getBoxQuads()[0]; + let size = button.getBoxQuads()[0]; + let innerWindow = tabsElement.getBoxQuads()[0] + let panelElementWidth = 200;//panelElementSize.p2.x - panelElementSize.p1.x; + // 1/4th of the way past the left hand side of the new tab button + // This seems to line up nicely with the left of the + + let offset = ((size.p3.x - size.p4.x) / 4); + let left = size.p4.x + offset; + if (left + panelElementWidth > innerWindow.p2.x) { + left -= panelElementWidth - offset; + } + panelElement.style.left = left + 'px'; + panelElement.style.top = size.p4.y + 'px'; + } + repositionPopup(); ContextualIdentityService.getIdentities().forEach(identity => { identity = this._convert(identity); - var menuItem = window.document.createElementNS(XUL_NS, "menuitem"); - menuItem.setAttribute("class", "menuitem-iconic"); - menuItem.setAttribute("label", identity.name); - menuItem.setAttribute("image", self.data.url("usercontext.svg") + "#" + identity.image); - - menuItem.addEventListener("command", (event) => { + let menuItemElement = window.document.createElementNS(XUL_NS, "menuitem"); + panelElement.appendChild(menuItemElement); + menuItemElement.className = "menuitem-iconic"; + menuItemElement.setAttribute("label", identity.name); + menuItemElement.setAttribute("data-usercontextid", identity.userContextId); + menuItemElement.setAttribute("data-identity-icon", identity.image); + menuItemElement.setAttribute("data-identity-color", identity.color); + menuItemElement.addEventListener("command", (event) => { + this.openTab({userContextId: identity.userContextId}); + event.stopPropagation(); + }); + //Command isn't working probably because I'm in a panel + menuItemElement.addEventListener("click", (event) => { + panelElement.hidden = true; this.openTab({userContextId: identity.userContextId}); event.stopPropagation(); }); - popup.appendChild(menuItem); + panelElement.appendChild(menuItemElement); }); - button.appendChild(popup); - let style = Style({ uri: self.data.url("chrome.css") }); + button.addEventListener('click', (e) => { + panelElement.hidden = false; + }); + button.addEventListener('mouseover', (e) => { +console.log('got mouseover', e); + repositionPopup(); + panelElement.hidden = false; + }); +/* + button.addEventListener('mouseout', (e) => { + let currentTarget = e.relatedTarget; + //el.closest(panelElement) doesn't seem to work on xul els + while (currentTarget) { + if (currentTarget == panelElement) { + return; + } + currentTarget = currentTarget.parentElement; + } + panelElement.hidden = true; + //if (e.relatedTarget !== panelElement) { + // panelElement.hidden = true; + //} + }); +*/ + panelElement.addEventListener('mouseout', (e) => { +console.log('got mouseout', e); + if (e.target !== panelElement) { + panelElement.hidden = true; + return; + } + repositionPopup(); + }); + let style = Style({ uri: self.data.url("chrome.css") }); attachTo(style, viewFor(window)); + let style2 = Style({ uri: self.data.url("usercontext.css") }); + attachTo(style2, viewFor(window)); } };