mirror of
https://github.com/zotero/zotero.git
synced 2026-10-08 03:08:19 +00:00
Translator errors now include a link to an upcoming Known Translator Issues page, which will eventually contain instructions for helping to fix broken translators
Related progress window changes: - Translators now use Zotero.ProgressWindow rather than Zotero_Browser.Progress (removed) -- browser.js currently creates a single instance of ProgressWindow per browser window for its use - Progress boxes now stay open while the mouse is over them and close when you click on them - New method Zotero.Utilities.parseMarkup() -- parses a text string for HTML/XUL markup and returns an array of parts (currently only <a>) - Using parseMarkup, ProgressWindow.addDescription() now supports adding clickable links to notifications Other progress window changes: - Fixed progress window offsets on Mac (on OS X outerHeight doesn't include 22px title bar and moveTo() positions popups 22px below the specified location) -- need to test this on other platforms - Added support for displaying progress window notifications relative to screen edges when there's no browser window Unrelated: - Fixed warning when calling getSelectedCollections() before the Z pane had been opened
This commit is contained in:
parent
47ec444b72
commit
541c228a37
6 changed files with 239 additions and 194 deletions
|
|
@ -372,11 +372,15 @@ var Zotero_Browser = new function() {
|
|||
*/
|
||||
function finishScraping(obj, returnValue, collection) {
|
||||
if(!returnValue) {
|
||||
Zotero_Browser.Progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
|
||||
Zotero_Browser.Progress.addDescription(Zotero.getString("ingester.scrapeErrorDescription"));
|
||||
Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
|
||||
// Include link to Known Translator Issues page
|
||||
var url = "http://www.zotero.org/documentation/known_translator_issues";
|
||||
var linkText = '<a href="' + url + '" tooltiptext="' + url + '">'
|
||||
+ Zotero.getString('ingester.scrapeErrorDescription.linkText') + '</a>';
|
||||
Zotero_Browser.progress.addDescription(Zotero.getString("ingester.scrapeErrorDescription", linkText));
|
||||
}
|
||||
|
||||
Zotero_Browser.Progress.fade();
|
||||
Zotero_Browser.progress.fade();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -386,7 +390,8 @@ var Zotero_Browser = new function() {
|
|||
function itemDone(obj, item, collection) {
|
||||
var title = item.getField("title");
|
||||
var icon = item.getImageSrc();
|
||||
Zotero_Browser.Progress.addLines([title], [icon]);
|
||||
Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scraping"));
|
||||
Zotero_Browser.progress.addLines([title], [icon]);
|
||||
|
||||
// add item to collection, if one was specified
|
||||
if(collection) {
|
||||
|
|
@ -547,7 +552,7 @@ Zotero_Browser.Tab.prototype._searchFrames = function(rootDoc, searchDoc) {
|
|||
*/
|
||||
Zotero_Browser.Tab.prototype.translate = function(saveLocation) {
|
||||
if(this.page.translators && this.page.translators.length) {
|
||||
Zotero_Browser.Progress.show();
|
||||
Zotero_Browser.progress.show();
|
||||
|
||||
if(saveLocation) {
|
||||
saveLocation = Zotero.Collections.get(saveLocation);
|
||||
|
|
@ -602,7 +607,7 @@ Zotero_Browser.Tab.prototype._selectItems = function(obj, itemList) {
|
|||
"_blank","chrome,modal,centerscreen,resizable=yes", io);
|
||||
|
||||
if(!io.dataOut) { // user selected no items, so kill the progress indicatior
|
||||
Zotero_Browser.Progress.kill();
|
||||
Zotero_Browser.progress.kill();
|
||||
}
|
||||
|
||||
return io.dataOut;
|
||||
|
|
@ -621,143 +626,7 @@ Zotero_Browser.Tab.prototype._translatorsAvailable = function(translate, transla
|
|||
Zotero_Browser.updateStatus();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zotero_Browser.Progress
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Handles the display of a div showing progress in scraping
|
||||
Zotero_Browser.Progress = new function() {
|
||||
var _progressWindow;
|
||||
|
||||
var _windowLoaded = false;
|
||||
var _windowLoading = false;
|
||||
// keep track of all of these things in case they're called before we're
|
||||
// done loading the progress window
|
||||
var _loadDescription = null;
|
||||
var _loadLines = new Array();
|
||||
var _loadIcons = new Array();
|
||||
var _loadHeadline = Zotero.getString("ingester.scraping");
|
||||
|
||||
this.show = show;
|
||||
this.changeHeadline = changeHeadline;
|
||||
this.addLines = addLines;
|
||||
this.addDescription = addDescription;
|
||||
this.fade = fade;
|
||||
this.kill = kill;
|
||||
|
||||
function show() {
|
||||
if(_windowLoading || _windowLoaded) { // already loading or loaded
|
||||
return false;
|
||||
}
|
||||
_progressWindow = window.openDialog("chrome://zotero/chrome/ingester/progress.xul",
|
||||
"", "chrome,dialog=no,titlebar=no,popup=yes");
|
||||
_progressWindow.addEventListener("load", _onWindowLoaded, false);
|
||||
_windowLoading = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function changeHeadline(headline) {
|
||||
if(_windowLoaded) {
|
||||
_progressWindow.document.getElementById("zotero-progress-text-headline").value = headline;
|
||||
} else {
|
||||
_loadHeadline = headline;
|
||||
}
|
||||
}
|
||||
|
||||
function addLines(label, icon) {
|
||||
if(_windowLoaded) {
|
||||
for(i in label) {
|
||||
var newLabel = _progressWindow.document.createElement("label");
|
||||
newLabel.setAttribute("class", "zotero-progress-item-label");
|
||||
newLabel.setAttribute("crop", "end");
|
||||
newLabel.setAttribute("value", label[i]);
|
||||
|
||||
var newImage = _progressWindow.document.createElement("image");
|
||||
newImage.setAttribute("class", "zotero-progress-item-icon");
|
||||
newImage.setAttribute("src", icon[i]);
|
||||
|
||||
var newHB = _progressWindow.document.createElement("hbox");
|
||||
newHB.setAttribute("class", "zotero-progress-item-hbox");
|
||||
newHB.setAttribute("valign", "center");
|
||||
newHB.appendChild(newImage);
|
||||
newHB.appendChild(newLabel);
|
||||
|
||||
_progressWindow.document.getElementById("zotero-progress-text-box").appendChild(newHB);
|
||||
}
|
||||
|
||||
_move();
|
||||
} else {
|
||||
_loadLines = _loadLines.concat(label);
|
||||
_loadIcons = _loadIcons.concat(icon);
|
||||
}
|
||||
}
|
||||
|
||||
function addDescription(text) {
|
||||
if(_windowLoaded) {
|
||||
var newHB = _progressWindow.document.createElement("hbox");
|
||||
newHB.setAttribute("class", "zotero-progress-item-hbox");
|
||||
var newDescription = _progressWindow.document.createElement("description");
|
||||
newDescription.setAttribute("class", "zotero-progress-description");
|
||||
var newText = _progressWindow.document.createTextNode(text);
|
||||
|
||||
newDescription.appendChild(newText);
|
||||
newHB.appendChild(newDescription);
|
||||
_progressWindow.document.getElementById("zotero-progress-text-box").appendChild(newHB);
|
||||
|
||||
_move();
|
||||
} else {
|
||||
_loadDescription = text;
|
||||
}
|
||||
}
|
||||
|
||||
function fade() {
|
||||
if(_windowLoaded || _windowLoading) {
|
||||
setTimeout(_timeout, 2500);
|
||||
}
|
||||
}
|
||||
|
||||
function kill() {
|
||||
_windowLoaded = false;
|
||||
_windowLoading = false;
|
||||
try {
|
||||
_progressWindow.close();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
function _onWindowLoaded() {
|
||||
_windowLoading = false;
|
||||
_windowLoaded = true;
|
||||
|
||||
_move();
|
||||
// do things we delayed because the window was loading
|
||||
changeHeadline(_loadHeadline);
|
||||
addLines(_loadLines, _loadIcons);
|
||||
if(_loadDescription) {
|
||||
addDescription(_loadDescription);
|
||||
}
|
||||
|
||||
// reset parameters
|
||||
_loadDescription = null;
|
||||
_loadLines = new Array();
|
||||
_loadIcons = new Array();
|
||||
_loadHeadline = Zotero.getString("ingester.scraping")
|
||||
}
|
||||
|
||||
function _move() {
|
||||
_progressWindow.sizeToContent();
|
||||
_progressWindow.moveTo(
|
||||
window.screenX + window.innerWidth - _progressWindow.outerWidth - 30,
|
||||
window.screenY + window.innerHeight - _progressWindow.outerHeight - 10
|
||||
);
|
||||
}
|
||||
|
||||
function _timeout() {
|
||||
kill(); // could check to see if we're really supposed to fade yet
|
||||
// (in case multiple scrapers are operating at once)
|
||||
}
|
||||
}
|
||||
Zotero_Browser.progress = new Zotero.ProgressWindow();
|
||||
|
||||
Zotero_Browser.init();
|
||||
|
|
@ -962,7 +962,9 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
function getSelectedCollection(asID) {
|
||||
if (this.collectionsView.selection.count > 0 && this.collectionsView.selection.currentIndex != -1) {
|
||||
if (this.collectionsView.selection
|
||||
&& this.collectionsView.selection.count > 0
|
||||
&& this.collectionsView.selection.currentIndex != -1) {
|
||||
var collection = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex);
|
||||
if (collection && collection.isCollection()) {
|
||||
if (asID) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<overlay id="zotero"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<?xul-overlay href="itemPane.xul" ?>
|
||||
|
||||
|
||||
<!-- Include the global XPCOM object -->
|
||||
<script src="include.js"/>
|
||||
|
||||
|
|
@ -367,6 +367,8 @@
|
|||
}, false);
|
||||
|
||||
document.getElementById('appcontent').addEventListener('keydown', ZoteroPane.handleKeyDown, true);
|
||||
// Make sure open progress windows are fading
|
||||
document.getElementById('appcontent').addEventListener('mousemove', Zotero.ProgressWindowSet.updateTimers, false);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@
|
|||
|
||||
<window id="zotero-progress-window"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
windowtype="alert:alert"
|
||||
align="start">
|
||||
|
||||
windowtype="alert:alert">
|
||||
|
||||
<hbox id="zotero-progress-box">
|
||||
<vbox id="zotero-progress-text-box">
|
||||
<label id="zotero-progress-text-headline" style="font-weight: bold;" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
|
|||
|
|
@ -25,49 +25,79 @@ Zotero.ProgressWindowSet = new function() {
|
|||
this.add = add;
|
||||
this.tile = tile;
|
||||
this.remove = remove;
|
||||
this.updateTimers = updateTimers;
|
||||
|
||||
var _numWindows = 0;
|
||||
var _progressWindows = [];
|
||||
|
||||
const X_OFFSET = 30;
|
||||
const Y_OFFSET = 10;
|
||||
const X_OFFSET = 25;
|
||||
const Y_OFFSET = 35;
|
||||
const Y_SEPARATOR = 12;
|
||||
const X_WINDOWLESS_OFFSET = 50;
|
||||
const Y_WINDOWLESS_OFFSET = 100;
|
||||
|
||||
function add(progressWin) {
|
||||
_progressWindows.push(progressWin);
|
||||
_numWindows++;
|
||||
function add(progressWindow, instance) {
|
||||
_progressWindows.push({
|
||||
progressWindow: progressWindow,
|
||||
instance: instance
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function tile(progressWin) {
|
||||
var parent = progressWin.opener;
|
||||
var sum = 0;
|
||||
var y_sub = null;
|
||||
|
||||
for (var i=0; i<_progressWindows.length; i++) {
|
||||
var p = _progressWindows[i];
|
||||
var p = _progressWindows[i].progressWindow;
|
||||
|
||||
// Skip progress windows from other windows
|
||||
if (p.opener != parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sum += Y_OFFSET + p.outerHeight;
|
||||
if (!y_sub) {
|
||||
y_sub = Y_OFFSET + p.outerHeight;
|
||||
}
|
||||
|
||||
p.moveTo(
|
||||
parent.screenX + parent.innerWidth - p.outerWidth - X_OFFSET,
|
||||
parent.screenY + parent.innerHeight - sum
|
||||
);
|
||||
if (parent) {
|
||||
var right = parent.screenX + parent.outerWidth;
|
||||
var bottom = parent.screenY + parent.outerHeight;
|
||||
// On OS X outerHeight doesn't include 22px title bar and
|
||||
// moveTo() positions popups 22px below the specified location
|
||||
if (Zotero.isMac) {
|
||||
bottom += (22 * 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var right = progressWin.screen.width + X_OFFSET - X_WINDOWLESS_OFFSET;
|
||||
var bottom = progressWin.screen.height + Y_OFFSET - Y_WINDOWLESS_OFFSET;
|
||||
}
|
||||
|
||||
p.moveTo(right - p.outerWidth - X_OFFSET, bottom - y_sub);
|
||||
|
||||
y_sub += p.outerHeight + Y_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function remove(progressWin) {
|
||||
_numWindows--;
|
||||
for (var i=0; i<_progressWindows.length; i++) {
|
||||
if (_progressWindows[i] == progressWin) {
|
||||
if (_progressWindows[i].progressWindow == progressWin) {
|
||||
_progressWindows.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateTimers() {
|
||||
if (!_progressWindows.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i=0; i<_progressWindows.length; i++) {
|
||||
_progressWindows[i].instance.fade();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -77,23 +107,6 @@ Zotero.ProgressWindowSet = new function() {
|
|||
* Pass the active window into the constructor
|
||||
*/
|
||||
Zotero.ProgressWindow = function(_window){
|
||||
if (!_window){
|
||||
var _window =
|
||||
Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Components.interfaces.nsIWindowWatcher).
|
||||
activeWindow;
|
||||
}
|
||||
|
||||
var _progressWindow = null;
|
||||
var _windowLoaded = false;
|
||||
var _windowLoading = false;
|
||||
// keep track of all of these things in case they're called before we're
|
||||
// done loading the progress window
|
||||
var _loadDescription = null;
|
||||
var _loadLines = new Array();
|
||||
var _loadIcons = new Array();
|
||||
var _loadHeadline = '';
|
||||
|
||||
this.show = show;
|
||||
this.changeHeadline = changeHeadline;
|
||||
this.addLines = addLines;
|
||||
|
|
@ -101,18 +114,49 @@ Zotero.ProgressWindow = function(_window){
|
|||
this.fade = fade;
|
||||
this.kill = kill;
|
||||
|
||||
var _window = null;
|
||||
|
||||
var _progressWindow = null;
|
||||
var _windowLoaded = false;
|
||||
var _windowLoading = false;
|
||||
var _timeoutID = false;
|
||||
|
||||
// keep track of all of these things in case they're called before we're
|
||||
// done loading the progress window
|
||||
var _loadHeadline = '';
|
||||
var _loadLines = [];
|
||||
var _loadIcons = [];
|
||||
var _loadDescription = null;
|
||||
|
||||
|
||||
function show() {
|
||||
if(_windowLoading || _windowLoaded) { // already loading or loaded
|
||||
return false;
|
||||
}
|
||||
|
||||
_progressWindow = _window.openDialog("chrome://zotero/chrome/progressWindow.xul",
|
||||
"", "chrome,dialog=no,titlebar=no,popup=yes");
|
||||
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Components.interfaces.nsIWindowWatcher);
|
||||
|
||||
if (!_window){
|
||||
_window = ww.activeWindow;
|
||||
}
|
||||
|
||||
if (_window) {
|
||||
_progressWindow = _window.openDialog("chrome://zotero/chrome/progressWindow.xul",
|
||||
"", "chrome,dialog=no,titlebar=no,popup=yes");
|
||||
}
|
||||
else {
|
||||
_progressWindow = ww.openWindow(null, "chrome://zotero/chrome/progressWindow.xul",
|
||||
"", "chrome,dialog=no,titlebar=no,popup=yes", null);
|
||||
}
|
||||
_progressWindow.addEventListener("pageshow", _onWindowLoaded, false);
|
||||
_progressWindow.addEventListener("mouseover", _onMouseOver, false);
|
||||
_progressWindow.addEventListener("mouseout", _onMouseOut, false);
|
||||
_progressWindow.addEventListener("mouseup", _onMouseUp, false);
|
||||
|
||||
_windowLoading = true;
|
||||
|
||||
Zotero.ProgressWindowSet.add(_progressWindow);
|
||||
Zotero.ProgressWindowSet.add(_progressWindow, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -127,7 +171,7 @@ Zotero.ProgressWindow = function(_window){
|
|||
|
||||
function addLines(label, icon) {
|
||||
if(_windowLoaded) {
|
||||
for(i in label) {
|
||||
for (var i in label) {
|
||||
var newLabel = _progressWindow.document.createElement("label");
|
||||
newLabel.setAttribute("class", "zotero-progress-item-label");
|
||||
newLabel.setAttribute("crop", "end");
|
||||
|
|
@ -153,15 +197,42 @@ Zotero.ProgressWindow = function(_window){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add a description to the progress window
|
||||
*
|
||||
* <a> elements are turned into XUL links
|
||||
*/
|
||||
function addDescription(text) {
|
||||
if(_windowLoaded) {
|
||||
var newHB = _progressWindow.document.createElement("hbox");
|
||||
newHB.setAttribute("class", "zotero-progress-item-hbox");
|
||||
var newDescription = _progressWindow.document.createElement("description");
|
||||
newDescription.setAttribute("class", "zotero-progress-description");
|
||||
var newText = _progressWindow.document.createTextNode(text);
|
||||
|
||||
newDescription.appendChild(newText);
|
||||
var utils = new Zotero.Utilities();
|
||||
var parts = utils.parseMarkup(text);
|
||||
for each(var part in parts) {
|
||||
if (part.type == 'text') {
|
||||
var elem = _progressWindow.document.createTextNode(part.text);
|
||||
}
|
||||
else if (part.type == 'link') {
|
||||
var elem = _progressWindow.document.createElement('label');
|
||||
elem.setAttribute('value', part.text);
|
||||
elem.setAttribute('class', 'text-link');
|
||||
for (var i in part.attributes) {
|
||||
elem.setAttribute(i, part.attributes[i]);
|
||||
|
||||
if (i == 'href') {
|
||||
// DEBUG: As of Fx2, 'mouseup' seems to be the only
|
||||
// way to detect a click in a popup window
|
||||
elem.addEventListener('mouseup', _handleLinkClick, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDescription.appendChild(elem);
|
||||
}
|
||||
|
||||
newHB.appendChild(newDescription);
|
||||
_progressWindow.document.getElementById("zotero-progress-text-box").appendChild(newHB);
|
||||
|
||||
|
|
@ -171,13 +242,19 @@ Zotero.ProgressWindow = function(_window){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function fade() {
|
||||
if(_windowLoaded || _windowLoading) {
|
||||
_window.setTimeout(_timeout, 2500);
|
||||
if (_windowLoaded || _windowLoading) {
|
||||
if (_timeoutID) {
|
||||
return;
|
||||
}
|
||||
|
||||
_timeoutID = _progressWindow.setTimeout(_timeout, 2500);
|
||||
}
|
||||
}
|
||||
|
||||
function kill() {
|
||||
_disableTimeout();
|
||||
_windowLoaded = false;
|
||||
_windowLoading = false;
|
||||
Zotero.ProgressWindowSet.remove(_progressWindow);
|
||||
|
|
@ -194,15 +271,15 @@ Zotero.ProgressWindow = function(_window){
|
|||
// do things we delayed because the window was loading
|
||||
changeHeadline(_loadHeadline);
|
||||
addLines(_loadLines, _loadIcons);
|
||||
if(_loadDescription) {
|
||||
if (_loadDescription) {
|
||||
addDescription(_loadDescription);
|
||||
}
|
||||
|
||||
// reset parameters
|
||||
_loadDescription = null;
|
||||
_loadLines = new Array();
|
||||
_loadIcons = new Array();
|
||||
_loadHeadline = '';
|
||||
_loadLines = [];
|
||||
_loadIcons = [];
|
||||
_loadDescription = null;
|
||||
}
|
||||
|
||||
function _move() {
|
||||
|
|
@ -213,5 +290,54 @@ Zotero.ProgressWindow = function(_window){
|
|||
function _timeout() {
|
||||
kill(); // could check to see if we're really supposed to fade yet
|
||||
// (in case multiple scrapers are operating at once)
|
||||
_timeoutID = false;
|
||||
}
|
||||
|
||||
function _disableTimeout() {
|
||||
_progressWindow.clearTimeout(_timeoutID);
|
||||
_timeoutID = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disable the fade timer when the mouse is over the window
|
||||
*/
|
||||
function _onMouseOver(e) {
|
||||
_disableTimeout();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Start the fade timer when the mouse leaves the window
|
||||
*
|
||||
* Note that this onmouseout doesn't work correctly on popups in Fx2,
|
||||
* so 1) we have to calculate the window borders manually to avoid fading
|
||||
* when the mouse is still over the box, and 2) this only does anything
|
||||
* when the mouse is moved off of the browser window -- otherwise the fade
|
||||
* is triggered by onmousemove on appcontent in overlay.xul.
|
||||
*/
|
||||
function _onMouseOut(e) {
|
||||
// |this| refers to progressWindow's XUL window
|
||||
var top = this.screenY + (Zotero.isMac ? 22 : 0);
|
||||
if ((e.screenX >= this.screenX && e.screenX <= (this.screenX + this.outerWidth))
|
||||
&& (e.screenY >= top) && e.screenY <= (top + this.outerHeight)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fade();
|
||||
}
|
||||
|
||||
|
||||
function _onMouseUp(e) {
|
||||
kill();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Open URL specified in target's href attribute in a new window
|
||||
*/
|
||||
function _handleLinkClick(event) {
|
||||
_progressWindow.open(event.target.getAttribute('href'), 'zotero-loaded-page',
|
||||
'menubar=yes,location=yes,toolbar=yes,personalbar=yes,resizable=yes,scrollbars=yes,status=yes');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,6 +152,54 @@ Zotero.Utilities.prototype.htmlSpecialChars = function(str) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parses a text string for HTML/XUL markup and returns an array of parts
|
||||
*
|
||||
* Currently only finds HTML links (<a> tags)
|
||||
*
|
||||
* Returns an array of objects with the following form:
|
||||
* {
|
||||
* type: 'text'|'link',
|
||||
* text: "text content",
|
||||
* [ attributes: { key1: val [ , key2: val, ...] }
|
||||
* }
|
||||
*/
|
||||
Zotero.Utilities.prototype.parseMarkup = function(str) {
|
||||
var parts = [];
|
||||
var splits = str.split(/(<a [^>]+>[^<]*<\/a>)/);
|
||||
|
||||
for each(var split in splits) {
|
||||
// Link
|
||||
if (split.indexOf('<a ') == 0) {
|
||||
var matches = split.match(/<a ([^>]+)>([^<]*)<\/a>/);
|
||||
if (matches) {
|
||||
// Attribute pairs
|
||||
var attributes = {};
|
||||
var pairs = matches[1].match(/([^ =]+)="([^"]+")/g);
|
||||
for each (var pair in pairs) {
|
||||
var [key, val] = pair.split(/=/);
|
||||
attributes[key] = val.substr(1, val.length - 2);
|
||||
}
|
||||
|
||||
parts.push({
|
||||
type: 'link',
|
||||
text: matches[2],
|
||||
attributes: attributes
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
parts.push({
|
||||
type: 'text',
|
||||
text: split
|
||||
});
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test if a string is an integer
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue