Sync with WebODF e50bc588ff3e380178ffabecfe2fbca92bef6aed.
* Keyboard support in iOS and other touchscreens * Pinch-zoom support on touch devices * SVG selections that look like those in LibreOffice * Major speed improvements with all editing operations and cursor movements * IME support on desktop browsers * Word-by-word navigation with Ctrl+Left/Right * Fixes for IE11 * Ability to add/edit/remove Hyperlinks.
This commit is contained in:
parent
8b71362d0e
commit
3cd491a5ef
24
css/3rdparty/webodf/editor.css
vendored
24
css/3rdparty/webodf/editor.css
vendored
@ -25,13 +25,18 @@ body.claro, #mainContainer {
|
||||
|
||||
#toolbar {
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
#container {
|
||||
text-align: center;
|
||||
background-color: #ddd;
|
||||
overflow: auto;
|
||||
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
bottom: 0;
|
||||
@ -40,7 +45,6 @@ body.claro, #mainContainer {
|
||||
}
|
||||
|
||||
#canvas {
|
||||
box-shadow: 0px 0px 20px #aaa;
|
||||
margin-top: 30px;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
@ -50,8 +54,16 @@ body.claro, #mainContainer {
|
||||
-webkit-transform-origin: top center;
|
||||
-moz-transform-origin: top center;
|
||||
-o-transform-origin: top center;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Add shadow to the sizer and not the canvas,
|
||||
* so that it will follow the smooth zooming
|
||||
* of the slider and not have to be updated
|
||||
* every time a gesture ends
|
||||
*/
|
||||
#canvas > div {
|
||||
box-shadow: 0px 0px 20px #aaa;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
@ -241,7 +253,7 @@ div.memberListLabel[fullname]:before {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
cursor div {
|
||||
cursor .handle {
|
||||
margin-top: 5px;
|
||||
padding-top: 3px;
|
||||
margin-left: auto;
|
||||
@ -269,11 +281,11 @@ cursor img {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
cursor div.active {
|
||||
cursor .handle.active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
cursor div:after {
|
||||
cursor .handle:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 0px;
|
||||
|
56
js/3rdparty/webodf/editor/Editor.js
vendored
56
js/3rdparty/webodf/editor/Editor.js
vendored
@ -317,6 +317,7 @@ define("webodf/editor/Editor", [
|
||||
runtime.assert(editorSession, "editorSession should exist here.");
|
||||
|
||||
tools.setEditorSession(editorSession);
|
||||
editorSession.sessionController.insertLocalCursor();
|
||||
editorSession.sessionController.startEditing();
|
||||
};
|
||||
|
||||
@ -330,6 +331,7 @@ define("webodf/editor/Editor", [
|
||||
|
||||
tools.setEditorSession(undefined);
|
||||
editorSession.sessionController.endEditing();
|
||||
editorSession.sessionController.removeLocalCursor();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -364,6 +366,40 @@ define("webodf/editor/Editor", [
|
||||
eventNotifier.unsubscribe(eventid, listener);
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies a CSS transformation to the toolbar
|
||||
* to ensure that if there is a body-scroll,
|
||||
* the toolbar remains visible at the top of
|
||||
* the screen.
|
||||
* The bodyscroll quirk has been observed on
|
||||
* iOS, generally when the keyboard appears.
|
||||
* But this workaround should function on
|
||||
* other platforms that exhibit this behaviour
|
||||
* as well.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function translateToolbar() {
|
||||
var bar = document.getElementById('toolbar'),
|
||||
y = document.body.scrollTop;
|
||||
|
||||
bar.style.WebkitTransformOrigin = "center top";
|
||||
bar.style.WebkitTransform = 'translateY(' + y + 'px)';
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: At the moment both the toolbar and the canvas
|
||||
* container are absolutely positioned. Changing them to
|
||||
* relative positioning to ensure that they do not overlap
|
||||
* causes scrollbars *within* the container to disappear.
|
||||
* Not sure why this happens, and a proper CSS fix has not
|
||||
* been found yet, so for now we need to reposition
|
||||
* the container using Js.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function repositionContainer() {
|
||||
document.getElementById('container').style.top = document.getElementById('toolbar').getBoundingClientRect().height + 'px';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!function(!Object=)} callback, passing an error object in case of error
|
||||
* @return {undefined}
|
||||
@ -371,6 +407,11 @@ define("webodf/editor/Editor", [
|
||||
this.destroy = function (callback) {
|
||||
var destroyMemberListView = memberListView ? memberListView.destroy : function(cb) { cb(); };
|
||||
|
||||
window.removeEventListener('scroll', translateToolbar);
|
||||
window.removeEventListener('focusout', translateToolbar);
|
||||
window.removeEventListener('touchmove', translateToolbar);
|
||||
window.removeEventListener('resize', repositionContainer);
|
||||
|
||||
// TODO: decide if some forced close should be done here instead of enforcing proper API usage
|
||||
runtime.assert(!session, "session should not exist here.");
|
||||
|
||||
@ -407,10 +448,12 @@ define("webodf/editor/Editor", [
|
||||
var editorPane, memberListPane,
|
||||
inviteButton,
|
||||
canvasElement = document.getElementById("canvas"),
|
||||
container = document.getElementById('container'),
|
||||
memberListElement = document.getElementById('memberList'),
|
||||
collabEditing = Boolean(server),
|
||||
directParagraphStylingEnabled = (! collabEditing) || args.unstableFeaturesEnabled,
|
||||
imageInsertingEnabled = (! collabEditing) || args.unstableFeaturesEnabled,
|
||||
hyperlinkEditingEnabled = (! collabEditing) || args.unstableFeaturesEnabled,
|
||||
// annotations not yet properly supported for OT
|
||||
annotationsEnabled = (! collabEditing) || args.unstableFeaturesEnabled,
|
||||
// undo manager is not yet integrated with collaboration
|
||||
@ -477,12 +520,13 @@ define("webodf/editor/Editor", [
|
||||
close: close,
|
||||
directParagraphStylingEnabled: directParagraphStylingEnabled,
|
||||
imageInsertingEnabled: imageInsertingEnabled,
|
||||
hyperlinkEditingEnabled: hyperlinkEditingEnabled,
|
||||
annotationsEnabled: annotationsEnabled,
|
||||
undoRedoEnabled: undoRedoEnabled
|
||||
});
|
||||
|
||||
odfCanvas = new odf.OdfCanvas(canvasElement);
|
||||
odfCanvas.enableAnnotations(annotationsEnabled);
|
||||
odfCanvas.enableAnnotations(annotationsEnabled, true);
|
||||
|
||||
odfCanvas.addListener("statereadychange", function () {
|
||||
var viewOptions = {
|
||||
@ -496,7 +540,8 @@ define("webodf/editor/Editor", [
|
||||
editorSession = new EditorSession(session, pendingMemberId, {
|
||||
viewOptions: viewOptions,
|
||||
directParagraphStylingEnabled: directParagraphStylingEnabled,
|
||||
imageInsertingEnabled: imageInsertingEnabled
|
||||
imageInsertingEnabled: imageInsertingEnabled,
|
||||
hyperlinkEditingEnabled: hyperlinkEditingEnabled
|
||||
});
|
||||
if (undoRedoEnabled) {
|
||||
editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager());
|
||||
@ -512,6 +557,13 @@ define("webodf/editor/Editor", [
|
||||
pendingEditorReadyCallback = null;
|
||||
pendingMemberId = null;
|
||||
});
|
||||
|
||||
repositionContainer();
|
||||
|
||||
window.addEventListener('scroll', translateToolbar);
|
||||
window.addEventListener('focusout', translateToolbar);
|
||||
window.addEventListener('touchmove', translateToolbar);
|
||||
window.addEventListener('resize', repositionContainer);
|
||||
}
|
||||
|
||||
init();
|
||||
|
66
js/3rdparty/webodf/editor/EditorSession.js
vendored
66
js/3rdparty/webodf/editor/EditorSession.js
vendored
@ -43,10 +43,6 @@ define("webodf/editor/EditorSession", [
|
||||
], function (fontsCSS) { // fontsCSS is retrieved as a string, using dojo's text retrieval AMD plugin
|
||||
"use strict";
|
||||
|
||||
runtime.libraryPaths = function () {
|
||||
return [ "../../webodf/lib" ];
|
||||
};
|
||||
|
||||
runtime.loadClass("core.DomUtils");
|
||||
runtime.loadClass("odf.OdfUtils");
|
||||
runtime.loadClass("ops.OdtDocument");
|
||||
@ -54,11 +50,13 @@ define("webodf/editor/EditorSession", [
|
||||
runtime.loadClass("ops.Session");
|
||||
runtime.loadClass("odf.Namespaces");
|
||||
runtime.loadClass("odf.OdfCanvas");
|
||||
runtime.loadClass("odf.OdfUtils");
|
||||
runtime.loadClass("gui.CaretManager");
|
||||
runtime.loadClass("gui.Caret");
|
||||
runtime.loadClass("gui.SessionController");
|
||||
runtime.loadClass("gui.SessionView");
|
||||
runtime.loadClass("gui.TrivialUndoManager");
|
||||
runtime.loadClass("gui.SvgSelectionView");
|
||||
runtime.loadClass("gui.SelectionViewManager");
|
||||
runtime.loadClass("core.EventNotifier");
|
||||
runtime.loadClass("gui.ShadowCursor");
|
||||
@ -208,7 +206,7 @@ define("webodf/editor/EditorSession", [
|
||||
function trackCurrentParagraph(info) {
|
||||
var cursor = odtDocument.getCursor(localMemberId),
|
||||
range = cursor && cursor.getSelectedRange(),
|
||||
paragraphRange = odtDocument.getDOM().createRange();
|
||||
paragraphRange = odtDocument.getDOMDocument().createRange();
|
||||
paragraphRange.selectNode(info.paragraphElement);
|
||||
if ((range && domUtils.rangesIntersect(range, paragraphRange)) || info.paragraphElement === currentParagraphNode) {
|
||||
self.emit(EditorSession.signalParagraphChanged, info);
|
||||
@ -312,7 +310,7 @@ define("webodf/editor/EditorSession", [
|
||||
/**
|
||||
* Round the step up to the next step
|
||||
* @param {!number} step
|
||||
* @returns {!boolean}
|
||||
* @return {!boolean}
|
||||
*/
|
||||
function roundUp(step) {
|
||||
return step === ops.StepsTranslator.NEXT_STEP;
|
||||
@ -394,7 +392,7 @@ define("webodf/editor/EditorSession", [
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attributes of a given paragraph style name
|
||||
@ -522,22 +520,30 @@ define("webodf/editor/EditorSession", [
|
||||
return array;
|
||||
};
|
||||
|
||||
this.getSelectedHyperlinks = function () {
|
||||
var cursor = odtDocument.getCursor(localMemberId);
|
||||
// no own cursor yet/currently added?
|
||||
if (!cursor) {
|
||||
return [];
|
||||
}
|
||||
return odfUtils.getHyperlinkElements(cursor.getSelectedRange());
|
||||
};
|
||||
|
||||
this.getSelectedRange = function () {
|
||||
var cursor = odtDocument.getCursor(localMemberId);
|
||||
return cursor && cursor.getSelectedRange();
|
||||
};
|
||||
|
||||
function undoStackModified(e) {
|
||||
self.emit(EditorSession.signalUndoStackChanged, e);
|
||||
}
|
||||
|
||||
this.hasUndoManager = function () {
|
||||
return Boolean(self.sessionController.getUndoManager());
|
||||
};
|
||||
|
||||
this.undo = function () {
|
||||
var undoManager = self.sessionController.getUndoManager();
|
||||
undoManager.moveBackward(1);
|
||||
self.sessionController.undo();
|
||||
};
|
||||
|
||||
this.redo = function () {
|
||||
var undoManager = self.sessionController.getUndoManager();
|
||||
undoManager.moveForward(1);
|
||||
self.sessionController.redo();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -548,8 +554,8 @@ define("webodf/editor/EditorSession", [
|
||||
* @param {!number} height
|
||||
*/
|
||||
this.insertImage = function (mimetype, content, width, height) {
|
||||
self.sessionController.getTextManipulator().removeCurrentSelection();
|
||||
self.sessionController.getImageManager().insertImage(mimetype, content, width, height);
|
||||
self.sessionController.getTextController().removeCurrentSelection();
|
||||
self.sessionController.getImageController().insertImage(mimetype, content, width, height);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -569,12 +575,12 @@ define("webodf/editor/EditorSession", [
|
||||
|
||||
head.removeChild(fontStyles);
|
||||
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalMemberAdded, onMemberAdded);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalMemberUpdated, onMemberUpdated);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalMemberRemoved, onMemberRemoved);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved);
|
||||
odtDocument.unsubscribe(ops.Document.signalMemberAdded, onMemberAdded);
|
||||
odtDocument.unsubscribe(ops.Document.signalMemberUpdated, onMemberUpdated);
|
||||
odtDocument.unsubscribe(ops.Document.signalMemberRemoved, onMemberRemoved);
|
||||
odtDocument.unsubscribe(ops.Document.signalCursorAdded, onCursorAdded);
|
||||
odtDocument.unsubscribe(ops.Document.signalCursorRemoved, onCursorRemoved);
|
||||
odtDocument.unsubscribe(ops.Document.signalCursorMoved, onCursorMoved);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCommonStyleCreated, onStyleCreated);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCommonStyleDeleted, onStyleDeleted);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified);
|
||||
@ -623,17 +629,17 @@ define("webodf/editor/EditorSession", [
|
||||
directParagraphStylingEnabled: config.directParagraphStylingEnabled
|
||||
});
|
||||
caretManager = new gui.CaretManager(self.sessionController);
|
||||
selectionViewManager = new gui.SelectionViewManager();
|
||||
selectionViewManager = new gui.SelectionViewManager(gui.SvgSelectionView);
|
||||
self.sessionView = new gui.SessionView(config.viewOptions, localMemberId, session, caretManager, selectionViewManager);
|
||||
self.availableFonts = getAvailableFonts();
|
||||
selectionViewManager.registerCursor(shadowCursor, true);
|
||||
// Custom signals, that make sense in the Editor context. We do not want to expose webodf's ops signals to random bits of the editor UI.
|
||||
odtDocument.subscribe(ops.OdtDocument.signalMemberAdded, onMemberAdded);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalMemberUpdated, onMemberUpdated);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalMemberRemoved, onMemberRemoved);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, onCursorAdded);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, onCursorRemoved);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, onCursorMoved);
|
||||
odtDocument.subscribe(ops.Document.signalMemberAdded, onMemberAdded);
|
||||
odtDocument.subscribe(ops.Document.signalMemberUpdated, onMemberUpdated);
|
||||
odtDocument.subscribe(ops.Document.signalMemberRemoved, onMemberRemoved);
|
||||
odtDocument.subscribe(ops.Document.signalCursorAdded, onCursorAdded);
|
||||
odtDocument.subscribe(ops.Document.signalCursorRemoved, onCursorRemoved);
|
||||
odtDocument.subscribe(ops.Document.signalCursorMoved, onCursorMoved);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCommonStyleCreated, onStyleCreated);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCommonStyleDeleted, onStyleDeleted);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified);
|
||||
|
16
js/3rdparty/webodf/editor/Tools.js
vendored
16
js/3rdparty/webodf/editor/Tools.js
vendored
@ -49,11 +49,12 @@ define("webodf/editor/Tools", [
|
||||
"webodf/editor/widgets/undoRedoMenu",
|
||||
"webodf/editor/widgets/toolbarWidgets/currentStyle",
|
||||
"webodf/editor/widgets/annotation",
|
||||
"webodf/editor/widgets/paragraphStylesDialog",
|
||||
"webodf/editor/widgets/editHyperlinks",
|
||||
"webodf/editor/widgets/imageInserter",
|
||||
"webodf/editor/widgets/paragraphStylesDialog",
|
||||
"webodf/editor/widgets/zoomSlider",
|
||||
"webodf/editor/EditorSession"],
|
||||
function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, AnnotationControl, ParagraphStylesDialog, ImageInserter, ZoomSlider, EditorSession) {
|
||||
function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, AnnotationControl, EditHyperlinks, ImageInserter, ParagraphStylesDialog, ZoomSlider, EditorSession) {
|
||||
"use strict";
|
||||
|
||||
return function Tools(args) {
|
||||
@ -72,6 +73,7 @@ define("webodf/editor/Tools", [
|
||||
paragraphAlignment,
|
||||
imageInserter,
|
||||
annotationControl,
|
||||
editHyperlinks,
|
||||
sessionSubscribers = [];
|
||||
|
||||
function handleCursorMoved(cursor) {
|
||||
@ -128,6 +130,7 @@ define("webodf/editor/Tools", [
|
||||
widget.startup();
|
||||
});
|
||||
sessionSubscribers.push(undoRedoMenu);
|
||||
undoRedoMenu.onToolDone = onToolDone;
|
||||
}
|
||||
|
||||
// Add annotation
|
||||
@ -226,6 +229,15 @@ define("webodf/editor/Tools", [
|
||||
sessionSubscribers.push(paragraphStylesDialog);
|
||||
paragraphStylesDialog.onToolDone = onToolDone;
|
||||
|
||||
if (args.hyperlinkEditingEnabled) {
|
||||
editHyperlinks = new EditHyperlinks(function (widget) {
|
||||
widget.placeAt(toolbar);
|
||||
widget.startup();
|
||||
});
|
||||
sessionSubscribers.push(editHyperlinks);
|
||||
editHyperlinks.onToolDone = onToolDone;
|
||||
}
|
||||
|
||||
formatMenuButton = new DropDownButton({
|
||||
dropDown: formatDropDownMenu,
|
||||
label: tr('Format'),
|
||||
|
@ -94,7 +94,9 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () {
|
||||
EVENT_BEFORESAVETOFILE,
|
||||
EVENT_SAVEDTOFILE,
|
||||
EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED,
|
||||
EVENT_HASSESSIONHOSTCONNECTIONCHANGED
|
||||
EVENT_HASSESSIONHOSTCONNECTIONCHANGED,
|
||||
ops.OperationRouter.signalProcessingBatchStart,
|
||||
ops.OperationRouter.signalProcessingBatchEnd
|
||||
]),
|
||||
/**@type{!boolean} tells if any local ops have been modifying ops */
|
||||
hasPushedModificationOps = false,
|
||||
@ -150,6 +152,8 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () {
|
||||
// take start time
|
||||
startTime = (new Date()).getTime();
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchStart, {});
|
||||
|
||||
// apply as much as possible in the given time
|
||||
while (unplayedServerOpspecQueue.length > 0) {
|
||||
// time over?
|
||||
@ -164,11 +168,13 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () {
|
||||
runtime.log(" op in: "+runtime.toJson(opspec));
|
||||
if (op !== null) {
|
||||
if (!playbackFunction(op)) {
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
hasError = true;
|
||||
errorCallback("opExecutionFailure");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
hasError = true;
|
||||
runtime.log("ignoring invalid incoming opspec: " + opspec);
|
||||
errorCallback("unknownOpReceived");
|
||||
@ -176,6 +182,8 @@ define("webodf/editor/server/pullbox/OperationRouter", [], function () {
|
||||
}
|
||||
}
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
|
||||
// still unplayed opspecs?
|
||||
if (unplayedServerOpspecQueue.length > 0) {
|
||||
// let other events be handled. then continue
|
||||
@ -493,6 +501,8 @@ runtime.log("OperationRouter: instant opsSync requested");
|
||||
return;
|
||||
}
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchStart, {});
|
||||
|
||||
for (i = 0; i < operations.length; i += 1) {
|
||||
op = operations[i];
|
||||
opspec = op.spec();
|
||||
@ -518,6 +528,8 @@ runtime.log("OperationRouter: instant opsSync requested");
|
||||
triggerPushingOps();
|
||||
|
||||
updateHasLocalUnsyncedOpsState();
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -38,10 +38,11 @@
|
||||
|
||||
/*global runtime,core,define,require,dijit */
|
||||
|
||||
runtime.loadClass("core.CSSUnits");
|
||||
|
||||
define("webodf/editor/widgets/dialogWidgets/alignmentPane", [], function () {
|
||||
"use strict";
|
||||
|
||||
runtime.loadClass("core.CSSUnits");
|
||||
|
||||
var AlignmentPane = function (callback) {
|
||||
var self = this,
|
||||
editorSession,
|
||||
|
30
js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.html
vendored
Normal file
30
js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.html
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<div data-dojo-type="dijit/form/Form" id="editHyperlinkPaneForm" data-dojo-id="editHyperlinkPaneForm">
|
||||
<div>
|
||||
<label text-i18n="Display Text" for="linkDisplayText"></label><br/>
|
||||
<input data-dojo-type="dijit/form/TextBox" id="linkDisplayText"
|
||||
value=""
|
||||
data-dojo-props="trim:true"
|
||||
name="linkDisplayText" />
|
||||
<input data-dojo-type="dijit/form/TextBox" id="isReadOnlyText"
|
||||
type ="hidden"
|
||||
value=""
|
||||
data-dojo-props="trim:true"
|
||||
name="isReadOnlyText" />
|
||||
</div>
|
||||
<div>
|
||||
<label text-i18n="URL" for="linkUrl"></label><br/>
|
||||
<input data-dojo-type="dijit/form/TextBox" id="linkUrl"
|
||||
value="http://"
|
||||
data-dojo-props="trim:true"
|
||||
name="linkUrl" />
|
||||
</div>
|
||||
<div>
|
||||
<button data-dojo-type="dijit/form/Button" id="saveHyperlinkChangeButton" type="submit">Ok</button>
|
||||
<button data-dojo-type="dijit/form/Button" id="cancelHyperlinkChangeButton" data-dojo-id="cancelHyperlinkChangeButton">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
110
js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.js
vendored
Normal file
110
js/3rdparty/webodf/editor/widgets/dialogWidgets/editHyperlinkPane.js
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* The JavaScript code in this page is free software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Affero General Public License
|
||||
* (GNU AGPL) as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. The code is distributed
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As additional permission under GNU AGPL version 3 section 7, you
|
||||
* may distribute non-source (e.g., minimized or compacted) forms of
|
||||
* that code without the copy of the GNU GPL normally required by
|
||||
* section 4, provided you include this license notice and a URL
|
||||
* through which recipients can access the Corresponding Source.
|
||||
*
|
||||
* As a special exception to the AGPL, any HTML file which merely makes function
|
||||
* calls to this code, and for that purpose includes it by reference shall be
|
||||
* deemed a separate work for copyright law purposes. In addition, the copyright
|
||||
* holders of this code give you permission to combine this code with free
|
||||
* software libraries that are released under the GNU LGPL. You may copy and
|
||||
* distribute such a system following the terms of the GNU AGPL for this code
|
||||
* and the LGPL for the libraries. If you modify this code, you may extend this
|
||||
* exception to your version of the code, but you are not obligated to do so.
|
||||
* If you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
* This license applies to this entire compilation.
|
||||
* @licend
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global runtime,core,define,require,document,dijit */
|
||||
|
||||
define("webodf/editor/widgets/dialogWidgets/editHyperlinkPane", [
|
||||
"dojo",
|
||||
"dijit/layout/ContentPane"],
|
||||
|
||||
function (dojo, ContentPane) {
|
||||
"use strict";
|
||||
|
||||
runtime.loadClass("core.CSSUnits");
|
||||
|
||||
var EditHyperlinkPane = function () {
|
||||
var self = this,
|
||||
editorBase = dojo.config && dojo.config.paths && dojo.config.paths['webodf/editor'],
|
||||
contentPane,
|
||||
form,
|
||||
displayTextField,
|
||||
initialValue;
|
||||
|
||||
runtime.assert(editorBase, "webodf/editor path not defined in dojoConfig");
|
||||
|
||||
function onSave() {
|
||||
if (self.onSave) {
|
||||
self.onSave();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
form.set('value', initialValue);
|
||||
if (self.onCancel) {
|
||||
self.onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
contentPane = new ContentPane({
|
||||
title: runtime.tr("editLink"),
|
||||
href: editorBase+"/widgets/dialogWidgets/editHyperlinkPane.html",
|
||||
preload: true,
|
||||
onLoad : function () {
|
||||
form = dijit.byId('editHyperlinkPaneForm');
|
||||
form.onSubmit = onSave;
|
||||
dijit.byId('cancelHyperlinkChangeButton').onClick = onCancel;
|
||||
displayTextField = dijit.byId('linkDisplayText');
|
||||
runtime.translateContent(form.domNode);
|
||||
if (initialValue) {
|
||||
form.set('value', initialValue);
|
||||
displayTextField.set('disabled', initialValue.isReadOnlyText);
|
||||
initialValue = undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.widget = function () {
|
||||
return contentPane;
|
||||
};
|
||||
|
||||
this.value = function () {
|
||||
return form && form.get('value');
|
||||
};
|
||||
|
||||
this.set = function (value) {
|
||||
initialValue = value;
|
||||
if (form) {
|
||||
form.set('value', value);
|
||||
displayTextField.set('disabled', value.isReadOnlyText);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return EditHyperlinkPane;
|
||||
});
|
181
js/3rdparty/webodf/editor/widgets/editHyperlinks.js
vendored
Normal file
181
js/3rdparty/webodf/editor/widgets/editHyperlinks.js
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* The JavaScript code in this page is free software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Affero General Public License
|
||||
* (GNU AGPL) as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. The code is distributed
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As additional permission under GNU AGPL version 3 section 7, you
|
||||
* may distribute non-source (e.g., minimized or compacted) forms of
|
||||
* that code without the copy of the GNU GPL normally required by
|
||||
* section 4, provided you include this license notice and a URL
|
||||
* through which recipients can access the Corresponding Source.
|
||||
*
|
||||
* As a special exception to the AGPL, any HTML file which merely makes function
|
||||
* calls to this code, and for that purpose includes it by reference shall be
|
||||
* deemed a separate work for copyright law purposes. In addition, the copyright
|
||||
* holders of this code give you permission to combine this code with free
|
||||
* software libraries that are released under the GNU LGPL. You may copy and
|
||||
* distribute such a system following the terms of the GNU AGPL for this code
|
||||
* and the LGPL for the libraries. If you modify this code, you may extend this
|
||||
* exception to your version of the code, but you are not obligated to do so.
|
||||
* If you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
* This license applies to this entire compilation.
|
||||
* @licend
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define,require,document,odf */
|
||||
|
||||
define("webodf/editor/widgets/editHyperlinks", [
|
||||
"webodf/editor/EditorSession",
|
||||
"webodf/editor/widgets/dialogWidgets/editHyperlinkPane",
|
||||
"dijit/form/Button",
|
||||
"dijit/form/DropDownButton",
|
||||
"dijit/TooltipDialog"],
|
||||
|
||||
function (EditorSession, EditHyperlinkPane, Button, DropDownButton, TooltipDialog) {
|
||||
"use strict";
|
||||
|
||||
runtime.loadClass("odf.OdfUtils");
|
||||
|
||||
var EditHyperlinks = function (callback) {
|
||||
var self = this,
|
||||
widget = {},
|
||||
editorSession,
|
||||
hyperlinkController,
|
||||
linkEditorContent,
|
||||
editHyperlinkButton,
|
||||
removeHyperlinkButton,
|
||||
odfUtils = new odf.OdfUtils(),
|
||||
dialog;
|
||||
|
||||
linkEditorContent = new EditHyperlinkPane();
|
||||
dialog = new TooltipDialog({
|
||||
title: runtime.tr("Edit link"),
|
||||
content: linkEditorContent.widget()
|
||||
});
|
||||
|
||||
editHyperlinkButton = new DropDownButton({
|
||||
label: runtime.tr('Edit link'),
|
||||
showLabel: false,
|
||||
iconClass: 'dijitEditorIcon dijitEditorIconCreateLink',
|
||||
dropDown: dialog
|
||||
});
|
||||
|
||||
removeHyperlinkButton = new Button({
|
||||
label: runtime.tr('Remove link'),
|
||||
showLabel: false,
|
||||
disabled: true,
|
||||
iconClass: 'dijitEditorIcon dijitEditorIconUnlink',
|
||||
onClick: function () {
|
||||
hyperlinkController.removeHyperlinks();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
|
||||
linkEditorContent.onSave = function () {
|
||||
var hyperlinkData = linkEditorContent.value();
|
||||
editHyperlinkButton.closeDropDown(false);
|
||||
if (hyperlinkData.isReadOnlyText == "true") {
|
||||
hyperlinkController.removeHyperlinks();
|
||||
hyperlinkController.addHyperlink(hyperlinkData.linkUrl);
|
||||
} else {
|
||||
hyperlinkController.addHyperlink(hyperlinkData.linkUrl, hyperlinkData.linkDisplayText);
|
||||
}
|
||||
self.onToolDone();
|
||||
};
|
||||
|
||||
linkEditorContent.onCancel = function () {
|
||||
editHyperlinkButton.closeDropDown(false);
|
||||
self.onToolDone();
|
||||
};
|
||||
|
||||
widget.children = [editHyperlinkButton, removeHyperlinkButton];
|
||||
widget.startup = function () {
|
||||
widget.children.forEach(function (element) {
|
||||
element.startup();
|
||||
});
|
||||
};
|
||||
|
||||
widget.placeAt = function (container) {
|
||||
widget.children.forEach(function (element) {
|
||||
element.placeAt(container);
|
||||
});
|
||||
return widget;
|
||||
};
|
||||
|
||||
function checkHyperlinkButtons() {
|
||||
var selection = editorSession.getSelectedRange(),
|
||||
textContent,
|
||||
linksInSelection = editorSession.getSelectedHyperlinks(),
|
||||
linkTarget = linksInSelection[0] ? odfUtils.getHyperlinkTarget(linksInSelection[0]) : "http://";
|
||||
|
||||
if (selection && selection.collapsed && linksInSelection.length === 1) {
|
||||
// Selection is collapsed within a single hyperlink. Assume user is modifying the hyperlink
|
||||
textContent = selection.cloneRange();
|
||||
textContent.selectNodeContents(linksInSelection[0]);
|
||||
linkEditorContent.set({
|
||||
linkDisplayText: textContent.toString(),
|
||||
linkUrl: linkTarget,
|
||||
isReadOnlyText: true
|
||||
});
|
||||
textContent.detach();
|
||||
} else if (selection && !selection.collapsed) {
|
||||
// User has selected part of a hyperlink or a block of text. Assume user is attempting to modify the
|
||||
// existing hyperlink, or wants to convert the selection into a hyperlink
|
||||
linkEditorContent.set({
|
||||
linkDisplayText: selection.toString(),
|
||||
linkUrl: linkTarget,
|
||||
isReadOnlyText: true
|
||||
});
|
||||
} else {
|
||||
// Selection is collapsed and is not in an existing hyperlink
|
||||
linkEditorContent.set({
|
||||
linkDisplayText: "",
|
||||
linkUrl: linkTarget,
|
||||
isReadOnlyText: false
|
||||
});
|
||||
}
|
||||
|
||||
// The 3rd parameter is false to avoid firing onChange when setting the value programmatically.
|
||||
removeHyperlinkButton.set('disabled', linksInSelection.length === 0, false);
|
||||
}
|
||||
|
||||
this.setEditorSession = function (session) {
|
||||
if (editorSession) {
|
||||
editorSession.unsubscribe(EditorSession.signalCursorMoved, checkHyperlinkButtons);
|
||||
editorSession.unsubscribe(EditorSession.signalParagraphChanged, checkHyperlinkButtons);
|
||||
editorSession.unsubscribe(EditorSession.signalParagraphStyleModified, checkHyperlinkButtons);
|
||||
}
|
||||
editorSession = session;
|
||||
hyperlinkController = session && session.sessionController.getHyperlinkController();
|
||||
widget.children.forEach(function (element) {
|
||||
element.setAttribute('disabled', !hyperlinkController);
|
||||
});
|
||||
if (editorSession) {
|
||||
editorSession.subscribe(EditorSession.signalCursorMoved, checkHyperlinkButtons);
|
||||
editorSession.subscribe(EditorSession.signalParagraphChanged, checkHyperlinkButtons);
|
||||
editorSession.subscribe(EditorSession.signalParagraphStyleModified, checkHyperlinkButtons);
|
||||
checkHyperlinkButtons();
|
||||
}
|
||||
};
|
||||
|
||||
this.onToolDone = function () {};
|
||||
|
||||
callback(widget);
|
||||
};
|
||||
|
||||
return EditHyperlinks;
|
||||
});
|
@ -50,7 +50,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
var self = this,
|
||||
editorSession,
|
||||
widget = {},
|
||||
directParagraphStyler,
|
||||
directFormattingController,
|
||||
justifyLeft,
|
||||
justifyCenter,
|
||||
justifyRight,
|
||||
@ -65,7 +65,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconJustifyLeft",
|
||||
onChange: function () {
|
||||
directParagraphStyler.alignParagraphLeft();
|
||||
directFormattingController.alignParagraphLeft();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -77,7 +77,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconJustifyCenter",
|
||||
onChange: function () {
|
||||
directParagraphStyler.alignParagraphCenter();
|
||||
directFormattingController.alignParagraphCenter();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -89,7 +89,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconJustifyRight",
|
||||
onChange: function () {
|
||||
directParagraphStyler.alignParagraphRight();
|
||||
directFormattingController.alignParagraphRight();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -101,7 +101,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconJustifyFull",
|
||||
onChange: function () {
|
||||
directParagraphStyler.alignParagraphJustified();
|
||||
directFormattingController.alignParagraphJustified();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -112,7 +112,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
showLabel: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconOutdent",
|
||||
onClick: function () {
|
||||
directParagraphStyler.outdent();
|
||||
directFormattingController.outdent();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -123,7 +123,7 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
showLabel: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconIndent",
|
||||
onClick: function () {
|
||||
directParagraphStyler.indent();
|
||||
directFormattingController.indent();
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -174,21 +174,21 @@ define("webodf/editor/widgets/paragraphAlignment", [
|
||||
}
|
||||
|
||||
this.setEditorSession = function (session) {
|
||||
if (directParagraphStyler) {
|
||||
directParagraphStyler.unsubscribe(gui.DirectParagraphStyler.paragraphStylingChanged, updateStyleButtons);
|
||||
if (directFormattingController) {
|
||||
directFormattingController.unsubscribe(gui.DirectFormattingController.paragraphStylingChanged, updateStyleButtons);
|
||||
}
|
||||
directParagraphStyler = session && session.sessionController.getDirectParagraphStyler();
|
||||
if (directParagraphStyler) {
|
||||
directParagraphStyler.subscribe(gui.DirectParagraphStyler.paragraphStylingChanged, updateStyleButtons);
|
||||
directFormattingController = session && session.sessionController.getDirectFormattingController();
|
||||
if (directFormattingController) {
|
||||
directFormattingController.subscribe(gui.DirectFormattingController.paragraphStylingChanged, updateStyleButtons);
|
||||
}
|
||||
widget.children.forEach(function (element) {
|
||||
element.setAttribute('disabled', !directParagraphStyler);
|
||||
element.setAttribute('disabled', !directFormattingController);
|
||||
});
|
||||
updateStyleButtons({
|
||||
isAlignedLeft: directParagraphStyler ? directParagraphStyler.isAlignedLeft() : false,
|
||||
isAlignedCenter: directParagraphStyler ? directParagraphStyler.isAlignedCenter() : false,
|
||||
isAlignedRight: directParagraphStyler ? directParagraphStyler.isAlignedRight() : false,
|
||||
isAlignedJustified: directParagraphStyler ? directParagraphStyler.isAlignedJustified() : false
|
||||
isAlignedLeft: directFormattingController ? directFormattingController.isAlignedLeft() : false,
|
||||
isAlignedCenter: directFormattingController ? directFormattingController.isAlignedCenter() : false,
|
||||
isAlignedRight: directFormattingController ? directFormattingController.isAlignedRight() : false,
|
||||
isAlignedJustified: directFormattingController ? directFormattingController.isAlignedJustified() : false
|
||||
});
|
||||
|
||||
if (editorSession) {
|
||||
|
@ -51,7 +51,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
var self = this,
|
||||
editorSession,
|
||||
widget = {},
|
||||
directTextStyler,
|
||||
directFormattingController,
|
||||
boldButton,
|
||||
italicButton,
|
||||
underlineButton,
|
||||
@ -67,7 +67,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconBold",
|
||||
onChange: function (checked) {
|
||||
directTextStyler.setBold(checked);
|
||||
directFormattingController.setBold(checked);
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -79,7 +79,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconItalic",
|
||||
onChange: function (checked) {
|
||||
directTextStyler.setItalic(checked);
|
||||
directFormattingController.setItalic(checked);
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -91,7 +91,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconUnderline",
|
||||
onChange: function (checked) {
|
||||
directTextStyler.setHasUnderline(checked);
|
||||
directFormattingController.setHasUnderline(checked);
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -103,7 +103,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
checked: false,
|
||||
iconClass: "dijitEditorIcon dijitEditorIconStrikethrough",
|
||||
onChange: function (checked) {
|
||||
directTextStyler.setHasStrikethrough(checked);
|
||||
directFormattingController.setHasStrikethrough(checked);
|
||||
self.onToolDone();
|
||||
}
|
||||
});
|
||||
@ -117,7 +117,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
constraints: {min:6, max:96},
|
||||
intermediateChanges: true,
|
||||
onChange: function (value) {
|
||||
directTextStyler.setFontSize(value);
|
||||
directFormattingController.setFontSize(value);
|
||||
},
|
||||
onClick: function () {
|
||||
self.onToolDone();
|
||||
@ -134,7 +134,7 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
fontPickerWidget = fontPicker.widget();
|
||||
fontPickerWidget.setAttribute('disabled', true);
|
||||
fontPickerWidget.onChange = function(value) {
|
||||
directTextStyler.setFontName(value);
|
||||
directFormattingController.setFontName(value);
|
||||
self.onToolDone();
|
||||
};
|
||||
|
||||
@ -183,24 +183,24 @@ define("webodf/editor/widgets/simpleStyles", [
|
||||
}
|
||||
|
||||
this.setEditorSession = function(session) {
|
||||
if (directTextStyler) {
|
||||
directTextStyler.unsubscribe(gui.DirectTextStyler.textStylingChanged, updateStyleButtons);
|
||||
if (directFormattingController) {
|
||||
directFormattingController.unsubscribe(gui.DirectFormattingController.textStylingChanged, updateStyleButtons);
|
||||
}
|
||||
directTextStyler = session && session.sessionController.getDirectTextStyler();
|
||||
directFormattingController = session && session.sessionController.getDirectFormattingController();
|
||||
fontPicker.setEditorSession(session);
|
||||
if (directTextStyler) {
|
||||
directTextStyler.subscribe(gui.DirectTextStyler.textStylingChanged, updateStyleButtons);
|
||||
if (directFormattingController) {
|
||||
directFormattingController.subscribe(gui.DirectFormattingController.textStylingChanged, updateStyleButtons);
|
||||
}
|
||||
widget.children.forEach(function (element) {
|
||||
element.setAttribute('disabled', !directTextStyler);
|
||||
element.setAttribute('disabled', !directFormattingController);
|
||||
});
|
||||
updateStyleButtons({
|
||||
isBold: directTextStyler ? directTextStyler.isBold() : false,
|
||||
isItalic: directTextStyler ? directTextStyler.isItalic() : false,
|
||||
hasUnderline: directTextStyler ? directTextStyler.hasUnderline() : false,
|
||||
hasStrikeThrough: directTextStyler ? directTextStyler.hasStrikeThrough() : false,
|
||||
fontSize: directTextStyler ? directTextStyler.fontSize() : undefined,
|
||||
fontName: directTextStyler ? directTextStyler.fontName() : undefined
|
||||
isBold: directFormattingController ? directFormattingController.isBold() : false,
|
||||
isItalic: directFormattingController ? directFormattingController.isItalic() : false,
|
||||
hasUnderline: directFormattingController ? directFormattingController.hasUnderline() : false,
|
||||
hasStrikeThrough: directFormattingController ? directFormattingController.hasStrikeThrough() : false,
|
||||
fontSize: directFormattingController ? directFormattingController.fontSize() : undefined,
|
||||
fontName: directFormattingController ? directFormattingController.fontName() : undefined
|
||||
});
|
||||
|
||||
if (editorSession) {
|
||||
|
@ -39,19 +39,17 @@
|
||||
/*global define,require*/
|
||||
|
||||
define("webodf/editor/widgets/undoRedoMenu",
|
||||
["webodf/editor/EditorSession"],
|
||||
["webodf/editor/EditorSession", "dijit/form/Button"],
|
||||
|
||||
function (EditorSession) {
|
||||
function (EditorSession, Button) {
|
||||
"use strict";
|
||||
|
||||
return function UndoRedoMenu(callback) {
|
||||
var editorSession,
|
||||
var self = this,
|
||||
editorSession,
|
||||
undoButton,
|
||||
redoButton;
|
||||
|
||||
function makeWidget(callback) {
|
||||
require(["dijit/form/Button"], function (Button) {
|
||||
var widget = {};
|
||||
redoButton,
|
||||
widget = {};
|
||||
|
||||
undoButton = new Button({
|
||||
label: runtime.tr('Undo'),
|
||||
@ -61,6 +59,7 @@ define("webodf/editor/widgets/undoRedoMenu",
|
||||
onClick: function () {
|
||||
if (editorSession) {
|
||||
editorSession.undo();
|
||||
self.onToolDone();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -73,6 +72,7 @@ define("webodf/editor/widgets/undoRedoMenu",
|
||||
onClick: function () {
|
||||
if (editorSession) {
|
||||
editorSession.redo();
|
||||
self.onToolDone();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -91,10 +91,6 @@ define("webodf/editor/widgets/undoRedoMenu",
|
||||
return widget;
|
||||
};
|
||||
|
||||
return callback(widget);
|
||||
});
|
||||
}
|
||||
|
||||
function checkUndoButtons(e) {
|
||||
if (undoButton) {
|
||||
undoButton.set('disabled', e.undoAvailable === false);
|
||||
@ -115,9 +111,9 @@ define("webodf/editor/widgets/undoRedoMenu",
|
||||
}
|
||||
};
|
||||
|
||||
this.onToolDone = function () {};
|
||||
|
||||
// init
|
||||
makeWidget(function (widget) {
|
||||
return callback(widget);
|
||||
});
|
||||
callback(widget);
|
||||
};
|
||||
});
|
||||
|
35
js/3rdparty/webodf/editor/widgets/zoomSlider.js
vendored
35
js/3rdparty/webodf/editor/widgets/zoomSlider.js
vendored
@ -38,24 +38,29 @@
|
||||
|
||||
/*global define,require*/
|
||||
|
||||
define("webodf/editor/widgets/zoomSlider", [], function () {
|
||||
define("webodf/editor/widgets/zoomSlider", [
|
||||
"webodf/editor/EditorSession"],
|
||||
function (EditorSession) {
|
||||
"use strict";
|
||||
|
||||
return function ZoomSlider(callback) {
|
||||
var self = this,
|
||||
editorSession,
|
||||
slider;
|
||||
slider,
|
||||
extremeZoomFactor = 4;
|
||||
|
||||
// The slider zooms from -1 to +1, which corresponds
|
||||
// to zoom levels of 1/extremeZoomFactor to extremeZoomFactor.
|
||||
function makeWidget(callback) {
|
||||
require(["dijit/form/HorizontalSlider", "dijit/form/NumberTextBox", "dojo"], function (HorizontalSlider, NumberTextBox, dojo) {
|
||||
var widget = {};
|
||||
|
||||
slider = new HorizontalSlider({
|
||||
name: 'zoomSlider',
|
||||
value: 100,
|
||||
minimum: 30,
|
||||
maximum: 150,
|
||||
discreteValues: 100,
|
||||
value: 0,
|
||||
minimum: -1,
|
||||
maximum: 1,
|
||||
discreteValues: 0.01,
|
||||
intermediateChanges: true,
|
||||
style: {
|
||||
width: '150px',
|
||||
@ -66,7 +71,7 @@ define("webodf/editor/widgets/zoomSlider", [], function () {
|
||||
|
||||
slider.onChange = function (value) {
|
||||
if (editorSession) {
|
||||
editorSession.getOdfCanvas().setZoomLevel(value / 100.0);
|
||||
editorSession.getOdfCanvas().getZoomHelper().setZoomLevel(Math.pow(extremeZoomFactor, value));
|
||||
}
|
||||
self.onToolDone();
|
||||
};
|
||||
@ -75,9 +80,23 @@ define("webodf/editor/widgets/zoomSlider", [], function () {
|
||||
});
|
||||
}
|
||||
|
||||
function updateSlider(zoomLevel) {
|
||||
if (slider) {
|
||||
slider.set('value', Math.log(zoomLevel) / Math.log(extremeZoomFactor), false);
|
||||
}
|
||||
}
|
||||
|
||||
this.setEditorSession = function(session) {
|
||||
var zoomHelper;
|
||||
if (editorSession) {
|
||||
editorSession.getOdfCanvas().getZoomHelper().unsubscribe(gui.ZoomHelper.signalZoomChanged, updateSlider);
|
||||
}
|
||||
editorSession = session;
|
||||
// if (slider) { slider.setValue(editorSession.getOdfCanvas().getZoomLevel() ); TODO!
|
||||
if (editorSession) {
|
||||
zoomHelper = editorSession.getOdfCanvas().getZoomHelper();
|
||||
zoomHelper.subscribe(gui.ZoomHelper.signalZoomChanged, updateSlider);
|
||||
updateSlider(zoomHelper.getZoomLevel());
|
||||
}
|
||||
};
|
||||
|
||||
this.onToolDone = function () {};
|
||||
|
20719
js/3rdparty/webodf/webodf-debug.js
vendored
20719
js/3rdparty/webodf/webodf-debug.js
vendored
File diff suppressed because one or more lines are too long
3160
js/3rdparty/webodf/webodf.js
vendored
3160
js/3rdparty/webodf/webodf.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user