Bug 373502 - Implement Fx2 style microsummary picker in the properties dialog. r=dietrich.
git-svn-id: svn://10.0.0.236/trunk@222212 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
d69b531ce7
commit
4e9ba1ddf2
@ -35,7 +35,7 @@ interface nsIMicrosummaryObserver : nsISupports
|
||||
};
|
||||
|
||||
|
||||
[scriptable, uuid(71c469b4-6e31-427e-922d-48aafbd17344)]
|
||||
[scriptable, uuid(05b48344-d0a7-427e-934e-9a6e0d5ecced)]
|
||||
interface nsIMicrosummaryGenerator : nsISupports
|
||||
{
|
||||
// Has the generator itself, which may be a remote resource, been loaded.
|
||||
@ -62,6 +62,12 @@ interface nsIMicrosummaryGenerator : nsISupports
|
||||
// of the generators they create.
|
||||
readonly attribute nsIURI uri;
|
||||
|
||||
/**
|
||||
* microsummary-generator equivalence test
|
||||
* generators equal if their canonical locations equal, see uri attribute.
|
||||
*/
|
||||
boolean equals(in nsIMicrosummaryGenerator aOther);
|
||||
|
||||
// For generators installed by the user or bundled with the browser, the
|
||||
// local URI points to the location of the local file containing the
|
||||
// generator's XML.
|
||||
@ -103,7 +109,7 @@ interface nsIMicrosummaryGenerator : nsISupports
|
||||
};
|
||||
|
||||
|
||||
[scriptable, uuid(1b1f232d-e65f-446a-9984-786578526072)]
|
||||
[scriptable, uuid(a999eabf-68f9-45c2-919f-2ad33777e3e3)]
|
||||
interface nsIMicrosummary : nsISupports
|
||||
{
|
||||
// the URI of the page being summarized
|
||||
@ -139,6 +145,15 @@ interface nsIMicrosummary : nsISupports
|
||||
*/
|
||||
void removeObserver(in nsIMicrosummaryObserver observer);
|
||||
|
||||
/**
|
||||
* Microsummary equivalence test
|
||||
* Microsummaries equal if they summarize the same page with the same
|
||||
* microsummary-generator (see also nsIMicrosummaryGenerator::equals).
|
||||
*
|
||||
* Note: this method returns false if either objects don't have a generator
|
||||
*/
|
||||
boolean equals(in nsIMicrosummary aOther);
|
||||
|
||||
/**
|
||||
* Update the microsummary, first loading its generator and page content
|
||||
* as necessary. If you want know when a microsummary finishes updating,
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org> (Original Author)
|
||||
* Simon Bünzli <zeniko@gmail.com>
|
||||
* Asaf Romano <mano@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -350,8 +351,7 @@ MicrosummaryService.prototype = {
|
||||
// upgraded from earlier versions to make bug 346822 no longer significant.
|
||||
this._fixGeneratorID(resource.content, resource.uri);
|
||||
|
||||
var generator = new MicrosummaryGenerator();
|
||||
generator.localURI = resource.uri;
|
||||
var generator = new MicrosummaryGenerator(null, resource.uri);
|
||||
generator.initFromXML(resource.content);
|
||||
|
||||
// Add the generator to the local generators cache.
|
||||
@ -481,8 +481,7 @@ MicrosummaryService.prototype = {
|
||||
file = this._dirs.get("UsrMicsumGens", Ci.nsIFile);
|
||||
file.append(fileName);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
generator = new MicrosummaryGenerator();
|
||||
generator.localURI = this._ios.newFileURI(file);
|
||||
generator = new MicrosummaryGenerator(null, this._ios.newFileURI(file));
|
||||
this._localGenerators[generatorID] = generator;
|
||||
topic = "microsummary-generator-installed";
|
||||
}
|
||||
@ -563,12 +562,20 @@ MicrosummaryService.prototype = {
|
||||
// If this is the current microsummary for this bookmark, load the content
|
||||
// from the datastore so it shows up immediately in microsummary picking UI.
|
||||
if (bookmarkID && this.isMicrosummary(bookmarkID, microsummary))
|
||||
microsummary.content = this._getField(bookmarkID, FIELD_GENERATED_TITLE);
|
||||
microsummary._content = this._getField(bookmarkID, FIELD_GENERATED_TITLE);
|
||||
|
||||
microsummaries.AppendElement(microsummary);
|
||||
}
|
||||
}
|
||||
|
||||
// If a bookmark identifier has been provided, list its microsummary
|
||||
// synchronously, if any.
|
||||
if (bookmarkID && this.hasMicrosummary(bookmarkID)) {
|
||||
var currentMicrosummary = this.getMicrosummary(bookmarkID);
|
||||
if (!microsummaries.hasItemForMicrosummary(currentMicrosummary))
|
||||
microsummaries.AppendElement(currentMicrosummary);
|
||||
}
|
||||
|
||||
// Get microsummaries defined by the page. If we don't have the page,
|
||||
// download it asynchronously, and then finish populating the set.
|
||||
var resource = getLoadedMicrosummaryResource(pageURI);
|
||||
@ -868,13 +875,10 @@ MicrosummaryService.prototype = {
|
||||
var pageURI = this._getPageForBookmark(bookmarkID);
|
||||
var generatorURI = this._uri(this._getField(bookmarkID, FIELD_MICSUM_GEN_URI));
|
||||
|
||||
var localGenerator = this._localGenerators[generatorURI.spec];
|
||||
var generator = this._localGenerators[generatorURI.spec] ||
|
||||
new MicrosummaryGenerator(generatorURI);
|
||||
|
||||
var microsummary = new Microsummary(pageURI, localGenerator);
|
||||
if (!localGenerator)
|
||||
microsummary.generator.uri = generatorURI;
|
||||
|
||||
return microsummary;
|
||||
return new Microsummary(pageURI, generator);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -994,15 +998,15 @@ MicrosummaryService.prototype = {
|
||||
* for the bookmark
|
||||
*
|
||||
*/
|
||||
isMicrosummary: function MSS_isMicrosummary(bookmarkID, microsummary) {
|
||||
if (!this.hasMicrosummary(bookmarkID))
|
||||
return false;
|
||||
|
||||
var currentGen = this._getField(bookmarkID, FIELD_MICSUM_GEN_URI);
|
||||
|
||||
if (microsummary.generator.uri.equals(this._uri(currentGen)))
|
||||
return true;
|
||||
isMicrosummary: function MSS_isMicrosummary(aBookmarkID, aMicrosummary) {
|
||||
if (!aMicrosummary || !aBookmarkID)
|
||||
throw Cr.NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (this.hasMicrosummary(aBookmarkID)) {
|
||||
currentMicrosummarry = this.getMicrosummary(aBookmarkID);
|
||||
if (aMicrosummary.equals(currentMicrosummarry))
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
@ -1033,11 +1037,10 @@ MicrosummaryService.prototype = {
|
||||
throw("can't get URL for bookmark with ID " + bookmarkID);
|
||||
var generatorURI = this._uri(this._getField(bookmarkID, FIELD_MICSUM_GEN_URI));
|
||||
|
||||
var localGenerator = this._localGenerators[generatorURI.spec];
|
||||
var generator = this._localGenerators[generatorURI.spec] ||
|
||||
new MicrosummaryGenerator(generatorURI);
|
||||
|
||||
var microsummary = new Microsummary(pageURI, localGenerator);
|
||||
if (!localGenerator)
|
||||
microsummary.generator.uri = generatorURI;
|
||||
var microsummary = new Microsummary(pageURI, generator);
|
||||
|
||||
// A microsummary observer that calls the microsummary service
|
||||
// to update the datastore when the microsummary finishes loading.
|
||||
@ -1069,10 +1072,13 @@ MicrosummaryService.prototype = {
|
||||
|
||||
|
||||
|
||||
function Microsummary(pageURI, generator) {
|
||||
function Microsummary(aPageURI, aGenerator) {
|
||||
this._observers = [];
|
||||
this.pageURI = pageURI;
|
||||
this.generator = generator ? generator : new MicrosummaryGenerator();
|
||||
this._pageURI = aPageURI || null;
|
||||
this._generator = aGenerator || null;
|
||||
this._content = null;
|
||||
this._pageContent = null;
|
||||
this._updateInterval = null;
|
||||
}
|
||||
|
||||
Microsummary.prototype = {
|
||||
@ -1117,15 +1123,13 @@ Microsummary.prototype = {
|
||||
},
|
||||
|
||||
// nsIMicrosummary
|
||||
|
||||
_content: null,
|
||||
get content() {
|
||||
// If we have everything we need to generate the content, generate it.
|
||||
if (this._content == null &&
|
||||
if (!this._content &&
|
||||
this.generator.loaded &&
|
||||
(this.pageContent || !this.generator.needsPageContent)) {
|
||||
this._content = this.generator.generateMicrosummary(this.pageContent);
|
||||
this.updateInterval = this.generator.calculateUpdateInterval(this.pageContent);
|
||||
this._updateInterval = this.generator.calculateUpdateInterval(this.pageContent);
|
||||
}
|
||||
|
||||
// Note: we return "null" if the content wasn't already generated and we
|
||||
@ -1135,17 +1139,21 @@ Microsummary.prototype = {
|
||||
// setting an observer to tell them when content generation is done.
|
||||
return this._content;
|
||||
},
|
||||
set content(newValue) { this._content = newValue },
|
||||
|
||||
_generator: null,
|
||||
get generator() { return this._generator },
|
||||
set generator(newValue) { this._generator = newValue },
|
||||
set generator(newValue) { return this._generator = newValue },
|
||||
|
||||
_pageURI: null,
|
||||
get pageURI() { return this._pageURI },
|
||||
set pageURI(newValue) { this._pageURI = newValue },
|
||||
get pageURI() { return this._pageURI },
|
||||
|
||||
equals: function(aOther) {
|
||||
if (this._generator &&
|
||||
this._pageURI.equals(aOther.pageURI) &&
|
||||
this._generator.equals(aOther.generator))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_pageContent: null,
|
||||
get pageContent() {
|
||||
if (!this._pageContent) {
|
||||
// If the page is currently loaded into a browser window, use that.
|
||||
@ -1158,16 +1166,13 @@ Microsummary.prototype = {
|
||||
|
||||
return this._pageContent;
|
||||
},
|
||||
set pageContent(newValue) { this._pageContent = newValue },
|
||||
set pageContent(newValue) { return this._pageContent = newValue },
|
||||
|
||||
_updateInterval: null,
|
||||
get updateInterval() { return this._updateInterval; },
|
||||
set updateInterval(newValue) { this._updateInterval = newValue; },
|
||||
set updateInterval(newValue) { return this._updateInterval = newValue; },
|
||||
|
||||
// nsIMicrosummary
|
||||
|
||||
_observers: null,
|
||||
|
||||
addObserver: function MS_addObserver(observer) {
|
||||
// Register the observer, but only if it isn't already registered,
|
||||
// so that we don't call the same observer twice for any given change.
|
||||
@ -1242,8 +1247,8 @@ Microsummary.prototype = {
|
||||
|
||||
// Now that we have both the generator and (if needed) the page content,
|
||||
// generate the microsummary, then let the observers know about it.
|
||||
this.content = this.generator.generateMicrosummary(this.pageContent);
|
||||
this.updateInterval = this.generator.calculateUpdateInterval(this.pageContent);
|
||||
this._content = this.generator.generateMicrosummary(this.pageContent);
|
||||
this._updateInterval = this.generator.calculateUpdateInterval(this.pageContent);
|
||||
this.pageContent = null;
|
||||
for ( var i = 0; i < this._observers.length; i++ )
|
||||
this._observers[i].onContentLoaded(this);
|
||||
@ -1381,7 +1386,15 @@ Microsummary.prototype = {
|
||||
|
||||
|
||||
|
||||
function MicrosummaryGenerator() {}
|
||||
function MicrosummaryGenerator(aURI, aLocalURI, aName) {
|
||||
this._uri = aURI || null;
|
||||
this._localURI = aLocalURI || null;
|
||||
this._name = aName || null;
|
||||
this._loaded = false;
|
||||
this._rules = [];
|
||||
this._template = null;
|
||||
this._content = null;
|
||||
}
|
||||
|
||||
MicrosummaryGenerator.prototype = {
|
||||
|
||||
@ -1412,33 +1425,18 @@ MicrosummaryGenerator.prototype = {
|
||||
// but for generators stored in the app or profile generators directory
|
||||
// it's the value of the generator tag's "uri" attribute (or its local URI
|
||||
// should the "uri" attribute be missing).
|
||||
_uri: null,
|
||||
get uri() { return this._uri || this.localURI },
|
||||
set uri(newValue) { this._uri = newValue },
|
||||
|
||||
// For generators bundled with the browser or installed by the user,
|
||||
// the local URI is the URI of the local file containing the generator XML.
|
||||
_localURI: null,
|
||||
get localURI() { return this._localURI },
|
||||
set localURI(newValue) { this._localURI = newValue },
|
||||
|
||||
_name: null,
|
||||
get name() { return this._name },
|
||||
set name(newValue) { this._name = newValue },
|
||||
|
||||
_template: null,
|
||||
get template() { return this._template },
|
||||
set template(newValue) { this._template = newValue },
|
||||
|
||||
_content: null,
|
||||
get content() { return this._content },
|
||||
set content(newValue) { this._content = newValue },
|
||||
|
||||
_loaded: false,
|
||||
get loaded() { return this._loaded },
|
||||
set loaded(newValue) { this._loaded = newValue },
|
||||
|
||||
_rules: null,
|
||||
equals: function(aOther) {
|
||||
// XXX: could the uri attribute for an exposed generator ever be null?
|
||||
return aOther.uri.equals(this.uri);
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether or not the generator applies to a given URI.
|
||||
@ -1475,12 +1473,12 @@ MicrosummaryGenerator.prototype = {
|
||||
},
|
||||
|
||||
get needsPageContent() {
|
||||
if (this.template)
|
||||
if (this._template)
|
||||
return true;
|
||||
else if (this.content)
|
||||
if (this._content)
|
||||
return false;
|
||||
else
|
||||
throw("needsPageContent called on uninitialized microsummary generator");
|
||||
|
||||
throw("needsPageContent called on uninitialized microsummary generator");
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1490,11 +1488,10 @@ MicrosummaryGenerator.prototype = {
|
||||
*
|
||||
* @param text
|
||||
* the text content
|
||||
*
|
||||
*/
|
||||
initFromText: function(text) {
|
||||
this.content = text;
|
||||
this.loaded = true;
|
||||
this._content = text;
|
||||
this._loaded = true;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1518,12 +1515,12 @@ MicrosummaryGenerator.prototype = {
|
||||
if (!generatorNode)
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
|
||||
this.name = generatorNode.getAttribute("name");
|
||||
this._name = generatorNode.getAttribute("name");
|
||||
|
||||
// If this is a local generator (i.e. it has a local URI), then we have
|
||||
// to retrieve its URI from the "uri" attribute of its generator tag.
|
||||
if (this.localURI && generatorNode.hasAttribute("uri")) {
|
||||
this.uri = this._ios.newURI(generatorNode.getAttribute("uri"), null, null);
|
||||
this._uri = this._ios.newURI(generatorNode.getAttribute("uri"), null, null);
|
||||
}
|
||||
|
||||
function getFirstChildByTagName(tagName, parentNode, namespace) {
|
||||
@ -1539,7 +1536,7 @@ MicrosummaryGenerator.prototype = {
|
||||
// Slurp the include/exclude rules that determine the pages to which
|
||||
// this generator applies. Order is important, so we add the rules
|
||||
// in the order in which they appear in the XML.
|
||||
this._rules = [];
|
||||
this._rules.splice(0);
|
||||
var pages = getFirstChildByTagName("pages", generatorNode, MICSUM_NS);
|
||||
if (pages) {
|
||||
// XXX Make sure the pages tag exists.
|
||||
@ -1588,23 +1585,23 @@ MicrosummaryGenerator.prototype = {
|
||||
|
||||
var templateNode = getFirstChildByTagName("template", generatorNode, MICSUM_NS);
|
||||
if (templateNode) {
|
||||
this.template = getFirstChildByTagName("transform", templateNode, XSLT_NS) ||
|
||||
getFirstChildByTagName("stylesheet", templateNode, XSLT_NS);
|
||||
this._template = getFirstChildByTagName("transform", templateNode, XSLT_NS) ||
|
||||
getFirstChildByTagName("stylesheet", templateNode, XSLT_NS);
|
||||
}
|
||||
// XXX Make sure the template is a valid XSL transform sheet.
|
||||
|
||||
this.loaded = true;
|
||||
this._loaded = true;
|
||||
},
|
||||
|
||||
generateMicrosummary: function MSD_generateMicrosummary(pageContent) {
|
||||
|
||||
var content;
|
||||
|
||||
if (this.content) {
|
||||
content = this.content;
|
||||
} else if (this.template) {
|
||||
if (this._content)
|
||||
content = this._content;
|
||||
else if (this._template)
|
||||
content = this._processTemplate(pageContent);
|
||||
} else
|
||||
else
|
||||
throw("generateMicrosummary called on uninitialized microsummary generator");
|
||||
|
||||
// Clean up the output
|
||||
@ -1616,7 +1613,7 @@ MicrosummaryGenerator.prototype = {
|
||||
},
|
||||
|
||||
calculateUpdateInterval: function MSD_calculateUpdateInterval(doc) {
|
||||
if (this.content || !this._updateIntervals || !doc)
|
||||
if (this._content || !this._updateIntervals || !doc)
|
||||
return null;
|
||||
|
||||
for (var i = 0; i < this._updateIntervals.length; i++) {
|
||||
@ -1636,7 +1633,7 @@ MicrosummaryGenerator.prototype = {
|
||||
},
|
||||
|
||||
_processTemplate: function MSD__processTemplate(doc) {
|
||||
LOG("processing template " + this.template + " against document " + doc);
|
||||
LOG("processing template " + this._template + " against document " + doc);
|
||||
|
||||
// XXX Should we just have one global instance of the processor?
|
||||
var processor = Cc["@mozilla.org/document-transformer;1?type=xslt"].
|
||||
@ -1646,7 +1643,7 @@ MicrosummaryGenerator.prototype = {
|
||||
// for security (otherwise local generators would be able to load local files).
|
||||
processor.flags |= Ci.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
|
||||
|
||||
processor.importStylesheet(this.template);
|
||||
processor.importStylesheet(this._template);
|
||||
var fragment = processor.transformToFragment(doc, doc);
|
||||
|
||||
LOG("template processing result: " + fragment.textContent);
|
||||
@ -1672,7 +1669,6 @@ function MicrosummarySet() {
|
||||
}
|
||||
|
||||
MicrosummarySet.prototype = {
|
||||
|
||||
// IO Service
|
||||
__ios: null,
|
||||
get _ios() {
|
||||
@ -1695,9 +1691,6 @@ MicrosummarySet.prototype = {
|
||||
return this;
|
||||
},
|
||||
|
||||
_observers: null,
|
||||
_elements: null,
|
||||
|
||||
// nsIMicrosummaryObserver
|
||||
|
||||
onContentLoaded: function MSSet_onContentLoaded(microsummary) {
|
||||
@ -1780,13 +1773,25 @@ MicrosummarySet.prototype = {
|
||||
continue;
|
||||
}
|
||||
|
||||
var microsummary = new Microsummary(resource.uri, null);
|
||||
microsummary.generator.name = linkTitle;
|
||||
microsummary.generator.uri = generatorURI;
|
||||
this.AppendElement(microsummary);
|
||||
var generator = new MicrosummaryGenerator(generatorURI, null, linkTitle);
|
||||
var microsummary = new Microsummary(resource.uri, generator);
|
||||
if (!this.hasItemForMicrosummary(microsummary))
|
||||
this.AppendElement(microsummary);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether the given microsumary is already represented in the
|
||||
* set.
|
||||
*/
|
||||
hasItemForMicrosummary: function MSSet_hasItemForMicrosummary(aMicrosummary) {
|
||||
for (var i = 0; i < this._elements.length; i++) {
|
||||
if (this._elements[i].equals(aMicrosummary))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// XXX Turn this into a complete implementation of nsICollection?
|
||||
AppendElement: function MSSet_AppendElement(element) {
|
||||
// Query the element to a microsummary.
|
||||
@ -1818,6 +1823,7 @@ MicrosummarySet.prototype = {
|
||||
*/
|
||||
function ArrayEnumerator(aItems) {
|
||||
this._index = 0;
|
||||
this._contents = [];
|
||||
if (aItems) {
|
||||
for (var i = 0; i < aItems.length; ++i) {
|
||||
if (!aItems[i])
|
||||
@ -1837,9 +1843,6 @@ ArrayEnumerator.prototype = {
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
_index: 0,
|
||||
_contents: [],
|
||||
|
||||
hasMoreElements: function() {
|
||||
return this._index < this._contents.length;
|
||||
@ -1892,7 +1895,18 @@ function MicrosummaryResource(uri) {
|
||||
if (uri.scheme != "http" && uri.scheme != "https" && uri.scheme != "file")
|
||||
throw NS_ERROR_DOM_BAD_URI;
|
||||
|
||||
this._uri = uri;
|
||||
this._uri = uri || null;
|
||||
this._content = null;
|
||||
this._contentType = null;
|
||||
this._isXML = false;
|
||||
this.__authFailed = false;
|
||||
|
||||
// A function to call when we finish loading/parsing the resource.
|
||||
this._loadCallback = null;
|
||||
// A function to call if we get an error while loading/parsing the resource.
|
||||
this._errorCallback = null;
|
||||
// A hidden iframe to parse HTML content.
|
||||
this._iframe = null;
|
||||
}
|
||||
|
||||
MicrosummaryResource.prototype = {
|
||||
@ -1905,35 +1919,22 @@ MicrosummaryResource.prototype = {
|
||||
return this.__ios;
|
||||
},
|
||||
|
||||
_uri: null,
|
||||
get uri() {
|
||||
return this._uri;
|
||||
},
|
||||
|
||||
_content: null,
|
||||
get content() {
|
||||
return this._content;
|
||||
},
|
||||
|
||||
_contentType: null,
|
||||
get contentType() {
|
||||
return this._contentType;
|
||||
},
|
||||
|
||||
_isXML: false,
|
||||
get isXML() {
|
||||
return this._isXML;
|
||||
},
|
||||
|
||||
// A function to call when we finish loading/parsing the resource.
|
||||
_loadCallback: null,
|
||||
|
||||
// A function to call if we get an error while loading/parsing the resource.
|
||||
_errorCallback: null,
|
||||
|
||||
// A hidden iframe to parse HTML content.
|
||||
_iframe: null,
|
||||
|
||||
// Implement notification callback interfaces so we can suppress UI
|
||||
// and abort loads for bad SSL certs and HTTP authorization requests.
|
||||
|
||||
@ -1995,9 +1996,8 @@ MicrosummaryResource.prototype = {
|
||||
// Auth requests appear to succeed when we cancel them (since the server
|
||||
// redirects us to a "you're not authorized" page), so we have to set a flag
|
||||
// to let the load handler know to treat the load as a failure.
|
||||
__authFailed: false,
|
||||
get _authFailed() { return this.__authFailed },
|
||||
set _authFailed(newValue) { this.__authFailed = newValue },
|
||||
get _authFailed() { return this.__authFailed; },
|
||||
set _authFailed(newValue) { return this.__authFailed = newValue },
|
||||
|
||||
// nsIAuthPromptProvider
|
||||
|
||||
|
||||
@ -78,7 +78,6 @@
|
||||
* - "location"
|
||||
* - "description"
|
||||
* - "keyword"
|
||||
* - "microsummary"
|
||||
* - "load in sidebar"
|
||||
* - "feedURI"
|
||||
* - "siteURI"
|
||||
@ -358,30 +357,12 @@ var BookmarkPropertiesPanel = {
|
||||
}
|
||||
},
|
||||
|
||||
_initMicrosummaryPicker: function BPP__initMicrosummaryPicker() {
|
||||
var placeURI = null;
|
||||
if (this._action == ACTION_EDIT) {
|
||||
NS_ASSERT(this._bookmarkId, "No bookmark identifier");
|
||||
placeURI = PlacesUtils.bookmarks.getItemURI(this._bookmarkId);
|
||||
}
|
||||
try {
|
||||
this._microsummaries = this._mss.getMicrosummaries(this._bookmarkURI,
|
||||
placeURI);
|
||||
}
|
||||
catch(ex) {
|
||||
// There was a problem retrieving microsummaries; disable the picker.
|
||||
// The microsummary service will throw an exception in at least
|
||||
// two cases:
|
||||
// 1. the bookmarked URI contains a scheme that the service won't
|
||||
// download for security reasons (currently it only handles http,
|
||||
// https, and file);
|
||||
// 2. the page to which the URI refers isn't HTML or XML (the only two
|
||||
// content types the service knows how to summarize).
|
||||
this._element("microsummaryRow").hidden = true;
|
||||
return;
|
||||
}
|
||||
this._microsummaries.addObserver(this._microsummaryObserver);
|
||||
this._rebuildMicrosummaryPicker();
|
||||
QueryInterface: function BPP_QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIMicrosummaryObserver) ||
|
||||
aIID.eqauls(Ci.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
_element: function BPP__element(aID) {
|
||||
@ -398,7 +379,7 @@ var BookmarkPropertiesPanel = {
|
||||
return;
|
||||
|
||||
if (hiddenRows.indexOf("title") != -1)
|
||||
this._element("titleTextfield").hidden = true;
|
||||
this._element("namePicker").hidden = true;
|
||||
if (hiddenRows.indexOf("location") != -1)
|
||||
this._element("locationRow").hidden = true;
|
||||
if (hiddenRows.indexOf("keyword") != -1)
|
||||
@ -411,8 +392,6 @@ var BookmarkPropertiesPanel = {
|
||||
this._element("livemarkFeedLocationRow").hidden = true;
|
||||
if (hiddenRows.indexOf("siteURI") != -1)
|
||||
this._element("livemarkSiteLocationRow").hidden = true;
|
||||
if (hiddenRows.indexOf("microsummary") != -1)
|
||||
this._element("microsummaryRow").hidden = true;
|
||||
if (hiddenRows.indexOf("load in sidebar") != -1)
|
||||
this._element("loadInSidebarCheckbox").hidden = true;
|
||||
},
|
||||
@ -423,8 +402,8 @@ var BookmarkPropertiesPanel = {
|
||||
_populateProperties: function BPP__populateProperties() {
|
||||
document.title = this._getDialogTitle();
|
||||
document.documentElement.getButton("accept").label = this._getAcceptLabel();
|
||||
|
||||
this._element("titleTextfield").value = this._itemTitle;
|
||||
|
||||
this._initNamePicker();
|
||||
this._element("descriptionTextfield").value = this._itemDescription;
|
||||
|
||||
if (this._itemType == BOOKMARK_ITEM) {
|
||||
@ -454,83 +433,127 @@ var BookmarkPropertiesPanel = {
|
||||
this._element("livemarkSiteLocationRow").hidden = true;
|
||||
}
|
||||
|
||||
if (this._itemType == BOOKMARK_ITEM && this._bookmarkURI) {
|
||||
// _initMicrosummaryPicker may also hide the row
|
||||
this._initMicrosummaryPicker();
|
||||
}
|
||||
else
|
||||
this._element("microsummaryRow").hidden = true;
|
||||
|
||||
if (this._action == ACTION_EDIT)
|
||||
this._element("folderRow").hidden = true;
|
||||
},
|
||||
|
||||
//XXXDietrich - bug 370215 - update to use bookmark id once 360133 is fixed.
|
||||
_rebuildMicrosummaryPicker: function BPP__rebuildMicrosummaryPicker() {
|
||||
var microsummaryMenuList = this._element("microsummaryMenuList");
|
||||
var microsummaryMenuPopup = this._element("microsummaryMenuPopup");
|
||||
_createMicrosummaryMenuItem:
|
||||
function BPP__createMicrosummaryMenuItem(aMicrosummary) {
|
||||
var menuItem = document.createElement("menuitem");
|
||||
|
||||
// Remove old items from the menu, except the first item, which represents
|
||||
// "don't show a microsummary; show the page title instead".
|
||||
while (microsummaryMenuPopup.childNodes.length > 1)
|
||||
microsummaryMenuPopup.removeChild(microsummaryMenuPopup.lastChild);
|
||||
// Store a reference to the microsummary in the menu item, so we know
|
||||
// which microsummary this menu item represents when it's time to
|
||||
// save changes or load its content.
|
||||
menuItem.microsummary = aMicrosummary;
|
||||
|
||||
var enumerator = this._microsummaries.Enumerate();
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var microsummary = enumerator.getNext().QueryInterface(Ci.nsIMicrosummary);
|
||||
// Content may have to be generated asynchronously; we don't necessarily
|
||||
// have it now. If we do, great; otherwise, fall back to the generator
|
||||
// name, then the URI, and we trigger a microsummary content update. Once
|
||||
// the update completes, the microsummary will notify our observer to
|
||||
// update the corresponding menu-item.
|
||||
// XXX Instead of just showing the generator name or (heaven forbid)
|
||||
// its URI when we don't have content, we should tell the user that
|
||||
// we're loading the microsummary, perhaps with some throbbing to let
|
||||
// her know it is in progress.
|
||||
if (aMicrosummary.content)
|
||||
menuItem.setAttribute("label", aMicrosummary.content);
|
||||
else {
|
||||
menuItem.setAttribute("label", aMicrosummary.generator.name ||
|
||||
aMicrosummary.generator.uri.spec);
|
||||
aMicrosummary.update();
|
||||
}
|
||||
|
||||
var menuItem = document.createElement("menuitem");
|
||||
return menuItem;
|
||||
},
|
||||
|
||||
// Store a reference to the microsummary in the menu item, so we know
|
||||
// which microsummary this menu item represents when it's time to save
|
||||
// changes to the datastore.
|
||||
menuItem.microsummary = microsummary;
|
||||
_initNamePicker: function BPP_initNamePicker() {
|
||||
var userEnteredNameField = this._element("userEnteredName");
|
||||
var namePicker = this._element("namePicker");
|
||||
userEnteredNameField.label = this._itemTitle;
|
||||
|
||||
// Content may have to be generated asynchronously; we don't necessarily
|
||||
// have it now. If we do, great; otherwise, fall back to the generator
|
||||
// name, then the URI, and we trigger a microsummary content update.
|
||||
// Once the update completes, the microsummary will notify our observer
|
||||
// to rebuild the menu.
|
||||
// XXX Instead of just showing the generator name or (heaven forbid)
|
||||
// its URI when we don't have content, we should tell the user that we're
|
||||
// loading the microsummary, perhaps with some throbbing to let her know
|
||||
// it's in progress.
|
||||
if (microsummary.content)
|
||||
menuItem.setAttribute("label", microsummary.content);
|
||||
else {
|
||||
menuItem.setAttribute("label", microsummary.generator ?
|
||||
microsummary.generator.name :
|
||||
microsummary.generatorURI.spec);
|
||||
microsummary.update();
|
||||
// Non-bookmark items always use the item-title itself
|
||||
if (this._itemType != BOOKMARK_ITEM || !this._bookmarkURI) {
|
||||
namePicker.selectedItem = userEnteredNameField;
|
||||
return;
|
||||
}
|
||||
|
||||
var itemToSelect = userEnteredNameField;
|
||||
var placeURI = null;
|
||||
if (this._action == ACTION_EDIT) {
|
||||
NS_ASSERT(this._bookmarkId, "No bookmark identifier");
|
||||
placeURI = PlacesUtils.bookmarks.getItemURI(this._bookmarkId);
|
||||
}
|
||||
try {
|
||||
this._microsummaries = this._mss.getMicrosummaries(this._bookmarkURI,
|
||||
placeURI);
|
||||
}
|
||||
catch(ex) {
|
||||
// getMicrosummaries will throw an exception in at least two cases:
|
||||
// 1. the bookmarked URI contains a scheme that the service won't
|
||||
// download for security reasons (currently it only handles http,
|
||||
// https, and file);
|
||||
// 2. the page to which the URI refers isn't HTML or XML (the only two
|
||||
// content types the service knows how to summarize).
|
||||
this._microsummaries = null;
|
||||
}
|
||||
if (this._microsummaries) {
|
||||
var enumerator = this._microsummaries.Enumerate();
|
||||
|
||||
if (enumerator.hasMoreElements()) {
|
||||
// Show the drop marker if there are microsummaries
|
||||
namePicker.setAttribute("droppable", "true");
|
||||
|
||||
var menupopup = namePicker.menupopup;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var microsummary = enumerator.getNext()
|
||||
.QueryInterface(Ci.nsIMicrosummary);
|
||||
var menuItem = this._createMicrosummaryMenuItem(microsummary);
|
||||
|
||||
if (this._action == ACTION_EDIT &&
|
||||
this._mss.isMicrosummary(placeURI, microsummary))
|
||||
itemToSelect = menuItem;
|
||||
|
||||
menupopup.appendChild(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
microsummaryMenuPopup.appendChild(menuItem);
|
||||
this._microsummaries.addObserver(this);
|
||||
}
|
||||
|
||||
if (this._action == ACTION_EDIT) {
|
||||
NS_ASSERT(this._bookmarkId, "No bookmark identifier");
|
||||
var placeURI = PlacesUtils.bookmarks.getItemURI(this._bookmarkId);
|
||||
// Select the item if this is the current microsummary for the bookmark.
|
||||
if (this._mss.isMicrosummary(placeURI, microsummary))
|
||||
microsummaryMenuList.selectedItem = menuItem;
|
||||
namePicker.selectedItem = itemToSelect;
|
||||
},
|
||||
|
||||
// nsIMicrosummaryObserver
|
||||
onContentLoaded: function BPP_onContentLoaded(aMicrosummary) {
|
||||
var namePicker = this._element("namePicker");
|
||||
var childNodes = namePicker.menupopup.childNodes;
|
||||
|
||||
// 0: user-entered item; 1: separator
|
||||
for (var i = 2; i < childNodes.length; i++) {
|
||||
if (childNodes[i].microsummary == aMicrosummary) {
|
||||
var newLabel = aMicrosummary.content;
|
||||
// XXXmano: non-editable menulist would do this for us, see bug 360220
|
||||
// We should fix editable-menulsits to set the DOMAttrModified as well
|
||||
//
|
||||
// Also note the order importance: if the label of the menu-item is
|
||||
// set the something different than the menulist's current value,
|
||||
// the menulist no longer has selectedItem set
|
||||
if (namePicker.selectedItem == childNodes[i])
|
||||
namePicker.value = newLabel;
|
||||
|
||||
childNodes[i].label = newLabel;
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_microsummaryObserver: {
|
||||
QueryInterface: function (aIID) {
|
||||
if (!aIID.equals(Ci.nsIMicrosummaryObserver) &&
|
||||
!aIID.equals(Ci.nsISupports))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
onElementAppended: function BPP_onElementAppended(aMicrosummary) {
|
||||
var namePicker = this._element("namePicker");
|
||||
namePicker.menupopup
|
||||
.appendChild(this._createMicrosummaryMenuItem(aMicrosummary));
|
||||
|
||||
onContentLoaded: function(aMicrosummary) {
|
||||
BookmarkPropertiesPanel._rebuildMicrosummaryPicker();
|
||||
},
|
||||
|
||||
onElementAppended: function(aMicrosummary) {
|
||||
BookmarkPropertiesPanel._rebuildMicrosummaryPicker();
|
||||
}
|
||||
// Make sure the drop-marker is shown
|
||||
namePicker.setAttribute("droppable", "true");
|
||||
},
|
||||
|
||||
/**
|
||||
@ -544,7 +567,7 @@ var BookmarkPropertiesPanel = {
|
||||
|
||||
onDialogUnload: function BPP_onDialogUnload() {
|
||||
if (this._microsummaries)
|
||||
this._microsummaries.removeObserver(this._microsummaryObserver);
|
||||
this._microsummaries.removeObserver(this);
|
||||
},
|
||||
|
||||
onDialogAccept: function BPP_onDialogAccept() {
|
||||
@ -648,14 +671,13 @@ var BookmarkPropertiesPanel = {
|
||||
if (siteURIString)
|
||||
siteURI = PlacesUtils._uri(siteURIString);
|
||||
|
||||
var name = this._element("titleTextfield").value;
|
||||
|
||||
var name = this._element("namePicker").value;
|
||||
return new PlacesCreateLivemarkTransaction(feedURI, siteURI,
|
||||
name, containerId,
|
||||
indexInContainer);
|
||||
}
|
||||
else if (this._itemType == BOOKMARK_FOLDER) { // folder
|
||||
var name = this._element("titleTextfield").value;
|
||||
var name = this._element("namePicker").value;
|
||||
return new PlacesCreateFolderTransaction(name, containerId,
|
||||
indexInContainer);
|
||||
}
|
||||
@ -688,7 +710,7 @@ var BookmarkPropertiesPanel = {
|
||||
// title transaction
|
||||
// XXXmano: this isn't necessary for new folders. We should probably
|
||||
// make insertItem take a title too (like insertFolder)
|
||||
var newTitle = this._element("titleTextfield").value;
|
||||
var newTitle = this._element("userEnteredName").label;
|
||||
if (this._action != ACTION_EDIT || newTitle != this._itemTitle)
|
||||
transactions.push(this._getEditTitleTransaction(itemId, newTitle));
|
||||
|
||||
@ -736,17 +758,18 @@ var BookmarkPropertiesPanel = {
|
||||
}
|
||||
|
||||
// microsummaries
|
||||
var menuList = this._element("microsummaryMenuList");
|
||||
if (isElementVisible(menuList)) {
|
||||
if (this._itemType == BOOKMARK_ITEM) {
|
||||
var namePicker = this._element("namePicker");
|
||||
|
||||
// Something should always be selected in the microsummary menu,
|
||||
// but if nothing is selected, then conservatively assume we should
|
||||
// just display the bookmark title.
|
||||
if (menuList.selectedIndex == -1)
|
||||
menuList.selectedIndex = 0;
|
||||
if (namePicker.selectedIndex == -1)
|
||||
namePicker.selectedIndex = 0;
|
||||
|
||||
// This will set microsummary == undefined if the user selected
|
||||
// the "don't display a microsummary" item.
|
||||
var newMicrosummary = menuList.selectedItem.microsummary;
|
||||
var newMicrosummary = namePicker.selectedItem.microsummary;
|
||||
|
||||
if (this._action == ACTION_ADD && newMicrosummary) {
|
||||
transactions.push(
|
||||
@ -818,5 +841,9 @@ var BookmarkPropertiesPanel = {
|
||||
this._tm.doTransaction(aggregate);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onNamePickerInput: function BPP_onNamePickerInput() {
|
||||
this._element("userEnteredName").label = this._element("namePicker").value;
|
||||
}
|
||||
};
|
||||
|
||||
@ -37,8 +37,19 @@
|
||||
</columns>
|
||||
<rows id="placesInfoRows">
|
||||
<row id="titleRow" align="center">
|
||||
<label value="&bookmark.property.title;" control="titleTextfield"/>
|
||||
<textbox id="titleTextfield"/>
|
||||
<label value="&bookmark.property.title;" control="namePicker"/>
|
||||
<menulist id="namePicker"
|
||||
editable="true"
|
||||
droppable="false"
|
||||
oninput="BookmarkPropertiesPanel.onNamePickerInput();">
|
||||
<menupopup>
|
||||
<menuitem id="userEnteredName"/>
|
||||
<menuitem disabled="true">
|
||||
<menuseparator flex="1"/>
|
||||
<label value="&liveTitlesSeparator.label;"/>
|
||||
</menuitem>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</row>
|
||||
<row id="locationRow" align="center">
|
||||
<label value="&bookmark.property.location;" control="editURLBar"/>
|
||||
@ -66,15 +77,6 @@
|
||||
<label value="&bookmark.property.description;" control="descriptionTextfield"/>
|
||||
<textbox id="descriptionTextfield" multiline="true"/>
|
||||
</row>
|
||||
<row id="microsummaryRow" align="center">
|
||||
<label value="&bookmark.property.microsummary;" control="microsummaryMenuList"/>
|
||||
<menulist id="microsummaryMenuList">
|
||||
<menupopup id="microsummaryMenuPopup">
|
||||
<menuitem label="&bookmark.property.microsummary.none;"
|
||||
selected="true"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</row>
|
||||
<row id="folderRow" flex="1" style="min-height: 100px;">
|
||||
<vbox align="end">
|
||||
<hbox align="start" flex="1">
|
||||
|
||||
@ -8,10 +8,8 @@
|
||||
"Shortcut">
|
||||
<!ENTITY bookmark.property.description
|
||||
"Description">
|
||||
<!ENTITY bookmark.property.microsummary
|
||||
"Summary">
|
||||
<!ENTITY bookmark.property.microsummary.none
|
||||
"Don't Display a Summary">
|
||||
<!ENTITY liveTitlesSeparator.label
|
||||
"Live Titles">
|
||||
<!ENTITY bookmark.property.folders
|
||||
"Folders">
|
||||
<!ENTITY bookmark.property.folder_list
|
||||
|
||||
@ -1,3 +1,98 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Firefox.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||
|
||||
/**** folder tree ****/
|
||||
#folderTree {
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
/**** name picker ****/
|
||||
|
||||
/* Make the microsummary picker look like a regular textbox instead of
|
||||
* an editable menulist when no microsummaries are available.
|
||||
*/
|
||||
|
||||
menulist#namePicker[droppable="false"] {
|
||||
-moz-appearance: none;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
padding: 0px;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
menulist#namePicker[droppable="false"] > .menulist-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
menulist#namePicker[droppable="false"] > .menulist-editable-box {
|
||||
/* These rules are duplicates of the rules for the textbox element
|
||||
* in textbox.css and should track changes in that file.
|
||||
*/
|
||||
-moz-appearance: textfield;
|
||||
cursor: text;
|
||||
margin: 2px 4px;
|
||||
border: 2px solid;
|
||||
-moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
|
||||
-moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
|
||||
-moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
|
||||
-moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
|
||||
padding: 2px 2px 3px 4px;
|
||||
background-color: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
|
||||
menulist#namePicker[droppable="false"] > .menulist-editable-box > html|*.textbox-input {
|
||||
margin: 0px !important;
|
||||
border: none !important;
|
||||
padding: 0px !important;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
/* Hide the drop marker and the popup. */
|
||||
|
||||
menulist#namePicker[droppable="false"] > .menulist-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
menulist#namePicker[droppable="false"] > menupopup {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,75 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Firefox.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
* Simon BŸnzli <zeniko@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**** folder tree ****/
|
||||
#folderTree {
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
/**** name picker ****/
|
||||
|
||||
/* Make the microsummary picker look like a regular textbox instead of
|
||||
* an editable menulist when no microsummaries are available.
|
||||
*/
|
||||
|
||||
menulist#namePicker[droppable="false"] {
|
||||
/* These rules come from the textbox element in textbox.css. */
|
||||
|
||||
/* Normal editable menulists set this to "none". */
|
||||
-moz-appearance: textfield;
|
||||
cursor: text;
|
||||
|
||||
border: 2px solid;
|
||||
-moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
|
||||
-moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
|
||||
-moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
|
||||
-moz-border-left-colors: ThreeDShadow ThreeDDarkShadow;
|
||||
background-color: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
|
||||
menulist#namePicker[droppable="false"] > .menulist-editable-box {
|
||||
/* Normal editable menulists set this to "menulist-textfield". */
|
||||
-moz-appearance: none;
|
||||
padding: 2px 2px 3px 4px;
|
||||
}
|
||||
|
||||
/* Hide the drop marker and the popup when no microsummaries are available. */
|
||||
menulist#namePicker[droppable="false"] > .menulist-dropmarker,
|
||||
menulist#namePicker[droppable="false"] > menupopup {
|
||||
display: none;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user