Skip to content

Commit

Permalink
Upgrade to TinyMCE 4.5.1
Browse files Browse the repository at this point in the history
- New flat theme (with padding tightened a bit from the default to fit
  in right-hand pane)
- Adds search/replace within notes
- Adds URL autolinking
- Image pasting/dragging is now properly disallowed (though TinyMCE 4
  has hooks that may allow us to actually support this by automatically
  creating attachments)
- New blockquote style with color bar
- Replaces custom context menu on link click with built-in version

 To-do:

- Fix display of pop-ups, which are now modal dialogs within the note
  frame instead of pop-up windows, to stay fully within the frame
- Localize (more important now that there are tooltips)
- Support image dragging
- Update elements list for HTML5, for better drag-and-drop?
- Move directionality control to context menu instead of taking up
  toolbar space?
- Evaluate other plugins for potential inclusion
- Show additional controls in separate note window?
- Fix opacity of text in tooltips

Closes zotero#451, closes zotero#421
  • Loading branch information
dstillman committed Dec 26, 2016
1 parent ab959cd commit dc04a12
Show file tree
Hide file tree
Showing 67 changed files with 54,822 additions and 25,006 deletions.
108 changes: 53 additions & 55 deletions chrome/content/zotero/bindings/styled-textbox.xml
Expand Up @@ -48,6 +48,7 @@
<constructor><![CDATA[
this.mode = this.getAttribute('mode');
this._onInitCallbacks = [];
this._iframe = document.getAnonymousElementByAttribute(this, "anonid", "rt-view");
this._htmlRTFmap = [
Expand All @@ -68,8 +69,10 @@
[/(?:\\par{}|\\\r?\n)/g, "</p><p>"]
];
this.init = function() {
if (this.initialized) return;
this.prepare = function() {
// DEBUG: Does this actually happen?
if (this.prepared) return;
// Tag data
var _rexData = [
[
Expand Down Expand Up @@ -282,9 +285,9 @@
this.rtfHTMLtagRegistry = tagRegistryMaker(1);
this.htmlRTFtagRegistry = tagRegistryMaker(0);
this.initialized = true;
this.prepared = true;
}
this.init();
this.prepare();
this.getSplit = function(mode, txt) {
if (!txt) return [];
Expand Down Expand Up @@ -375,14 +378,14 @@
Zotero.debug("Setting mode to " + val);
switch (val) {
case 'note':
var self = this;
this._eventHandler = function (event) {
// Necessary in Fx32+
if (event.wrappedJSObject) {
event = event.wrappedJSObject;
}
var commandEvent = false;
//Zotero.debug(event.type);
switch (event.type) {
case 'keydown':
Expand All @@ -392,7 +395,7 @@
&& !event.altKey && event.keyCode == 90) {
event.stopPropagation();
event.preventDefault();
self.redo();
this.redo();
return;
}
break;
Expand All @@ -407,38 +410,36 @@
//Zotero.debug("Not a char");
return;
}
commandEvent = true;
break;
// 'change' includes text added via drag-and-drop
case 'change':
case 'undo':
case 'redo':
commandEvent = true;
break;
case 'openlink':
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
win = wm.getMostRecentWindow('navigator:browser');
win.ZoteroPane.loadURI(event.target.href, event.modifierKeys);
break;
default:
return;
}
if (self._timer) {
clearTimeout(self._timer);
}
// Trigger command event on change
if (event.type == 'keypress' || event.type == 'change') {
self._timer = self.timeout && setTimeout(function () {
var attr = self.getAttribute('oncommand');
// Trigger command on change
if (commandEvent && this.timeout) {
if (this._timer) {
clearTimeout(this._timer);
}
this._timer = setTimeout(function () {
var attr = this.getAttribute('oncommand');
attr = attr.replace('this', 'thisObj');
var func = new Function('thisObj', 'event', attr);
func(self, event);
}, self.timeout);
func(this, event);
}.bind(this), this.timeout);
}
return true;
};
}.bind(this);
break;
case 'integration':
Expand Down Expand Up @@ -583,6 +584,18 @@
</body>
</method>

<method name="onInit">
<parameter name="callback"/>
<body><![CDATA[
if (this.initialized) {
this._editor.once(event, callback);
}
else {
this._onInitCallbacks.push(callback);
}
]]></body>
</method>

<field name="_loaded"/>
<method name="_load">
<body>
Expand Down Expand Up @@ -660,15 +673,15 @@
if (fontSize < 6) {
fontSize = 11;
}
var css = "body#zotero-tinymce-note.mceContentBody, "
+ "body#zotero-tinymce-note.mceContentBody p, "
+ "body#zotero-tinymce-note.mceContentBody th, "
+ "body#zotero-tinymce-note.mceContentBody td, "
+ "body#zotero-tinymce-note.mceContentBody pre { "
var css = "body#zotero-tinymce-note, "
+ "body#zotero-tinymce-note p, "
+ "body#zotero-tinymce-note th, "
+ "body#zotero-tinymce-note td, "
+ "body#zotero-tinymce-note pre { "
+ "font-size: " + fontSize + "px; "
+ "} "
+ "body#zotero-tinymce-note.mceContentBody, "
+ "body#zotero-tinymce-note.mceContentBody p { "
+ "body#zotero-tinymce-note, "
+ "body#zotero-tinymce-note p { "
+ "font-family: "
+ Zotero.Prefs.get('note.fontFamily') + "; "
+ "}"
Expand All @@ -681,11 +694,11 @@
head.appendChild(style);
}
// Dispatch a tinymceInitialized event
var ev = document.createEvent('HTMLEvents');
ev.initEvent('tinymceInitialized', true, true);
self.dispatchEvent(ev);
};
let cb;
while (cb = this._onInitCallbacks.shift()) {
cb(this._editor);
}
}.bind(this);
}
var editor = SJOW.tinyMCE.get("tinymce");
Expand All @@ -701,11 +714,7 @@
return;
}
if(window.ZoteroTab) {
ZoteroTab.containerWindow.gBrowser.removeEventListener("DOMContentLoaded", listener, true);
} else {
self._iframe.removeEventListener("DOMContentLoaded", listener, false);
}
self._iframe.removeEventListener("DOMContentLoaded", listener, false);
if (self._eventHandler) {
win.wrappedJSObject.zoteroHandleEvent = self._eventHandler;
Expand All @@ -715,20 +724,9 @@
win.wrappedJSObject.zoteroExecCommand = function (doc, command, ui, value) {
return doc.execCommand(command, ui, value);
}
win.wrappedJSObject.zoteroFixWindow = function (win) {
win.locationbar.visible = false;
win.statusbar.visible = false;
}
};
}.bind(this);
if(window.ZoteroTab) {
// I'm not sure why it's necessary to attach the event listener to the
// container window to get it to fire on the tab, but apparently it is...
ZoteroTab.containerBrowser.addEventListener("DOMContentLoaded", listener, true);
} else {
this._iframe.addEventListener("DOMContentLoaded", listener, false);
}
this._iframe.addEventListener("DOMContentLoaded", listener, false);
this._iframe.webNavigation.loadURI(uri.spec,
Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null, null);
Expand Down
11 changes: 4 additions & 7 deletions chrome/content/zotero/integration/addCitationDialog.js
Expand Up @@ -623,14 +623,11 @@ var Zotero_Citation_Dialog = new function () {
io.preview().then(function(preview) {
editor.value = preview;

if(editor.initialized) {
if (editor.initialized) {
_originalHTML = editor.value;
} else {
var eventListener = function() {
_originalHTML = editor.value;
editor.removeEventListener("tinymceInitialized", eventListener, false);
};
editor.addEventListener("tinymceInitialized", eventListener, false);
}
else {
editor.onInit(() => _originalHTML = editor.value);
}
});
} else {
Expand Down
2 changes: 1 addition & 1 deletion chrome/skin/default/zotero/overlay.css
Expand Up @@ -247,7 +247,7 @@
#zotero-item-pane
{
width: 338px;
min-width: 250px;
min-width: 320px;
}

#zotero-layout-switcher
Expand Down
Empty file modified resource/tinymce/css/integration-content.css 100755 → 100644
Empty file.
19 changes: 5 additions & 14 deletions resource/tinymce/css/note-content.css
@@ -1,16 +1,7 @@
pre {
font-family: -moz-fixed;
}

blockquote {
margin-left: 2em;
}

/* Add quotation marks around blockquote */
blockquote p:not(:empty):before {
content: '“';
}

blockquote p:not(:empty):last-child:after {
content: '”';
margin-top: 1.5em;
margin-bottom: 1.5em;
margin-left: 1em;
padding-left: .75em;
border-left: 3px solid lightblue;
}
61 changes: 38 additions & 23 deletions resource/tinymce/css/note-ui.css
Expand Up @@ -2,40 +2,55 @@ html, body {
height: 100%;
margin: 0;
}
#tinymce_parent {
display: block;
height: 100%;
}
#tinymce_tbl {

/* Stretch editor to fit frame */
#tinymce_ifr, .mce-tinymce:not(.mce-floatpanel) {
height: 100% !important;
width: 100% !important;
border: 0 !important;
}

table.mceLayout > tbody > tr.mceLast {
position: absolute;
display: block;
top: 54px;
bottom: 2px;
left: 1px;
right: 1px;
.mce-container-body {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}

td.mceIframeContainer {
display: block;
height: 100% !important;
width: 100% !important;
.mce-container-body .mce-edit-area {
position: absolute;
top: 57px;
bottom: 1px;
left: 0;
right: 0;
}
#tinymce_ifr {
height: 100% !important;
width: 100% !important;

/* Shrink the buttons a bit */
.mce-listbox button {
padding-right: 8px !important;
}

.mce-btn-small button {
padding-left: 4px !important;
padding-right: 4px !important;
}

/* Tighten some padding */
.mce-toolbar:first-child > div > :nth-child(3) {
margin-left: 0;
}

.mce-toolbar:last-child > div > :nth-child(2) {
margin-left: 0;
}

#tinymce_formatselect_text {
width: 65px;
/* Keep popup windows within frame */
.mce-window {
max-width: calc(100% - 15px) !important;
overflow-x: hidden;
}

#noScriptWarning {
padding: 4px;
font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-family: sans-serif;
font-size: 12px;
}
35 changes: 12 additions & 23 deletions resource/tinymce/integration.html 100755 → 100644
Expand Up @@ -13,41 +13,30 @@
height: 100%;
min-height: 130px;
}
#tinymce_tbl {
height: 100% !important;
width: 100% !important;
}

#noScriptWarning {
padding: 10px 8px 4px;
font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
font-family: sans-serif;
font-size: 12px;
}
</style>

<script type="text/javascript" src="tiny_mce.js"></script>
<script type="text/javascript" src="tinymce.js"></script>
<script type="text/javascript">
tinyMCE.init({
// General options
mode : "none",
theme : "advanced",
content_css : "css/integration-content.css",

// Theme options
theme_advanced_buttons1 : "bold,italic,underline,|,sub,sup,|,removeformat",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_resizing : true,
content_css: "css/integration-content.css",

toolbar: "bold italic underline | sub sup | removeformat",
toolbar_items_size: 'small',
menubar: false,
resize: false,
statusbar: false,

setup : function (ed) {
ed.onInit.add(function (ed) {
zoteroInit(ed);
});
init_instance_callback: function (ed) {
zoteroInit(ed);
}
});
tinyMCE.execCommand("mceAddControl", true, "tinymce");
tinyMCE.execCommand("mceAddEditor", true, "tinymce");
</script>
</head>
<body>
Expand Down
1 change: 0 additions & 1 deletion resource/tinymce/langs/en.js

This file was deleted.

0 comments on commit dc04a12

Please sign in to comment.