diff --git a/chrome/content/zotero/browser.js b/chrome/content/zotero/browser.js
index c42b14af74..e14243162e 100644
--- a/chrome/content/zotero/browser.js
+++ b/chrome/content/zotero/browser.js
@@ -394,9 +394,8 @@ var Zotero_Browser = new function() {
var linkText = ''
+ Zotero.getString('ingester.scrapeErrorDescription.linkText') + '';
Zotero_Browser.progress.addDescription(Zotero.getString("ingester.scrapeErrorDescription", linkText));
+ Zotero_Browser.progress.startCloseTimer();
}
-
- Zotero_Browser.progress.fade();
}
@@ -413,6 +412,8 @@ var Zotero_Browser = new function() {
if(collection) {
collection.addItem(item.getID());
}
+
+ Zotero_Browser.progress.startCloseTimer();
}
//////////////////////////////////////////////////////////////////////////////
@@ -622,8 +623,8 @@ Zotero_Browser.Tab.prototype._selectItems = function(obj, itemList) {
var newDialog = window.openDialog("chrome://zotero/content/ingester/selectitems.xul",
"_blank","chrome,modal,centerscreen,resizable=yes", io);
- if(!io.dataOut) { // user selected no items, so kill the progress indicatior
- Zotero_Browser.progress.kill();
+ if(!io.dataOut) { // user selected no items, so close the progress indicatior
+ Zotero_Browser.progress.close();
}
return io.dataOut;
diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js
index d7b6c74419..8a76eabcaa 100644
--- a/chrome/content/zotero/overlay.js
+++ b/chrome/content/zotero/overlay.js
@@ -1504,6 +1504,13 @@ var ZoteroPane = new function()
function addItemFromPage() {
+ var progressWin = new Zotero.ProgressWindow();
+ progressWin.changeHeadline(Zotero.getString('ingester.scraping'));
+ var icon = 'chrome://zotero/skin/treeitem-webpage.png';
+ progressWin.addLines(window.content.document.title, icon)
+ progressWin.show();
+ progressWin.startCloseTimer();
+
var data = {
title: window.content.document.title,
url: window.content.document.location.href,
@@ -1515,27 +1522,55 @@ var ZoteroPane = new function()
// Automatically save snapshot if pref set
if (item.getID() && Zotero.Prefs.get('automaticSnapshots'))
{
- this.addAttachmentFromPage(false, item.getID(), true);
+ var f = function() {
+ // We set |noParent|, since child items don't belong to collections
+ ZoteroPane.addAttachmentFromPage(false, item.getID(), true);
+ }
+ // Give progress window time to appear
+ setTimeout(f, 300);
}
return item.getID();
}
- function addAttachmentFromPage(link, id, noParent)
+ /*
+ * Create an attachment from the current page
+ *
+ * |link| -- create web link instead of snapshot
+ * |itemID| -- itemID of parent item
+ * |noParent| -- don't add to current collection
+ */
+ function addAttachmentFromPage(link, itemID, noParent)
{
- if (this.itemsView && this.itemsView._itemGroup.isCollection() && !noParent) {
- var parentCollectionID = this.itemsView._itemGroup.ref.getID();
+ if (!noParent) {
+ var progressWin = new Zotero.ProgressWindow();
+ progressWin.changeHeadline(Zotero.getString('save.' + (link ? 'link' : 'attachment')));
+ var type = link ? 'web-link' : 'snapshot';
+ var icon = 'chrome://zotero/skin/treeitem-attachment-' + type + '.png';
+ progressWin.addLines(window.content.document.title, icon)
+ progressWin.show();
+ progressWin.startCloseTimer();
+
+ Zotero.debug('here');
+ if (this.itemsView && this.itemsView._itemGroup.isCollection()) {
+ Zotero.debug('here2');
+ var parentCollectionID = this.itemsView._itemGroup.ref.getID();
+ Zotero.debug(parentCollectionID);
+ }
}
- if(link)
- {
- Zotero.Attachments.linkFromDocument(window.content.document, id, parentCollectionID);
- }
- else
- {
- Zotero.Attachments.importFromDocument(window.content.document, id, false, parentCollectionID);
+ var f = function() {
+ Zotero.debug(parentCollectionID);
+ if (link) {
+ Zotero.Attachments.linkFromDocument(window.content.document, itemID, false, parentCollectionID);
+ }
+ else {
+ Zotero.Attachments.importFromDocument(window.content.document, itemID, false, false, parentCollectionID);
+ }
}
+ // Give progress window time to appear
+ setTimeout(f, 100);
}
diff --git a/chrome/content/zotero/overlay.xul b/chrome/content/zotero/overlay.xul
index 5f4a88fa96..bae40857a9 100644
--- a/chrome/content/zotero/overlay.xul
+++ b/chrome/content/zotero/overlay.xul
@@ -55,10 +55,10 @@
oncommand="var itemID = ZoteroPane.addItemFromPage(); ZoteroPane.newNote(false, itemID, window.content.getSelection().toString())"/>
+ oncommand="Zotero.Attachments.importFromURL(window.gContextMenu.linkURL, false, false, false, ZoteroPane.getSelectedCollection(true))"/>
+ oncommand="Zotero.Attachments.importFromURL(window.gContextMenu.onImage ? window.gContextMenu.imageURL : window.gContextMenu.bgImageURL, false, false, false, ZoteroPane.getSelectedCollection(true))"/>
diff --git a/chrome/content/zotero/preferences.xul b/chrome/content/zotero/preferences.xul
index 554cb4b318..0b205abcdb 100644
--- a/chrome/content/zotero/preferences.xul
+++ b/chrome/content/zotero/preferences.xul
@@ -108,6 +108,8 @@ To add a new preference:
+
+
diff --git a/chrome/content/zotero/webpagedump/common.js b/chrome/content/zotero/webpagedump/common.js
new file mode 100644
index 0000000000..2b04f615a1
--- /dev/null
+++ b/chrome/content/zotero/webpagedump/common.js
@@ -0,0 +1,790 @@
+/* ***** 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 ScrapBook.
+ *
+ * The Initial Developer of the Original Code is Gomita.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bernhard Pollak (WebPageDump Fork)
+ *
+ * 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 ***** */
+
+// --------------------------------------------------------------------------------
+// "WebPageDump" Firefox Extension
+// --------------------------------------------------------------------------------
+// - File: "common.js" -
+// - Description:
+// provides common functions (file, preferences, windows, error,...)
+//
+// --------------------------------------------------------------------------------
+
+
+var gBrowserWindow = null;
+var gExceptLocation = "about:blank";
+var gCallback = "";
+var gTimeOutID = 0;
+var gTimedOut = false;
+var gWaitForPaint = false;
+
+var MODE_SIMULATE = false;
+var WPD_DEFAULTWIDTH=1024;
+var WPD_DEFAULTHEIGHT=768;
+
+var WPD_MAXUIERRORCOUNT=8;
+
+
+/*function wpdGetTopBrowserWindow()
+{
+ var winMed = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var winList = winMed.getZOrderDOMWindowEnumerator("navigator:browser", true);
+ if (!winList.hasMoreElements())
+ return top.getBrowser().contentWindow; // fallback
+
+ return winList.getNext().getBrowser().contentWindow;
+}*/
+
+
+
+/* [14:55:15] paolinho: var browserWin = windowMediator.getMostRecentWindow("navigator:browser");
+ const mainTabBox = browserWin.getBrowser().mTabBox;
+ const topWindow = browserWin.getBrowser().browsers[mainTabBox.selectedIndex].contentWindow;
+[14:55:50] … var windowMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
+*/
+
+function wpdGetTopBrowserWindow()
+{
+ var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
+ var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator);
+ var topWindowOfType = windowManagerInterface.getMostRecentWindow( "navigator:browser" );
+
+ if (topWindowOfType) {
+ return topWindowOfType;
+ }
+ return null;
+}
+
+
+function wpdWindowLoaded()
+{
+ try {
+ // this will be called multiple times if the page contains more than one document (frames, flash,...)
+ //var browser=this.document.getElementById("content");
+ dump("[wpdWindowLoaded] ... \n");
+ var browser = this.top.getBrowser();
+ // each time we have to check if the page is fully loaded...
+ if (!(browser.webProgress.isLoadingDocument || browser.contentDocument.location == gExceptLocation)) {
+ dump("[wpdWindowLoaded] window finally loaded\n");
+ gBrowserWindow.clearTimeout(gTimeOutID);
+ gBrowserWindow.removeEventListener("load",wpdWindowLoaded,true);
+ //dump("[wpdWindowLoaded] calling "+gCallback+"\n");
+ if (gWaitForPaint) {
+ wpdCommon.sizeWindow(WPD_DEFAULTWIDTH-1,WPD_DEFAULTHEIGHT); // this is for the strange empty lines bug
+ wpdCommon.sizeWindow(WPD_DEFAULTWIDTH,WPD_DEFAULTHEIGHT);
+ }
+ var w=0;
+ if (gWaitForPaint) w=5000; // wait for painting
+ gBrowserWindow.setTimeout(gCallback, w);
+ }
+ } catch (ex) {
+ dump("[wpdWindowLoaded] EXCEPTION: "+ex+"\n");
+ }
+}
+
+function wpdTimeOut()
+{
+ dump("[wpdTimeOut] timeout triggered!\n");
+ gTimedOut=true;
+ gBrowserWindow.clearTimeout(gTimeOutID);
+ gBrowserWindow.removeEventListener("load",wpdWindowLoaded,true);
+ gBrowserWindow.setTimeout(gCallback, 0);
+}
+
+function wpdIsTimedOut()
+{
+ return gTimedOut;
+}
+
+function wpdLoadURL(aURI,aCallback)
+{
+ try {
+ gTimedOut=false;
+ dump("\n[wpdLoadURL] aURI: "+aURI+"\n");
+ if (aURI=="") return;
+ gBrowserWindow = wpdGetTopBrowserWindow();
+ gBrowserWindow.loadURI(aURI);
+ gCallback = aCallback;
+ // 30 seconds maximum for loading the page
+ gTimeOutID=gBrowserWindow.setTimeout(wpdTimeOut, 60000);
+ gBrowserWindow.addEventListener("load",wpdWindowLoaded, true);
+ } catch (ex) {
+ dump("[wpdLoadURL] EXCEPTION: "+ex+"\n");
+ }
+}
+
+var wpdCommon = {
+
+ errList : "",
+ errCount : 0,
+ downloading : false,
+ downloaded : false,
+
+ allowed_entities:
+ ""&'<> ¡¢£¤¥¦"+
+ "§¨©ª«¬®¯°±"+
+ "²³´µ¶·¸¹º»"+
+ "¼½¾¿ÀÁÂÃÄ"+
+ "ÅÆÇÈÉÊËÌÍ"+
+ "ÎÏÐÑÒÓÔÕÖ"+
+ "רÙÚÛÜÝÞß"+
+ "àáâãäåæçè"+
+ "éêëìíîïðñò"+
+ "óôõö÷øùúûü"+
+ "ýþÿŒœŠšŸƒˆ"+
+ "˜ΑΒΓΔΕΖΗΘΙΚ"+
+ "ΛΜΝΞΟΠΡΣΤΥΦΧΨ"+
+ "Ωαβγδεζηθικ"+
+ "λμνξοπρςστυφ"+
+ "χψωϑϒφϖ "+
+ "–—‘’‚“”„"+
+ "†‡•…‰′″‹›"+
+ "‾⁄€ℑ℘ℜ™ℵ←↑"+
+ "→↓↔↵⇐⇑⇒⇓⇔∀"+
+ "∂∃∅∇∈∉∋∏∑−∗√"+
+ "∝∞∠∨∩∪∫∴∼≅≈≠≡"+
+ "≤≥⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈"+
+ "⌉⌊⌋〈〉◊♠♣♥♦",
+
+
+
+ trim : function (aString) {
+ try {
+ return (aString.replace(/\s+$/,"").replace(/^\s+/,""));
+ } catch(ex) {
+ return aString;
+ }
+ },
+
+
+ // checks the CRLFs at the beginning - if there are CRLFs present
+ // one additional CRLF will be added at the beginning
+ checkCRLF : function (aNode)
+ {
+ try {
+ var before=false;
+ var after=false;
+ if (aNode.parentNode.firstChild==aNode) before=true;
+ if (!before && !after) {
+ throw new Error("return");
+ }
+ // why
? Because the
Tag ist not present in text DOM nodes...
+ var aString=aNode.nodeValue;
+ if (aString.search(/\n/)==-1) throw new Error("return");
+ aString=(aString.replace(/\r\n/g,"
").replace(/\n/g,"
"));
+ var a=aString.split("
");
+ var s=0;
+ var e=0;
+
+
+ if (before) {
+ for (var i=0;i0) aString="\r\n"+aString;
+ return aString;
+
+ } catch (ex) {
+ return aNode.nodeValue;
+ }
+ },
+
+ unicodeToEntity : function (text,charset)
+ {
+
+ function convertEntity(letter) {
+ try {
+ var l = gEntityConverter.ConvertToEntity(letter,entityVersion);
+ // is the entity allowed?
+ if (entities.indexOf(l)>=0) {
+ return l;
+ } else if ( (l!=letter) ) {
+ return ""+letter.charCodeAt(0)+";";
+ }
+ } catch (ex) {
+ }
+ // now we check if the letter is valid inside the destination charset
+ // (if the result is a ? it is not valid - except letter=?)
+ try {
+ var s=gUnicodeConverter.ConvertFromUnicode(letter);
+ if ( (charset!="UTF-8") && (s=="?") ) {
+ return ""+letter.charCodeAt(0)+";";
+ }
+ } catch (ex) {
+ }
+ return letter;
+ }
+
+ if (!gUnicodeConverter) {
+ try {
+ var gUnicodeConverter = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].getService(Components.interfaces.nsIScriptableUnicodeConverter);
+ gUnicodeConverter.charset = charset;
+ } catch(ex) {
+ dump ("gUnicodeConverter EXCEPTION:"+ex+"\n");
+ }
+ }
+
+ if (!gEntityConverter) {
+ try {
+ var gEntityConverter = Components.classes["@mozilla.org/intl/entityconverter;1"].createInstance(Components.interfaces.nsIEntityConverter);
+ } catch(e) {
+ dump ("gEntityConverter EXCEPTION:"+ex+"\n");
+ }
+ }
+
+ // Firefox - Source Code Snippet:
+ // const unsigned long entityNone = 0;
+ // const unsigned long html40Latin1 = 1;
+ // const unsigned long html40Symbols = 2;
+ // const unsigned long html40Special = 4; // excludes ", &, <, >
+ // const unsigned long transliterate = 8;
+ // const unsigned long mathml20 = 16;
+ // const unsigned long html32 = html40Latin1;
+ // const unsigned long html40 = html40Latin1+html40Symbols+html40Special;
+ // const unsigned long entityW3C = html40+mathml20;
+ const entityVersion = Components.interfaces.nsIEntityConverter.html40;
+ // convert to entities (
+ // replace other chars > 0x7f via nsIEntityConverter/convertEntity
+ var entities = this.allowed_entities;
+ text = text.replace(/[^\0-\u007f]/g, convertEntity);
+ return text;
+ },
+
+
+ playSound : function()
+ {
+ try {
+ var sound = Components.classes["@mozilla.org/sound;1"].createInstance(Components.interfaces.nsISound);
+ sound.playSystemSound("ringin.wav");
+ } catch(ex) {
+ }
+ },
+
+ // return the current focused window
+ getFocusedWindow : function()
+ {
+ var win = document.commandDispatcher.focusedWindow;
+ if ( !win || win == window || win instanceof Components.interfaces.nsIDOMChromeWindow ) win = window._content;
+ return win;
+ },
+
+ sizeWindow : function(w,h)
+ {
+ try {
+ var window=this.getFocusedWindow();
+ window.moveTo(0,0);
+ if ((w==0) || (w>screen.availWidth)) w=screen.availWidth;
+ if ((h==0) || (w>screen.availHeight)) h=screen.availHeight;
+ window.resizeTo(w,h);
+ window.focus();
+ } catch(ex) {
+ }
+ },
+
+ // add a line to the error list (displays a maximum of 15 errors)
+ addError : function(aError)
+ {
+ dump('ERROR: '+aError+"\n");
+ if (this.errCount-1) return; // is the same
+ this.errList = this.errList+aError+"\n";
+ } else if (this.errCount==WPD_MAXUIERRORCOUNT) {
+ this.errList = this.errList+'...';
+ }
+ this.errCount++;
+ },
+
+ saveWebPage : function(aDestFile) {
+ dump("[saveWebPage] "+aDestFile+"\n");
+ var nsIWBP = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Components.interfaces.nsIWebBrowserPersist);
+ var doc = window.content.document;
+ var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ file.initWithPath(aDestFile);
+ var dataPath = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ dataPath.initWithPath(this.getFilePath(aDestFile));
+ nsIWBP.saveDocument(doc, file, dataPath, null, 0, 0);
+ },
+
+ // returns num as string of length i filled up with 0s
+ addLeftZeros : function(num,i)
+ {
+ var s=""+num;
+ var r="";
+ for (var f=0;f]+/g, ")");
+ aFileName = aFileName.replace(/[\s]+/g, "_");
+ aFileName = aFileName.replace(/[%]+/g, "@");
+ return aFileName;
+ },
+
+ getURL : function()
+ {
+ return top.window._content.document.location.href;
+ },
+
+ // remove get variables from an URL
+ removeGETFromURL : function(aURL)
+ {
+ var pos;
+ aURL = ( (pos = aURL.indexOf("?")) != -1 ) ? aURL.substring(0, pos) : aURL;
+ aURL = ( (pos = aURL.indexOf("#")) != -1 ) ? aURL.substring(0, pos) : aURL;
+ return aURL;
+ },
+
+ // extract filename from URL
+ getFileName : function(aURL)
+ {
+ var pos;
+ aURL = this.removeGETFromURL(aURL);
+ aURL = ( (pos = aURL.lastIndexOf("/")) != -1 ) ? aURL.substring(++pos) : aURL;
+ return aURL;
+ },
+
+ filePathToURI: function(filePath)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].getService(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(filePath);
+ var obj_FPH = Components.classes["@mozilla.org/network/protocol;1?name=file"].getService(Components.interfaces.nsIFileProtocolHandler);
+ return obj_FPH.getURLSpecFromFile(obj_File);
+ },
+
+ URLToFilePath: function(aURL)
+ {
+ var obj_FPH = Components.classes["@mozilla.org/network/protocol;1?name=file"].getService(Components.interfaces.nsIFileProtocolHandler);
+ try {
+ return obj_FPH.getFileFromURLSpec(aURL).path;
+ } catch(ex) {
+ return aURL;
+ }
+ },
+
+ // right part of filepath/filename
+ getFileLeafName: function(filePath)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].getService(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(filePath);
+ return obj_File.leafName;
+ },
+
+ getFilePath: function(filePath)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].getService(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(filePath);
+ var pos; // Added by Dan S. for Zotero
+ return ( (pos = filePath.lastIndexOf(obj_File.leafName)) != -1 ) ? filePath.substring(0,pos) : filePath;
+ },
+
+ appendFilePath: function(filePath,appendPath)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].getService(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(filePath);
+ obj_File.appendRelativePath(appendPath);
+ return obj_File.path;
+ },
+
+ pathExists: function(filePath)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].getService(Components.interfaces.nsILocalFile);
+ try {
+ obj_File.initWithPath(filePath);
+ return obj_File.exists();
+ } catch(ex) {
+ return false;
+ }
+ },
+
+ // add the HTML Tag Stuff to aNode and embedd the aNode.innerHTML between the tags
+ nodeToHTMLString: function(aNode)
+ {
+ if (aNode==null) return "";
+ var tag = "<" + aNode.nodeName.toLowerCase();
+ for ( var i=0; i\n";
+ return tag + aNode.innerHTML + "" + aNode.nodeName.toLowerCase() + ">\n";
+ },
+
+ ConvertFromUnicode16 : function(aString,charset)
+ {
+ if ( !aString ) return "";
+ try {
+ var UNICODE = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].getService(Components.interfaces.nsIScriptableUnicodeConverter);
+ UNICODE.charset = charset;
+ aString = UNICODE.ConvertFromUnicode(aString);
+ aString = aString + UNICODE.Finish();
+ } catch(ex) {
+ //this.addError("[wpdCommon.convertStringToCharset]:\n -> charset: "+charset+"\n -> "+ex);
+ }
+ return aString;
+ },
+
+ ConvertToUnicode16 : function(aString,charset)
+ {
+ if ( !aString ) return "";
+ try {
+ var UNICODE = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].getService(Components.interfaces.nsIScriptableUnicodeConverter);
+ UNICODE.charset = charset;
+ aString = UNICODE.ConvertToUnicode(aString);
+ } catch(ex) {
+ //this.addError("[wpdCommon.convertStringToCharset]:\n -> charset: "+charset+"\n -> "+ex);
+ }
+ return aString;
+ },
+
+ // convert the doctype to an HTML doctype String
+ doctypeToHTMLString : function(aDoctype)
+ {
+ if ( !aDoctype ) return "";
+ var ret = "\n";
+ return ret;
+ },
+
+ addCommentTag : function(targetNode, aComment)
+ {
+ targetNode.appendChild(document.createTextNode("\n"));
+ targetNode.appendChild(document.createComment(aComment));
+ targetNode.appendChild(document.createTextNode("\n"));
+ },
+
+
+ removeNodeFromParent : function(aNode)
+ {
+ var newNode = document.createTextNode("");
+ aNode.parentNode.replaceChild(newNode, aNode);
+ aNode = newNode;
+ return aNode;
+ },
+
+ // convert URL String to Object
+ // for easier URL handling
+ convertURLToObject : function(aURLString)
+ {
+ var aURL = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURL);
+ aURL.spec = aURLString;
+ return aURL;
+ },
+
+ // resolves the relative URL (aRelURL) with the base URL (aBaseURL)
+ resolveURL : function(aBaseURL, aRelURL)
+ {
+ try {
+ var aBaseURLObj = this.convertURLToObject(aBaseURL);
+ return aBaseURLObj.resolve(aRelURL);
+ } catch(ex) {
+ this.addError("[wpdCommon.resolveURL]:\n -> aBaseURL: "+aBaseURL+"\n -> aRelURL: "+aRelURL+"\n -> "+ex);
+ }
+ return "";
+ },
+
+ getHostName : function(aURL)
+ {
+ try {
+ var aURLObj = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURI);
+ aURLObj.spec = aURL
+ return aURLObj.asciiHost;
+ } catch(ex) {
+ this.addError("[wpdCommon.getHostName]:\n -> aURL: "+aURL+"\n -> "+ex);
+ }
+ return "";
+ },
+
+ convertUrlToASCII : function(aURL)
+ {
+ try {
+ var aURLObj = Components.classes['@mozilla.org/network/standard-url;1'].createInstance(Components.interfaces.nsIURI);
+ aURLObj.spec = aURL
+ return aURLObj.asciiSpec;
+ } catch(ex) {
+ this.addError("[wpdCommon.getHostName]:\n -> aURL: "+aURL+"\n -> "+ex);
+ }
+ return "";
+ },
+
+ createDir : function(str_Dir)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(str_Dir);
+ if (!obj_File.exists())
+ obj_File.create(obj_File.DIRECTORY_TYPE, 0700);
+ },
+
+ readDir : function(str_Dir)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(str_Dir);
+ if (obj_File.exists()) return obj_File.directoryEntries;
+ return [];
+ },
+
+ fileSize : function(str_Filename)
+ {
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(str_Filename);
+ return obj_File.fileSize;
+ },
+
+ // read the file (str_Filename) to a String Buffer (str_Buffer)
+ readFile : function(str_Filename,removeComments,text)
+ {
+ try{
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(str_Filename);
+ if (!obj_File.exists()) {
+ this.addError("[wpdCommon.readFile]:\n -> str_Filename: "+str_Filename+"\n -> file not found!");
+ return "";
+ }
+
+ var obj_Transport = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
+
+ obj_Transport.init( obj_File, 0x01 , 004, 0 );
+
+ var sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance( Components.interfaces.nsIScriptableInputStream );
+ sis.init( obj_Transport );
+ var output = sis.read( sis.available() );
+ if (text) output = output.replace(/\r/g,"");
+ if (text && removeComments) {
+ output = output.replace(/^\/\/.*/g,"");
+ output = output.replace(/\n\/\/.*/g,"");
+ output = output.replace(/\n\n+/g,"\n");
+ }
+ if (text) output = output.split(/\n/g);
+ return output;
+ } catch (ex) {
+ this.addError("[wpdCommon.readFile]:\n -> str_Filename: "+str_Filename+"\n -> "+ex);
+ }
+ return "";
+ },
+
+ // write the String Buffer (str_Buffer) to a file (str_Filename)
+ writeFile : function(str_Buffer,str_Filename)
+ {
+ if (MODE_SIMULATE) return true;
+ try{
+ var obj_File = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ obj_File.initWithPath(str_Filename);
+ if (!obj_File.exists())
+ obj_File.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666 );
+
+ var obj_Transport = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+
+ /* Open flags
+ #define PR_RDONLY 0x01 - Open for reading only.
+ #define PR_WRONLY 0x02 - Open for writing only.
+ #define PR_RDWR 0x04 - Open for reading and writing.
+ #define PR_CREATE_FILE 0x08 - If the file does not exist, the file is created. If the file exists, this flag has no effect.
+ #define PR_APPEND 0x10 - The file pointer is set to the end of the file prior to each write.
+ #define PR_TRUNCATE 0x20 - If the file exists, its length is truncated to 0.
+ #define PR_SYNC 0x40 - If set, each write will wait for both the file data and file status to be physically updated.
+ #define PR_EXCL 0x80 - With PR_CREATE_FILE, if the file does not exist, the file is created. If the file already exists, no action and NULL is returned.
+
+ File modes
+ 'mode' is currently only applicable on UNIX platforms.
+ The 'mode' argument may be ignored by PR_Open on other platforms.
+ 00400 Read by owner.
+ 00200 Write by owner.
+ 00100 Execute (search if a directory) by owner.
+ 00040 Read by group.
+ 00020 Write by group.
+ 00010 Execute by group.
+ 00004 Read by others.
+ 00002 Write by others
+ 00001 Execute by others.
+ */
+ obj_Transport.init( obj_File, 0x20 | 0x04 | 0x08, 064, 0 );
+ obj_Transport.write(str_Buffer,str_Buffer.length);
+ obj_Transport.flush();
+ obj_Transport.close();
+ return true;
+ } catch (ex) {
+ this.addError("[wpdCommon.writeFile]:\n -> str_Filename: "+str_Filename+"\n -> "+ex);
+ }
+ return false;
+ },
+
+
+ copyFile : function(sourcefile,destfile)
+ {
+
+ var destdir=this.getFilePath(destfile);
+ destfile=this.getFileLeafName(destfile);
+ var aFile = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ if (!aFile) return false;
+
+ var aDir = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ if (!aDir) return false;
+
+ aFile.initWithPath(sourcefile);
+
+ aDir.initWithPath(destdir);
+
+ aFile.copyTo(aDir,destfile);
+ return true; // Added by Dan S. for Zotero
+ },
+
+ // download aSourceURL to aTargetFilename
+ // (works also on local files...)
+ downloadFile : function (aSourceURL,aTargetFilename)
+ {
+ if (MODE_SIMULATE) return true;
+ try {
+ //new obj_URI object
+ var obj_URI = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI(aSourceURL, null, null);
+
+ //new file object
+ var obj_TargetFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ //set file with path
+ // NOTE: This function has a known bug on the macintosh and other OSes
+ // which do not represent file locations as paths. If you do use this
+ // function, be very aware of this problem!
+ obj_TargetFile.initWithPath(aTargetFilename);
+
+ //new persistence object
+ var obj_Persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Components.interfaces.nsIWebBrowserPersist);
+
+ // set flags
+ const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
+ var flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
+ nsIWBP.PERSIST_FLAGS_FROM_CACHE;
+ //nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
+ obj_Persist.persistFlags = flags;
+
+ // has the url the same filetype like the file extension?
+ //save file to target
+ obj_Persist.saveURI(obj_URI,null,null,null,null,obj_TargetFile);
+
+ return true;
+
+ } catch (ex) {
+ aSourceURL=this.removeGETFromURL(aSourceURL);
+ this.addError("[wpdCommon.downloadFile]:\n -> aSourceURL: "+aSourceURL.substring(aSourceURL.length-60)+"\n -> aTargetFilename: "+aTargetFilename+"\n -> "+ex);
+ }
+ return false;
+ },
+
+ // get the integer preferences
+ getIntPrefs : function (branch)
+ {
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
+ return mPrefSvc.getIntPref(branch);
+ },
+
+ // set the integer preferences
+ setIntPrefs : function (branch,value)
+ {
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
+ return mPrefSvc.setIntPref(branch,value);
+ },
+
+ // get the integer preferences
+ getStrPrefs : function (branch)
+ {
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
+ return mPrefSvc.getCharPref(branch);
+ },
+
+ // set the string preferences
+ setStrPrefs : function (branch,value)
+ {
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
+ return mPrefSvc.setCharPref(branch,value);
+ },
+
+ // get the string preferences
+ getStrPrefsEx : function (branch)
+ {
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ return mPrefSvc.getComplexValue(branch,Components.interfaces.nsISupportsString).data;
+ },
+
+ // set the string preferences
+ setStrPrefsEx : function (branch,value)
+ {
+ var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
+ str.data = value;
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ return mPrefSvc.setComplexValue(branch,Components.interfaces.nsISupportsString,str);
+ },
+
+
+ // Get the preferences branch ("browser.download." for normal 'save' mode)...
+ setBoolPrefs : function (branch,value)
+ {
+ var mPrefSvc=Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
+ return mPrefSvc.setBoolPref(branch,value);
+ }
+
+};
+
+
diff --git a/chrome/content/zotero/webpagedump/domsaver.js b/chrome/content/zotero/webpagedump/domsaver.js
new file mode 100644
index 0000000000..221f907710
--- /dev/null
+++ b/chrome/content/zotero/webpagedump/domsaver.js
@@ -0,0 +1,1029 @@
+/* ***** 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 ScrapBook.
+ *
+ * The Initial Developer of the Original Code is Gomita.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bernhard Pollak (WebPageDump Fork)
+ *
+ * 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 ***** */
+
+// --------------------------------------------------------------------------------
+// "WebPageDump" Firefox Extension
+// --------------------------------------------------------------------------------
+// - File: "domsaver.js" -
+// - Description:
+// Makes a (hopefully perfect) local copy of the actual open webpage.
+// Current Browsers make sometimes errors when saving a webpage. The files
+// will be saved in one flat directory (without subdirs)
+// - Using:
+// 1. call "wpdDOMSaver.init(filePath)" and pass the full destination path
+// 2. afterwards call "wpdDOMSaver.saveHTMLDocument" for saving the (active) window
+// --------------------------------------------------------------------------------
+// Call Tree Overview - wpdDOMSaver
+//
+// saveHTMLDocument
+// saveDocumentEx (decide if we have a HTML or another file)
+// saveDocumentFile (we have a non HTML file (e.g for embedded objects - images, movies,...))
+// download (we download the file and ...)
+// writefile (... make a HTML wrapper file)
+// saveDocumentHTML (we have a HTML File)
+// processDOMRecursively (go through the DOM nodes)
+// processDOMNode (for each node we do extensive processing (links, javascript,...))
+// download (for image,flash,... references)
+// saveDocumentEx ... (starting again with "saveDocumentEx" for frame documents)
+// saveDocumentCSS (save CSS File)
+// processCSSRecursively (process the CSS text)
+// processCSSText (do some replacement stuff and link processing)
+// download (download CSS image references)
+// generateHTMLString (create the HTML string)
+//
+//
+// --------------------------------------------------------------------------------
+//
+
+//
+
+// TO DO: use version information from rdf file...
+var WPD_VERSION = "0.2";
+
+
+// Bug variables: set to false if the bug is not present anymore
+
+// CRLFBUG: Innerhtml trims the text inside a tag. This lead
+// to problems with the PRE Tag where sometimes one starting
+// carriage return is lost...
+var WPD_CRLFBUG = true;
+
+// ENTITYBUG: HTML Entities are lost inside the DOM Tree (they
+// are converted to corresponding unicode characters) which
+// results in problems when using a non unicode charset as output
+// target where this values/symbols do not exist. So we call
+// the ConvertToEntities XPCOM function for generating usual
+// HTML Entities...
+// (this is precisely not a bug but a concept failure)
+var WPD_ENTITYBUG = true;
+
+// CSSSCROLLBUG: The css "scroll" property of "background" is
+// loosing the zero vertical position leading to a false
+// positioned background (centered by default)...
+var WPD_CSSSCROLLBUG = true;
+// CSSBACKGROUNDPOSITIONBUG: "background-position 0 0" is
+// loosing the zero vertical position
+var WPD_CSSBACKGROUNDPOSITIONBUG = true;
+
+// DOCTYPEBUG: If the doctype is inserted before
+// the tag there would be rendering errors with the
+// right to left writing direction, because there are problems
+// with the DIR attribute (text direction (rtl,ltr,lro,rlo))
+// Positioning the doctype below the Tag would fix the
+// problem.
+// But: inserting the docctype only below the tag
+// results in small layout changes in some tables. So we
+// leave the doctype at the original position before the
+// HTML tag and insert the doctype entry a second
+// time below the tag...
+var WPD_DOCTYPEBUG = true;
+
+// JAVASCRIPTSRCBUG: Deleting the "src" attribute together
+// with the whole