From 651bcf2380feef12a596daed68654d00a56b76ab Mon Sep 17 00:00:00 2001
From: Dan Stillman
Date: Mon, 13 Oct 2008 19:51:53 +0000
Subject: [PATCH] Adds rich text support to notes
- Still a few issues
- Converts plaintext notes to HTML on upgrade
---
chrome/content/zotero/addCitationDialog.xul | 2 +-
chrome/content/zotero/bindings/noteeditor.xml | 10 +-
.../zotero/bindings/styled-textbox.xml | 142 +++++++++++++++---
.../content/zotero/editBibliographyDialog.xul | 2 +-
.../content/zotero/tiny_mce/integration.html | 25 ++-
chrome/content/zotero/tiny_mce/note.html | 63 +++++++-
chrome/content/zotero/xpcom/data/item.js | 17 ++-
chrome/content/zotero/xpcom/data/notes.js | 3 +
chrome/content/zotero/xpcom/db.js | 14 ++
chrome/content/zotero/xpcom/report.js | 19 ++-
chrome/content/zotero/xpcom/schema.js | 5 +
chrome/skin/default/zotero/report/detail.css | 8 +-
.../integration-content.css} | 2 +-
.../default/zotero/tinymce/note-content.css | 14 ++
userdata.sql | 2 +-
15 files changed, 282 insertions(+), 46 deletions(-)
rename chrome/skin/default/zotero/{tinymce-content.css => tinymce/integration-content.css} (75%)
create mode 100644 chrome/skin/default/zotero/tinymce/note-content.css
diff --git a/chrome/content/zotero/addCitationDialog.xul b/chrome/content/zotero/addCitationDialog.xul
index 3dc99d1c7..29c57025f 100644
--- a/chrome/content/zotero/addCitationDialog.xul
+++ b/chrome/content/zotero/addCitationDialog.xul
@@ -192,7 +192,7 @@
-
+
diff --git a/chrome/content/zotero/bindings/noteeditor.xml b/chrome/content/zotero/bindings/noteeditor.xml
index 791937eb9..341117c6c 100644
--- a/chrome/content/zotero/bindings/noteeditor.xml
+++ b/chrome/content/zotero/bindings/noteeditor.xml
@@ -155,11 +155,11 @@
textbox.setAttribute('readonly', 'true');
}
- var scrollPos = textbox.inputField.scrollTop;
+ //var scrollPos = textbox.inputField.scrollTop;
if (this.item) {
textbox.value = this.item.getNote();
}
- textbox.inputField.scrollTop = scrollPos;
+ //textbox.inputField.scrollTop = scrollPos;
this._id('linksbox').hidden = !(this.displayTags && this.displayRelated);
@@ -322,7 +322,7 @@
@@ -330,7 +330,7 @@
@@ -357,7 +357,7 @@
-
+
diff --git a/chrome/content/zotero/bindings/styled-textbox.xml b/chrome/content/zotero/bindings/styled-textbox.xml
index d37836eb4..3b9bb0435 100644
--- a/chrome/content/zotero/bindings/styled-textbox.xml
+++ b/chrome/content/zotero/bindings/styled-textbox.xml
@@ -28,23 +28,33 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+
+
+
+
+
+
",
+ "":"\\i ",
+ "":"\\i0 ",
"":"\\i ",
"":"\\i0 ",
+ "":"\\b ",
+ "":"\\b0 ",
"":"\\b ",
"":"\\b0 ",
"":"\\ul ",
"":"\\ul0 ",
- "
":"\x0B",
+ "
":"\x0B",
"":"\\super ",
"":"\\super0 ",
"":"\\sub ",
@@ -56,41 +66,108 @@
// not sure why an event is necessary here, but it is
var me = this;
- this._loadHandler = function() {me._browserLoaded()};
- this._browser.addEventListener("DOMContentLoaded", this._loadHandler, false);
+ this._loadHandler = function() {me._iframeLoaded()};
+ this._iframe.addEventListener("DOMContentLoaded", this._loadHandler, false);
]]>
-
-
+
+
+
+
+
+
", "", "g");
output = output.replace("
", "\\par ", "g");
output = output.replace(/<\/?div[^>]*>/g, "");
output = Zotero.Utilities.prototype.trim(output);
+ output = Zotero.Utilities.prototype.unescapeHTML(output);
if(output.substr(-4) == "\\par") output = output.substr(0, output.length-4);
}
return output;
]]>
+
+
-
+
\ No newline at end of file
diff --git a/chrome/content/zotero/editBibliographyDialog.xul b/chrome/content/zotero/editBibliographyDialog.xul
index cf00cdf89..63ddde068 100644
--- a/chrome/content/zotero/editBibliographyDialog.xul
+++ b/chrome/content/zotero/editBibliographyDialog.xul
@@ -111,6 +111,6 @@
-
+
diff --git a/chrome/content/zotero/tiny_mce/integration.html b/chrome/content/zotero/tiny_mce/integration.html
index c6f1a46a1..1baa5b555 100755
--- a/chrome/content/zotero/tiny_mce/integration.html
+++ b/chrome/content/zotero/tiny_mce/integration.html
@@ -1,13 +1,32 @@
+
+
+
-
-
+
+
diff --git a/chrome/content/zotero/tiny_mce/note.html b/chrome/content/zotero/tiny_mce/note.html
index 77556c2ac..969998aff 100755
--- a/chrome/content/zotero/tiny_mce/note.html
+++ b/chrome/content/zotero/tiny_mce/note.html
@@ -2,24 +2,79 @@
TinyMCE
+
-
+
diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js
index a4e41a4a7..a7847234e 100644
--- a/chrome/content/zotero/xpcom/data/item.js
+++ b/chrome/content/zotero/xpcom/data/item.js
@@ -1240,10 +1240,16 @@ Zotero.Item.prototype.save = function() {
sql = "INSERT INTO itemNotes "
+ "(itemID, sourceItemID, note, title) VALUES (?,?,?,?)";
var parent = this.isNote() ? this.getSource() : null;
+ var noteText = this._noteText ? this._noteText : '';
+ // Add wrapper if not present
+ if (!noteText.match(/^
.*<\/div>$/)) {
+ noteText = '
' + noteText + '
';
+ }
+
var bindParams = [
itemID,
parent ? parent : null,
- this._noteText ? this._noteText : '',
+ noteText,
this._noteTitle ? this._noteTitle : ''
];
Zotero.DB.query(sql, bindParams);
@@ -1575,10 +1581,15 @@ Zotero.Item.prototype.save = function() {
sql = "REPLACE INTO itemNotes "
+ "(itemID, sourceItemID, note, title) VALUES (?,?,?,?)";
var parent = this.isNote() ? this.getSource() : null;
+ var noteText = this._noteText;
+ // Add
wrapper if not present
+ if (!noteText.match(/^
.*<\/div>$/)) {
+ noteText = '
' + noteText + '
';
+ }
var bindParams = [
this.id,
parent ? parent : null,
- this._noteText,
+ noteText,
this._noteTitle
];
Zotero.DB.query(sql, bindParams);
@@ -1983,6 +1994,8 @@ Zotero.Item.prototype.getNote = function() {
var sql = "SELECT note FROM itemNotes WHERE itemID=?";
var note = Zotero.DB.valueQuery(sql, this.id);
+ // Don't include
wrapper when returning value
+ note = note.replace(/^
(.*)<\/div>$/, '$1');
this._noteText = note ? note : '';
diff --git a/chrome/content/zotero/xpcom/data/notes.js b/chrome/content/zotero/xpcom/data/notes.js
index a22813267..c99747589 100644
--- a/chrome/content/zotero/xpcom/data/notes.js
+++ b/chrome/content/zotero/xpcom/data/notes.js
@@ -30,6 +30,9 @@ Zotero.Notes = new function() {
* Return first line (or first MAX_LENGTH characters) of note content
**/
function noteToTitle(text) {
+ text = Zotero.Utilities.prototype.trim(text);
+ text = Zotero.Utilities.prototype.unescapeHTML(text);
+
var max = this.MAX_TITLE_LENGTH;
var t = text.substring(0, max);
diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js
index 6589df9c2..8748e3d95 100644
--- a/chrome/content/zotero/xpcom/db.js
+++ b/chrome/content/zotero/xpcom/db.js
@@ -995,6 +995,20 @@ Zotero.DBConnection.prototype._getDBConnection = function () {
};
this._connection.createFunction('regexp', 2, rx);
+ // text2html UDF
+ var rx = {
+ onFunctionCall: function (arg) {
+ var str = arg.getUTF8String(0);
+ str = Zotero.Utilities.prototype.htmlSpecialChars(str);
+ str = '
'
+ + str.replace(/\n/g, '
')
+ .replace(/\t/g, ' ')
+ .replace(/ /g, ' ')
+ + '
';
+ return str.replace(/
\s*<\/p>/g, '
');
+ }
+ };
+ this._connection.createFunction('text2html', 1, rx);
return this._connection;
}
diff --git a/chrome/content/zotero/xpcom/report.js b/chrome/content/zotero/xpcom/report.js
index f3c3d0888..7886930f7 100644
--- a/chrome/content/zotero/xpcom/report.js
+++ b/chrome/content/zotero/xpcom/report.js
@@ -70,7 +70,14 @@ Zotero.Report = new function() {
// Independent note
if (arr['note']) {
- content += '
' + escapeXML(arr['note']) + '
\n';
+ content += '\n';
+ if (arr.note.substr(0, 1024).match(/
]*>/)) {
+ content += arr.note + '\n';
+ }
+ // Wrap plaintext notes in
+ else {
+ content += '
' + arr.note + '
\n';
+ }
}
}
@@ -85,7 +92,15 @@ Zotero.Report = new function() {
content += '
\n';
for each(var note in arr.reportChildren.notes) {
content += '- \n';
- content += '
' + escapeXML(note.note) + '
\n';
+
+ content += note.note + '\n';
+ if (note.note.substr(0, 1024).match(/]*>/)) {
+ content += note.note + '\n';
+ }
+ // Wrap plaintext notes in
+ else {
+ content += '
' + note.note + '
\n';
+ }
// Child note tags
content += _generateTagsList(note);
diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js
index 6f9b293dc..48f278d5c 100644
--- a/chrome/content/zotero/xpcom/schema.js
+++ b/chrome/content/zotero/xpcom/schema.js
@@ -1945,6 +1945,11 @@ Zotero.Schema = new function(){
if (i==42) {
Zotero.DB.query("UPDATE itemAttachments SET syncState=0");
}
+
+ // 1.5 Sync Preview 2.3
+ if (i==43) {
+ Zotero.DB.query("UPDATE itemNotes SET note='' || TEXT2HTML(note) || '
' WHERE note NOT LIKE ' li p:last-child {
/* Preserve whitespace on notes */
-ul.notes li p, li.note p {
- white-space: pre-wrap; /* css-3 */
- white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
+ul.notes li p.plaintext, li.note p.plaintext {
+ white-space: pre-wrap;
}
/* Display tags within child notes inline */
diff --git a/chrome/skin/default/zotero/tinymce-content.css b/chrome/skin/default/zotero/tinymce/integration-content.css
similarity index 75%
rename from chrome/skin/default/zotero/tinymce-content.css
rename to chrome/skin/default/zotero/tinymce/integration-content.css
index eb1f290b6..28158e5bb 100755
--- a/chrome/skin/default/zotero/tinymce-content.css
+++ b/chrome/skin/default/zotero/tinymce/integration-content.css
@@ -1,2 +1,2 @@
-body, td, pre {font-family:Times New Roman, Times, serif; font-size:14px; margin: 8px;}
+body, td, pre {font-family:Times New Roman, Times, serif; font-size:14px; margin: 8px;}
p, div {margin:0; padding:0}
\ No newline at end of file
diff --git a/chrome/skin/default/zotero/tinymce/note-content.css b/chrome/skin/default/zotero/tinymce/note-content.css
new file mode 100644
index 000000000..8b4b8d87e
--- /dev/null
+++ b/chrome/skin/default/zotero/tinymce/note-content.css
@@ -0,0 +1,14 @@
+body {
+ font-size: 11px;
+ font-family: Lucida Grande, Tahoma, Verdana, Helvetica, sans-serif;
+}
+
+/*
+blockquote p:not(:empty):before {
+ content: '“'
+}
+
+blockquote p:not(:empty):after {
+ content: '”'
+}
+*/
diff --git a/userdata.sql b/userdata.sql
index 5aa23ca52..7afaf79e2 100644
--- a/userdata.sql
+++ b/userdata.sql
@@ -1,4 +1,4 @@
--- 42
+-- 43
-- This file creates tables containing user-specific data -- any changes made
-- here must be mirrored in transition steps in schema.js::_migrateSchema()