parent
8bfc42e8d8
commit
26a2398399
10 changed files with 227 additions and 264 deletions
|
@ -1,242 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2011 Center for History and New Media
|
||||
George Mason University, Fairfax, Virginia, USA
|
||||
http://zotero.org
|
||||
|
||||
This file is part of Zotero.
|
||||
|
||||
Zotero is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Zotero is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
-->
|
||||
|
||||
<bindings xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="guidancepanel">
|
||||
<resources>
|
||||
<stylesheet src="chrome://zotero/skin/bindings/guidancepanel.css"/>
|
||||
</resources>
|
||||
|
||||
<implementation>
|
||||
<property name="panel" onget="return document.getAnonymousNodes(this)[0]"/>
|
||||
|
||||
<!--
|
||||
@param {Object} [options]
|
||||
@param {String} [options.text] - Text to use in place of firstRunGuidance.<about>
|
||||
@param {DOMElement} [options.forEl] - Anchor node
|
||||
@param {Boolean} [options.force] - Show even if already shown, and don't update
|
||||
firstRunGuidanceShown.<about> pref
|
||||
-->
|
||||
<method name="show">
|
||||
<parameter name="options"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
if(!Zotero.Prefs.get("firstRunGuidance")) return;
|
||||
|
||||
options = options || {};
|
||||
let text = options.text;
|
||||
let useLastText = options.useLastText || false;
|
||||
let forEl = options.forEl || document.getElementById(this.getAttribute("for"));
|
||||
let force = options.force || false;
|
||||
|
||||
if (!forEl) return;
|
||||
// Don't show two panels at once
|
||||
if (Zotero.guidanceBeingShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
var about = this.getAttribute("about");
|
||||
var pref = false;
|
||||
if (about) {
|
||||
pref = "firstRunGuidanceShown." + about;
|
||||
let shown = false;
|
||||
try {
|
||||
shown = Zotero.Prefs.get(pref);
|
||||
} catch(e) {};
|
||||
if (shown && !force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.guidanceBeingShown = true;
|
||||
|
||||
var x = this.getAttribute("x"),
|
||||
y = this.getAttribute("y"),
|
||||
position = this.getAttribute("position");
|
||||
|
||||
if (!useLastText) {
|
||||
if (!text) {
|
||||
text = Zotero.getString("firstRunGuidance." + about);
|
||||
}
|
||||
text = text.split("\n");
|
||||
var descriptionNode = this.id('panel-description');
|
||||
|
||||
while (descriptionNode.hasChildNodes()) {
|
||||
descriptionNode.removeChild(descriptionNode.firstChild);
|
||||
}
|
||||
|
||||
while(text.length) {
|
||||
var textLine = text.shift();
|
||||
descriptionNode.appendChild(document.createTextNode(textLine));
|
||||
if(text.length) descriptionNode.appendChild(document.createElementNS(
|
||||
"http://www.w3.org/1999/xhtml", "br"));
|
||||
}
|
||||
}
|
||||
|
||||
this.setAttribute(
|
||||
"onpopuphidden",
|
||||
"this.hidden = true; "
|
||||
+ "Zotero.guidanceBeingShown = false; "
|
||||
+ (this.getAttribute("onpopuphidden") || "")
|
||||
);
|
||||
|
||||
this._initNavButton('back', options.back);
|
||||
this._initNavButton('forward', options.forward);
|
||||
|
||||
var self = this;
|
||||
var f = function() {
|
||||
if (self.hasAttribute("foregroundonly") && Services.ww.activeWindow != window) return;
|
||||
|
||||
// Hide panel if content page changes
|
||||
if (self.getAttribute('hideonpagechange') == "true") {
|
||||
let popupShownListener = function () {
|
||||
self.removeEventListener("popupshown", popupShownListener);
|
||||
|
||||
let appcontent = document.getElementById('appcontent');
|
||||
let pageHideListener = function (event) {
|
||||
var doc = event.originalTarget;
|
||||
if(!(doc instanceof HTMLDocument)) return;
|
||||
|
||||
var rootDoc = doc.defaultView.top.document;
|
||||
// Don't hide when frames and special URLs are unloaded
|
||||
if (rootDoc != doc || !rootDoc.location.href.startsWith('http')) {
|
||||
return;
|
||||
}
|
||||
appcontent.removeEventListener("pagehide", pageHideListener);
|
||||
self.hide();
|
||||
};
|
||||
appcontent.addEventListener("pagehide", pageHideListener);
|
||||
};
|
||||
self.addEventListener("popupshown", popupShownListener);
|
||||
}
|
||||
|
||||
self.hidden = false;
|
||||
self.panel.openPopup(forEl, position ? position : "after_start",
|
||||
x ? parseInt(x, 10) : 0, y ? parseInt(y, 10) : 0, false, false, null);
|
||||
if (pref) {
|
||||
Zotero.Prefs.set(pref, true);
|
||||
}
|
||||
};
|
||||
|
||||
if(this.hasAttribute("delay") && !force) {
|
||||
window.setTimeout(f, this.getAttribute("delay"));
|
||||
} else {
|
||||
f();
|
||||
}
|
||||
|
||||
if (this.getAttribute("noautohide") == 'true'
|
||||
&& !this.hasAttribute('forward')) {
|
||||
let listener = function () {
|
||||
this.panel.removeEventListener("click", listener);
|
||||
this.panel.hidePopup();
|
||||
}.bind(this);
|
||||
this.panel.addEventListener("click", listener);
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="hide">
|
||||
<body>
|
||||
<![CDATA[
|
||||
document.getAnonymousNodes(this)[0].hidePopup();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_initNavButton">
|
||||
<parameter name="dir"/>
|
||||
<parameter name="nextID"/>
|
||||
<body><![CDATA[
|
||||
if (!nextID) {
|
||||
nextID = this.getAttribute(dir);
|
||||
}
|
||||
if (!nextID) {
|
||||
return;
|
||||
}
|
||||
var nextElem = document.getElementById(nextID);
|
||||
button = this.id(dir + '-button');
|
||||
button.hidden = false;
|
||||
var target;
|
||||
// If there's a forward action and no back action, the whole panel triggers
|
||||
// the forward in noautohide mode
|
||||
if (dir == 'forward' && !this.hasAttribute('back')
|
||||
&& this.getAttribute('noautohide') == 'true') {
|
||||
target = this.panel;
|
||||
}
|
||||
else {
|
||||
target = button;
|
||||
}
|
||||
var listener = function (event) {
|
||||
target.removeEventListener("click", listener);
|
||||
this.hide();
|
||||
var data = {
|
||||
force: true
|
||||
};
|
||||
// Point the next panel back to this one
|
||||
data[dir == 'back' ? 'forward' : 'back'] = this.getAttribute('id');
|
||||
// When going backwards, don't regenerate text
|
||||
if (dir == 'back') {
|
||||
data.useLastText = true;
|
||||
}
|
||||
nextElem.show(data);
|
||||
event.stopPropagation();
|
||||
}.bind(this);
|
||||
target.addEventListener("click", listener);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="id">
|
||||
<parameter name="id"/>
|
||||
<body><![CDATA[
|
||||
return document.getAnonymousNodes(this)[0].getElementsByAttribute('anonid', id)[0];
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<content>
|
||||
<xul:panel type="arrow" align="top" xbl:inherits="noautohide">
|
||||
<xul:stack>
|
||||
<xul:hbox align="center">
|
||||
<xul:image src="chrome://zotero/skin/zotero-new-z-48px.png" style="margin-right: 10px; width: 48px; height: 48px;"/>
|
||||
<xul:description anonid="panel-description" flex="1"></xul:description>
|
||||
</xul:hbox>
|
||||
<xul:hbox anonid="close-button-box">
|
||||
<xul:toolbarbutton anonid="close-button" class="close-icon" hidden="true"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox anonid="nav-buttons">
|
||||
<xul:toolbarbutton anonid="back-button" oncommand="hide()" hidden="true"/>
|
||||
<xul:toolbarbutton anonid="forward-button" oncommand="hide()" hidden="true"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</xul:panel>
|
||||
</content>
|
||||
</binding>
|
||||
</bindings>
|
202
chrome/content/zotero/elements/guidancePanel.js
Normal file
202
chrome/content/zotero/elements/guidancePanel.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2022 Corporation for Digital Scholarship
|
||||
Vienna, Virginia, USA
|
||||
https://www.zotero.org
|
||||
|
||||
This file is part of Zotero.
|
||||
|
||||
Zotero is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Zotero is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
{
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/base.js", this);
|
||||
|
||||
class GuidancePanel extends XULElementBase {
|
||||
content = MozXULElement.parseXULToFragment(`
|
||||
<panel type="arrow" align="top">
|
||||
<stack>
|
||||
<hbox align="center">
|
||||
<image src="chrome://zotero/skin/zotero-new-z-48px.png" style="margin-right: 10px; width: 48px; height: 48px;"></image>
|
||||
<label id="panel-description" flex="1"></label>
|
||||
</hbox>
|
||||
<hbox id="close-button-box">
|
||||
<toolbarbutton id="close-button" class="close-icon" hidden="true"></toolbarbutton>
|
||||
</hbox>
|
||||
<hbox id="nav-buttons">
|
||||
<toolbarbutton id="back-button" hidden="true"></toolbarbutton>
|
||||
<toolbarbutton id="forward-button" hidden="true"></toolbarbutton>
|
||||
</hbox>
|
||||
</stack>
|
||||
</panel>
|
||||
`);
|
||||
|
||||
stylesheets = ['chrome://global/skin/', 'chrome://zotero-platform/content/guidancePanel.css'];
|
||||
|
||||
get panel() {
|
||||
return this.shadowRoot.querySelector('panel');
|
||||
}
|
||||
|
||||
init() {
|
||||
this.panel.addEventListener('popupshown', () => {
|
||||
Zotero.guidanceBeingShown = true;
|
||||
});
|
||||
|
||||
this.panel.addEventListener('popuphidden', () => {
|
||||
Zotero.guidanceBeingShown = false;
|
||||
});
|
||||
|
||||
if (this.getAttribute("noautohide") == 'true'
|
||||
&& !this.hasAttribute('forward')) {
|
||||
let listener = () => {
|
||||
this.panel.removeEventListener("click", listener);
|
||||
this.panel.hidePopup();
|
||||
};
|
||||
this.panel.addEventListener("click", listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.text] Text to use in place of firstRunGuidance.<about>
|
||||
* @param {DOMElement} [options.forEl] Anchor node
|
||||
* @param {Boolean} [options.force] Show even if already shown
|
||||
*/
|
||||
show(options) {
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
if (!Zotero.Prefs.get("firstRunGuidance")) return;
|
||||
|
||||
options = options || {};
|
||||
let text = options.text;
|
||||
let useLastText = options.useLastText || false;
|
||||
let forEl = options.forEl || document.getElementById(this.getAttribute("for"));
|
||||
let force = options.force || false;
|
||||
|
||||
if (!forEl) return;
|
||||
// Don't show two panels at once
|
||||
if (Zotero.guidanceBeingShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
var about = this.getAttribute("about");
|
||||
var pref = false;
|
||||
if (about) {
|
||||
pref = "firstRunGuidanceShown." + about;
|
||||
let shown = false;
|
||||
try {
|
||||
shown = Zotero.Prefs.get(pref);
|
||||
}
|
||||
catch (e) {}
|
||||
if (shown && !force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var x = this.getAttribute("x"),
|
||||
y = this.getAttribute("y"),
|
||||
position = this.getAttribute("position");
|
||||
|
||||
if (!useLastText) {
|
||||
if (!text) {
|
||||
text = Zotero.getString("firstRunGuidance." + about);
|
||||
}
|
||||
text = text.split("\n");
|
||||
var descriptionNode = this.id('panel-description');
|
||||
|
||||
while (descriptionNode.hasChildNodes()) {
|
||||
descriptionNode.removeChild(descriptionNode.firstChild);
|
||||
}
|
||||
|
||||
while (text.length) {
|
||||
var textLine = text.shift();
|
||||
descriptionNode.appendChild(document.createTextNode(textLine));
|
||||
if (text.length) descriptionNode.appendChild(document.createElement("br"));
|
||||
}
|
||||
}
|
||||
|
||||
this._initNavButton('back', options.back);
|
||||
this._initNavButton('forward', options.forward);
|
||||
|
||||
var f = () => {
|
||||
if (this.hasAttribute("foregroundonly") && Services.ww.activeWindow != window) return;
|
||||
|
||||
this.panel.openPopup(forEl, position || "after_start",
|
||||
x ? parseInt(x, 10) : 0, y ? parseInt(y, 10) : 0);
|
||||
if (pref) {
|
||||
Zotero.Prefs.set(pref, true);
|
||||
}
|
||||
};
|
||||
|
||||
if (this.hasAttribute("delay") && !force) {
|
||||
window.setTimeout(f, this.getAttribute("delay"));
|
||||
}
|
||||
else {
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.panel.hidePopup();
|
||||
}
|
||||
|
||||
_initNavButton(dir, nextID) {
|
||||
if (!nextID) {
|
||||
nextID = this.getAttribute(dir);
|
||||
}
|
||||
if (!nextID) {
|
||||
return;
|
||||
}
|
||||
var nextElem = document.getElementById(nextID);
|
||||
var button = this.id(dir + '-button');
|
||||
button.hidden = false;
|
||||
var target;
|
||||
// If there's a forward action and no back action, the whole panel triggers
|
||||
// the forward in noautohide mode
|
||||
if (dir == 'forward' && !this.hasAttribute('back')
|
||||
&& this.getAttribute('noautohide') == 'true') {
|
||||
target = this.panel;
|
||||
}
|
||||
else {
|
||||
target = button;
|
||||
}
|
||||
var listener = (event) => {
|
||||
target.removeEventListener("click", listener);
|
||||
this.hide();
|
||||
var data = {
|
||||
force: true
|
||||
};
|
||||
// Point the next panel back to this one
|
||||
data[dir == 'back' ? 'forward' : 'back'] = this.getAttribute('id');
|
||||
// When going backwards, don't regenerate text
|
||||
if (dir == 'back') {
|
||||
data.useLastText = true;
|
||||
}
|
||||
nextElem.show(data);
|
||||
event.stopPropagation();
|
||||
};
|
||||
target.addEventListener("click", listener);
|
||||
}
|
||||
|
||||
id(id) {
|
||||
return this.shadowRoot.getElementById(id);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("guidance-panel", GuidancePanel);
|
||||
}
|
|
@ -29,6 +29,7 @@
|
|||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/shadowAutocompleteInput.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/guidancePanel.js", this);
|
||||
|
||||
class ItemBox extends XULElement {
|
||||
constructor() {
|
||||
|
@ -76,7 +77,7 @@
|
|||
<menuitem id="zotero-doi-menu-view-online" label="&zotero.item.viewOnline;"/>
|
||||
<menuitem id="zotero-doi-menu-copy" label="&zotero.item.copyAsURL;"/>
|
||||
</menupopup>
|
||||
<zoteroguidancepanel id="zotero-author-guidance" about="authorMenu" position="after_end" x="-25"/>
|
||||
<guidance-panel id="zotero-author-guidance" about="authorMenu" position="after_end" x="-25"/>
|
||||
</popupset>
|
||||
<div id="retraction-box" hidden="hidden">
|
||||
<div id="retraction-header">
|
||||
|
@ -1916,12 +1917,11 @@
|
|||
// Reset creator mode settings here so that flex attribute gets reset
|
||||
this.switchCreatorMode(row, (otherFields.fieldMode ? 1 : 0), true);
|
||||
if (Zotero.ItemTypes.getName(this.item.itemTypeID) === "bookSection") {
|
||||
var creatorTypeLabels = this.getElementsByClassName("creator-type-label");
|
||||
var creatorTypeLabels = this.shadowRoot.querySelectorAll(".creator-type-label");
|
||||
Zotero.debug(creatorTypeLabels[creatorTypeLabels.length-1] + "");
|
||||
// fx-compat TODO: Re-enable this
|
||||
// document.getElementById("zotero-author-guidance").show({
|
||||
// forEl: creatorTypeLabels[creatorTypeLabels.length-1]
|
||||
// });
|
||||
this._id("zotero-author-guidance").show({
|
||||
forEl: creatorTypeLabels[creatorTypeLabels.length - 1]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,6 @@
|
|||
<button id="citation-properties-library-link" onclick="Zotero_QuickFormat.showInLibrary()"/>
|
||||
</vbox>
|
||||
</panel>
|
||||
<zoteroguidancepanel class="citation-dialog guidance" about="quickFormat"
|
||||
for="zotero-icon" x="26"/>
|
||||
<guidance-panel class="citation-dialog guidance" about="quickFormat"
|
||||
for="zotero-icon" x="26"/> <!-- fx-compat TODO: pull in chrome://zotero/content/elements/guidancePanel.js for this -->
|
||||
</window>
|
||||
|
|
|
@ -42,11 +42,6 @@ dialog[resizable="true"]
|
|||
-moz-binding: url('chrome://zotero/content/bindings/resizabledialog.xml#resizabledialog');
|
||||
}
|
||||
|
||||
zoteroguidancepanel
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/guidancepanel.xml#guidancepanel');
|
||||
}
|
||||
|
||||
richlistitem {
|
||||
padding: 0.2em 0.4em;
|
||||
}
|
||||
|
|
1
scss/_guidancePanel.scss
Normal file
1
scss/_guidancePanel.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "components/guidancePanel";
|
|
@ -1,15 +1,19 @@
|
|||
panel {
|
||||
min-width: none;
|
||||
}
|
||||
|
||||
stack {
|
||||
max-width: 400px;
|
||||
width: 400px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
*[anonid=nav-buttons] {
|
||||
#nav-buttons {
|
||||
-moz-box-align: end;
|
||||
-moz-box-pack: end;
|
||||
}
|
||||
|
||||
*[anonid=nav-buttons] > toolbarbutton {
|
||||
#nav-buttons > toolbarbutton {
|
||||
-moz-appearance: none; /* Necessary on Linux for button to be shown */
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
|
@ -22,31 +26,31 @@ stack {
|
|||
margin-bottom: -7px;
|
||||
}
|
||||
|
||||
*[anonid=nav-buttons] > toolbarbutton:hover {
|
||||
#nav-buttons > toolbarbutton:hover {
|
||||
border-color: var(--toolbarbutton-hover-bordercolor);
|
||||
box-shadow: var(--toolbarbutton-hover-boxshadow);
|
||||
}
|
||||
|
||||
*[anonid=nav-buttons] > toolbarbutton:active:hover {
|
||||
#nav-buttons > toolbarbutton:active:hover {
|
||||
border-color: var(--toolbarbutton-active-bordercolor);
|
||||
box-shadow: var(--toolbarbutton-active-boxshadow);
|
||||
transition-duration: 10ms;
|
||||
}
|
||||
|
||||
*[anonid=back-button] {
|
||||
#back-button {
|
||||
background-image: url("chrome://zotero/skin/chevron-left_808080_32.png");
|
||||
}
|
||||
|
||||
*[anonid=forward-button] {
|
||||
#forward-button {
|
||||
margin-right: -16px;
|
||||
background-image: url("chrome://zotero/skin/chevron-right_808080_32.png");
|
||||
}
|
||||
|
||||
*[anonid=close-button-box] {
|
||||
#close-button-box {
|
||||
-moz-box-align: start;
|
||||
-moz-box-pack: end;
|
||||
}
|
||||
|
||||
*[anonid=close-button] {
|
||||
#close-button {
|
||||
margin: -16px -16px;
|
||||
}
|
1
scss/guidancePanel-mac.scss
Normal file
1
scss/guidancePanel-mac.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "guidancePanel";
|
1
scss/guidancePanel-unix.scss
Normal file
1
scss/guidancePanel-unix.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "guidancePanel";
|
1
scss/guidancePanel-win.scss
Normal file
1
scss/guidancePanel-win.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "guidancePanel";
|
Loading…
Reference in a new issue