Add an option to create parent item from identifier (#1901)
This commit is contained in:
parent
f393a233e9
commit
86b77cc45e
16 changed files with 429 additions and 54 deletions
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright © 2020 Corporation for Digital Scholarship
|
||||||
|
Vienna, Virginia, USA
|
||||||
|
https://digitalscholar.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';
|
||||||
|
|
||||||
|
import React, { memo } from 'react';
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import cx from 'classnames';
|
||||||
|
import { IntlProvider } from "react-intl";
|
||||||
|
|
||||||
|
function CreateParent({ loading, item, toggleAccept }) {
|
||||||
|
// When the input has/does not have characters toggle the accept button on the dialog
|
||||||
|
const handleInput = (e) => {
|
||||||
|
if (e.target.value.trim() !== '') {
|
||||||
|
toggleAccept(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toggleAccept(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IntlProvider
|
||||||
|
locale={ Zotero.locale }
|
||||||
|
messages={ Zotero.Intl.strings }
|
||||||
|
>
|
||||||
|
<div className="create-parent-container">
|
||||||
|
<span className="title">
|
||||||
|
{ item.attachmentFilename }
|
||||||
|
</span>
|
||||||
|
<div className="body">
|
||||||
|
<input
|
||||||
|
id="parent-item-identifier"
|
||||||
|
placeholder={ Zotero.getString('createParent.prompt') }
|
||||||
|
size="50"
|
||||||
|
disabled={ loading }
|
||||||
|
onChange={ handleInput }
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
mode="undetermined"
|
||||||
|
className={ cx('downloadProgress', { hidden: !loading }) }
|
||||||
|
>
|
||||||
|
<div className="progress-bar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</IntlProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CreateParent.propTypes = {
|
||||||
|
loading: PropTypes.bool,
|
||||||
|
item: PropTypes.object,
|
||||||
|
toggleAccept: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
Zotero.CreateParent = memo(CreateParent);
|
||||||
|
|
||||||
|
|
||||||
|
Zotero.CreateParent.destroy = (domEl) => {
|
||||||
|
ReactDOM.unmountComponentAtNode(domEl);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Zotero.CreateParent.render = (domEl, props) => {
|
||||||
|
ReactDOM.render(<CreateParent { ...props } />, domEl);
|
||||||
|
};
|
80
chrome/content/zotero/createParentDialog.js
Normal file
80
chrome/content/zotero/createParentDialog.js
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright © 2009 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 *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var io;
|
||||||
|
let createParent;
|
||||||
|
|
||||||
|
function toggleAccept(enabled) {
|
||||||
|
document.documentElement.getButton("accept").disabled = !enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doLoad() {
|
||||||
|
// Set font size from pref
|
||||||
|
let sbc = document.getElementById('zotero-create-parent-container');
|
||||||
|
Zotero.setFontSize(sbc);
|
||||||
|
|
||||||
|
io = window.arguments[0];
|
||||||
|
|
||||||
|
createParent = document.getElementById('create-parent');
|
||||||
|
Zotero.CreateParent.render(createParent, {
|
||||||
|
loading: false,
|
||||||
|
item: io.dataIn.item,
|
||||||
|
toggleAccept
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function doUnload() {
|
||||||
|
Zotero.CreateParent.destroy(createParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doAccept() {
|
||||||
|
let textBox = document.getElementById('parent-item-identifier');
|
||||||
|
let childItem = io.dataIn.item;
|
||||||
|
let newItems = await Zotero_Lookup.addItemsFromIdentifier(
|
||||||
|
textBox,
|
||||||
|
childItem,
|
||||||
|
(on) => {
|
||||||
|
// Render react again with correct loading value
|
||||||
|
Zotero.CreateParent.render(createParent, {
|
||||||
|
loading: on,
|
||||||
|
item: childItem,
|
||||||
|
toggleAccept
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// If we successfully created a parent, return it
|
||||||
|
if (newItems) {
|
||||||
|
io.dataOut = { parent: newItems[0] };
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doManualEntry() {
|
||||||
|
io.dataOut = { parent: false };
|
||||||
|
window.close();
|
||||||
|
}
|
34
chrome/content/zotero/createParentDialog.xul
Normal file
34
chrome/content/zotero/createParentDialog.xul
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://zotero/skin/overlay.css" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://zotero-platform/content/overlay.css" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
|
||||||
|
|
||||||
|
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
|
||||||
|
|
||||||
|
<dialog
|
||||||
|
id="zotero-parent-dialog"
|
||||||
|
title="&zotero.createParent.title;"
|
||||||
|
orient="vertical"
|
||||||
|
buttons="cancel,accept,extra2"
|
||||||
|
buttondisabledaccept="true"
|
||||||
|
buttonlabelextra2="&zotero.createParent.button.manual;"
|
||||||
|
buttonlabelaccept="&zotero.createParent.title;"
|
||||||
|
ondialogaccept="doAccept();return false;"
|
||||||
|
ondialogextra2="doManualEntry();"
|
||||||
|
onload="doLoad();"
|
||||||
|
onunload="doUnload();"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
|
style="padding:20px 15px;width:400px;">
|
||||||
|
|
||||||
|
<script src="include.js"/>
|
||||||
|
<script src="lookup.js"/>
|
||||||
|
<script src="createParentDialog.js"/>
|
||||||
|
<script src="components/createParent/createParent.js"/>
|
||||||
|
|
||||||
|
<vbox id="zotero-create-parent-container" flex="1">
|
||||||
|
<html:div id="create-parent" />
|
||||||
|
</vbox>
|
||||||
|
</dialog>
|
|
@ -29,9 +29,19 @@
|
||||||
*/
|
*/
|
||||||
var Zotero_Lookup = new function () {
|
var Zotero_Lookup = new function () {
|
||||||
/**
|
/**
|
||||||
* Performs a lookup by DOI, PMID, or ISBN
|
* Performs a lookup by DOI, PMID, or ISBN on the given textBox value
|
||||||
|
* and adds any items it can.
|
||||||
|
*
|
||||||
|
* If a childItem is passed, then only one identifier is allowed, the
|
||||||
|
* child's library/collection information is used and no attachments are
|
||||||
|
* saved for the parent.
|
||||||
|
*
|
||||||
|
* @param textBox {HTMLElement} - Textbox containing identifiers
|
||||||
|
* @param childItem {Zotero.Item|false} - Child item (optional)
|
||||||
|
* @param toggleProgress {function} - Callback to toggle progress on/off
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
this.accept = Zotero.Promise.coroutine(function* (textBox) {
|
this.addItemsFromIdentifier = async function (textBox, childItem, toggleProgress) {
|
||||||
var identifiers = Zotero.Utilities.Internal.extractIdentifiers(textBox.value);
|
var identifiers = Zotero.Utilities.Internal.extractIdentifiers(textBox.value);
|
||||||
if (!identifiers.length) {
|
if (!identifiers.length) {
|
||||||
Zotero.alert(
|
Zotero.alert(
|
||||||
|
@ -41,58 +51,87 @@ var Zotero_Lookup = new function () {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (childItem && identifiers.length > 1) {
|
||||||
var libraryID = false;
|
// Only allow one identifier when creating a parent for a child
|
||||||
var collection = false;
|
Zotero.alert(
|
||||||
try {
|
window,
|
||||||
libraryID = ZoteroPane_Local.getSelectedLibraryID();
|
Zotero.getString("lookup.failure.title"),
|
||||||
collection = ZoteroPane_Local.getSelectedCollection();
|
Zotero.getString("lookup.failureTooMany.description")
|
||||||
} catch(e) {
|
);
|
||||||
/** TODO: handle this **/
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var successful = 0; //counter for successful retrievals
|
var libraryID = false;
|
||||||
|
var collections = false;
|
||||||
|
if (childItem) {
|
||||||
|
libraryID = childItem.libraryID;
|
||||||
|
collections = childItem.collections;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
libraryID = ZoteroPane.getSelectedLibraryID();
|
||||||
|
let collection = ZoteroPane.getSelectedCollection();
|
||||||
|
collections = collection ? [collection.id] : false;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
/** TODO: handle this **/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Zotero_Lookup.toggleProgress(true);
|
let newItems = false;
|
||||||
|
toggleProgress(true);
|
||||||
|
|
||||||
for (let identifier of identifiers) {
|
await Zotero.Promise.all(identifiers.map(async (identifier) => {
|
||||||
var translate = new Zotero.Translate.Search();
|
var translate = new Zotero.Translate.Search();
|
||||||
translate.setIdentifier(identifier);
|
translate.setIdentifier(identifier);
|
||||||
|
|
||||||
// be lenient about translators
|
// be lenient about translators
|
||||||
let translators = yield translate.getTranslators();
|
let translators = await translate.getTranslators();
|
||||||
translate.setTranslator(translators);
|
translate.setTranslator(translators);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let newItems = yield translate.translate({
|
newItems = await translate.translate({
|
||||||
libraryID,
|
libraryID,
|
||||||
collections: collection ? [collection.id] : false
|
collections,
|
||||||
|
saveAttachments: !childItem
|
||||||
});
|
});
|
||||||
successful++;
|
|
||||||
}
|
}
|
||||||
// Continue with other ids on failure
|
// Continue with other ids on failure
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.logError(e);
|
Zotero.logError(e);
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
|
|
||||||
Zotero_Lookup.toggleProgress(false);
|
toggleProgress(false);
|
||||||
// TODO: Give indication if some failed
|
if (!newItems) {
|
||||||
if (successful) {
|
|
||||||
document.getElementById("zotero-lookup-panel").hidePopup();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Zotero.alert(
|
Zotero.alert(
|
||||||
window,
|
window,
|
||||||
Zotero.getString("lookup.failure.title"),
|
Zotero.getString("lookup.failure.title"),
|
||||||
Zotero.getString("lookup.failure.description")
|
Zotero.getString("lookup.failure.description")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// TODO: Give indication if some, but not all failed
|
||||||
|
|
||||||
|
return newItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try a lookup and hide popup if successful
|
||||||
|
*/
|
||||||
|
this.accept = async function (textBox) {
|
||||||
|
let newItems = await Zotero_Lookup.addItemsFromIdentifier(
|
||||||
|
textBox,
|
||||||
|
false,
|
||||||
|
on => Zotero_Lookup.toggleProgress(on)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newItems) {
|
||||||
|
document.getElementById("zotero-lookup-panel").hidePopup();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
};
|
||||||
|
|
||||||
|
|
||||||
this.showPanel = function (button) {
|
this.showPanel = function (button) {
|
||||||
var panel = document.getElementById('zotero-lookup-panel');
|
var panel = document.getElementById('zotero-lookup-panel');
|
||||||
panel.openPopup(button, "after_start", 16, -2, false, false);
|
panel.openPopup(button, "after_start", 16, -2, false, false);
|
||||||
|
|
|
@ -2821,24 +2821,12 @@ var ZoteroPane = new function()
|
||||||
show.push(m.findPDF, m.sep3);
|
show.push(m.findPDF, m.sep3);
|
||||||
}
|
}
|
||||||
|
|
||||||
var canCreateParent = true;
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
|
||||||
let item = items[i];
|
|
||||||
if (!item.isTopLevelItem() || !item.isAttachment() || item.isFeedItem) {
|
|
||||||
canCreateParent = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (canCreateParent) {
|
|
||||||
show.push(m.createParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canRename) {
|
if (canRename) {
|
||||||
show.push(m.renameAttachments);
|
show.push(m.renameAttachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add in attachment separator
|
// Add in attachment separator
|
||||||
if (canCreateParent || canRecognize || canUnrecognize || canRename || canIndex) {
|
if (canRecognize || canUnrecognize || canRename || canIndex) {
|
||||||
show.push(m.sep5);
|
show.push(m.sep5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2849,7 +2837,6 @@ var ZoteroPane = new function()
|
||||||
if (item.isFileAttachment()) {
|
if (item.isFileAttachment()) {
|
||||||
disable.push(
|
disable.push(
|
||||||
m.moveToTrash,
|
m.moveToTrash,
|
||||||
m.createParent,
|
|
||||||
m.renameAttachments
|
m.renameAttachments
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -4517,20 +4504,33 @@ var ZoteroPane = new function()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.createParentItemsFromSelected = Zotero.Promise.coroutine(function* () {
|
this.createParentItemsFromSelected = async function () {
|
||||||
if (!this.canEdit()) {
|
if (!this.canEdit()) {
|
||||||
this.displayCannotEditLibraryMessage();
|
this.displayCannotEditLibraryMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var items = this.getSelectedItems();
|
let item = this.getSelectedItems()[0];
|
||||||
for (var i=0; i<items.length; i++) {
|
if (!item.isAttachment() || !item.isTopLevelItem()) {
|
||||||
var item = items[i];
|
throw new Error('Item ' + itemID + ' is not a top-level attachment');
|
||||||
if (!item.isTopLevelItem() || item.isRegularItem()) {
|
}
|
||||||
throw('Item ' + itemID + ' is not a top-level attachment or note in ZoteroPane_Local.createParentItemsFromSelected()');
|
|
||||||
}
|
let io = { dataIn: { item }, dataOut: null };
|
||||||
|
window.openDialog('chrome://zotero/content/createParentDialog.xul', '', 'chrome,modal,centerscreen', io);
|
||||||
yield Zotero.DB.executeTransaction(function* () {
|
if (!io.dataOut) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we made a parent, attach the child
|
||||||
|
if (io.dataOut.parent) {
|
||||||
|
await Zotero.DB.executeTransaction(function* () {
|
||||||
|
item.parentID = io.dataOut.parent.id;
|
||||||
|
yield item.save();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// If they clicked manual entry then make a dummy parent
|
||||||
|
else {
|
||||||
|
await Zotero.DB.executeTransaction(function* () {
|
||||||
// TODO: remove once there are no top-level web attachments
|
// TODO: remove once there are no top-level web attachments
|
||||||
if (item.isWebAttachment()) {
|
if (item.isWebAttachment()) {
|
||||||
var parent = new Zotero.Item('webpage');
|
var parent = new Zotero.Item('webpage');
|
||||||
|
@ -4549,8 +4549,8 @@ var ZoteroPane = new function()
|
||||||
yield item.save();
|
yield item.save();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
|
||||||
this.renameSelectedAttachmentsFromParents = Zotero.Promise.coroutine(function* () {
|
this.renameSelectedAttachmentsFromParents = Zotero.Promise.coroutine(function* () {
|
||||||
// TEMP: fix
|
// TEMP: fix
|
||||||
|
|
|
@ -175,6 +175,9 @@
|
||||||
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, or arXiv IDs to add to your library:">
|
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, or arXiv IDs to add to your library:">
|
||||||
<!ENTITY zotero.lookup.button.search "Search">
|
<!ENTITY zotero.lookup.button.search "Search">
|
||||||
|
|
||||||
|
<!ENTITY zotero.createParent.title "Create Parent Item">
|
||||||
|
<!ENTITY zotero.createParent.button.manual "Manual Entry">
|
||||||
|
|
||||||
<!ENTITY zotero.selectitems.title "Select Items">
|
<!ENTITY zotero.selectitems.title "Select Items">
|
||||||
<!ENTITY zotero.selectitems.intro.label "Select which items you'd like to add to your library">
|
<!ENTITY zotero.selectitems.intro.label "Select which items you'd like to add to your library">
|
||||||
<!ENTITY zotero.selectitems.cancel.label "Cancel">
|
<!ENTITY zotero.selectitems.cancel.label "Cancel">
|
||||||
|
|
|
@ -1148,6 +1148,9 @@ file.error.cannotAddShortcut = Shortcut files cannot be added directly. Pl
|
||||||
lookup.failure.title = Lookup Failed
|
lookup.failure.title = Lookup Failed
|
||||||
lookup.failure.description = Zotero could not find a record for the specified identifier. Please verify the identifier and try again.
|
lookup.failure.description = Zotero could not find a record for the specified identifier. Please verify the identifier and try again.
|
||||||
lookup.failureToID.description = Zotero could not find any identifiers in your input. Please verify your input and try again.
|
lookup.failureToID.description = Zotero could not find any identifiers in your input. Please verify your input and try again.
|
||||||
|
lookup.failureTooMany.description = Too many identifiers. Please enter one identifier and try again.
|
||||||
|
|
||||||
|
createParent.prompt = Enter a DOI, ISBN, PMID, or arXiv ID to identify this file
|
||||||
|
|
||||||
locate.online.label = View Online
|
locate.online.label = View Online
|
||||||
locate.online.tooltip = Go to this item online
|
locate.online.tooltip = Go to this item online
|
||||||
|
|
|
@ -22,8 +22,10 @@
|
||||||
|
|
||||||
@import "components/autosuggest";
|
@import "components/autosuggest";
|
||||||
@import "components/button";
|
@import "components/button";
|
||||||
|
@import "components/createParent";
|
||||||
@import "components/editable";
|
@import "components/editable";
|
||||||
@import "components/icons";
|
@import "components/icons";
|
||||||
|
@import "components/progressMeter";
|
||||||
@import "components/search";
|
@import "components/search";
|
||||||
@import "components/tagsBox";
|
@import "components/tagsBox";
|
||||||
@import "components/tagSelector";
|
@import "components/tagSelector";
|
||||||
|
|
35
scss/components/_createParent.scss
Normal file
35
scss/components/_createParent.scss
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
.create-parent-container {
|
||||||
|
.title {
|
||||||
|
font-size: 1.4em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
margin: 1em 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
right: -1em;
|
||||||
|
transform: translateY(-100%);
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
scss/components/_progressMeter.scss
Normal file
72
scss/components/_progressMeter.scss
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// From https://dxr.mozilla.org/mozilla-esr60/source/browser/themes/shared/downloads/progressmeter.inc.css
|
||||||
|
|
||||||
|
/*** Common-styled progressmeter ***/
|
||||||
|
.downloadProgress {
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 1px;
|
||||||
|
margin: 4px 0 0;
|
||||||
|
margin-inline-end: 12px;
|
||||||
|
|
||||||
|
/* for overriding rules in progressmeter.css */
|
||||||
|
-moz-appearance: none;
|
||||||
|
border-style: none;
|
||||||
|
background-color: transparent;
|
||||||
|
min-width: initial;
|
||||||
|
min-height: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress[mode="undetermined"] {
|
||||||
|
/* for overriding rules on global.css in Linux. */
|
||||||
|
-moz-binding: url("chrome://global/content/bindings/progressmeter.xml#progressmeter");
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress > .progress-bar {
|
||||||
|
background-color: Highlight;
|
||||||
|
|
||||||
|
/* for overriding rules in progressmeter.css */
|
||||||
|
-moz-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress[paused="true"] > .progress-bar {
|
||||||
|
background-color: GrayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress[mode="undetermined"] > .progress-bar {
|
||||||
|
/* Make a white reflecting animation.
|
||||||
|
Create a gradient with 2 identical pattern, and enlarge the size to 200%.
|
||||||
|
This allows us to animate background-position with percentage. */
|
||||||
|
background-image: linear-gradient(90deg, transparent 0%,
|
||||||
|
rgba(255,255,255,0.5) 25%,
|
||||||
|
transparent 50%,
|
||||||
|
rgba(255,255,255,0.5) 75%,
|
||||||
|
transparent 100%);
|
||||||
|
background-blend-mode: lighten;
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: downloadProgressSlideX 1.5s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress > .progress-remainder {
|
||||||
|
border: solid ButtonShadow;
|
||||||
|
border-block-start-width: 1px;
|
||||||
|
border-block-end-width: 1px;
|
||||||
|
border-inline-start-width: 0;
|
||||||
|
border-inline-end-width: 1px;
|
||||||
|
background-color: ButtonFace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress[value="0"] > .progress-remainder {
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.downloadProgress > .progress-remainder[mode="undetermined"] {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes downloadProgressSlideX {
|
||||||
|
0% {
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: -100% 0;
|
||||||
|
}
|
||||||
|
}
|
4
scss/linux/_createParent.scss
Normal file
4
scss/linux/_createParent.scss
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.create-parent-container {
|
||||||
|
// This matches the margin on the buttons in the dialog box, which are platform dependent
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
5
scss/mac/_createParent.scss
Normal file
5
scss/mac/_createParent.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.create-parent-container {
|
||||||
|
// This matches the margin on the buttons in the dialog box, which are platform dependent
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
4
scss/win/_createParent.scss
Normal file
4
scss/win/_createParent.scss
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.create-parent-container {
|
||||||
|
// This matches the margin on the buttons in the dialog box, which are platform dependent
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
@import "mac/button";
|
@import "mac/button";
|
||||||
|
@import "mac/createParent";
|
||||||
@import "mac/editable";
|
@import "mac/editable";
|
||||||
@import "mac/search";
|
@import "mac/search";
|
||||||
@import "mac/tag-selector";
|
@import "mac/tag-selector";
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// Linux specific
|
// Linux specific
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
@import "linux/createParent";
|
||||||
@import "linux/editable";
|
@import "linux/editable";
|
||||||
@import "linux/search";
|
@import "linux/search";
|
||||||
@import "linux/tagsBox";
|
@import "linux/tagsBox";
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
// Windows specific
|
// Windows specific
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
@import "win/createParent";
|
||||||
@import "win/search";
|
@import "win/search";
|
||||||
@import "win/tag-selector";
|
@import "win/tag-selector";
|
||||||
|
|
Loading…
Reference in a new issue