mirror of
https://github.com/antos-rde/antosdk-apps.git
synced 2024-12-26 04:08:21 +01:00
editor control
This commit is contained in:
parent
18e0db7253
commit
a033ea21c5
@ -1,7 +1,36 @@
|
||||
<afx-app-window apptitle="Open Page" width="600" height="500" data-id="OpenPage">
|
||||
<afx-app-window apptitle="Open Page" width="650" height="500" data-id="OpenPage">
|
||||
<afx-hbox >
|
||||
<div data-id="container">
|
||||
<div data-id="odfcanvas"></div>
|
||||
</div>
|
||||
<afx-vbox>
|
||||
<afx-hbox data-id="toolbox" data-height="28">
|
||||
<div data-width="5"></div>
|
||||
<afx-button data-width = "25" data-id="btundo" iconclass = "fa fa-undo"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btredo" iconclass = "fa fa-rotate-right" ></afx-button>
|
||||
<afx-button data-width = "25" data-id="btbold" iconclass = "fa fa-bold"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btitalic" iconclass = "fa fa-italic"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btunderline" iconclass = "fa fa-underline"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btstrike" iconclass = "fa fa-strikethrough"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btnote" iconclass = "fa fa-sticky-note"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btlink" iconclass = "fa fa-link"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btunlink" iconclass = "fa fa-unlink"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btimage" iconclass = "fa fa-image"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btac" iconclass = "fa fa-align-center"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btal" iconclass = "fa fa-align-left" ></afx-button>
|
||||
<afx-button data-width = "25" data-id="btar" iconclass = "fa fa-align-right"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btaj" iconclass = "fa fa-align-justify"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btindent" iconclass = "fa fa-indent"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btoutdent" iconclass = "fa fa-outdent"></afx-button>
|
||||
<afx-list-view dropdown = "true" data-width="80" data-id="format-list"></afx-list-view>
|
||||
<div data-width="5"></div>
|
||||
<afx-nspinner data-width = "50" data-id="font-size" ></afx-nspinner>
|
||||
<div data-width="5"></div>
|
||||
<afx-list-view dropdown = "true" data-width="150" data-id="font-list"></afx-list-view>
|
||||
<div data-width="5"></div>
|
||||
</afx-hbox>
|
||||
<div data-height="5"></div>
|
||||
<div data-id="container">
|
||||
<div data-id="odfcanvas"></div>
|
||||
</div>
|
||||
</afx-vbox>
|
||||
|
||||
</afx-hbox>
|
||||
</afx-app-window>
|
@ -2,6 +2,42 @@
|
||||
afx-app-window[data-id="OpenPage"] div[data-id="container"]
|
||||
{
|
||||
overflow: auto;
|
||||
margin:0 auto;
|
||||
padding:0px
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
background-color: #f2f1f0;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="OpenPage"] div[data-id="odfcanvas"]
|
||||
{
|
||||
cursor: text;
|
||||
margin:auto;
|
||||
box-shadow: 1px 1px 3px 3px #9f9F9F;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"]
|
||||
{
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 3px 3px 3px #9f9F9F;
|
||||
}
|
||||
afx-app-window[data-id="HyperLinkDialog"] afx-label.header span
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button{
|
||||
border: 1px solid #f5f5f5;
|
||||
background-color: transparent;
|
||||
width:100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button:hover, afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button.btactive button
|
||||
{
|
||||
border: 1px solid #759DC0;
|
||||
background-color: transparent;
|
||||
border-radius:5px;
|
||||
color:#759DC0;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var OpenPage;
|
||||
var HyperLinkDialog, OpenPage;
|
||||
|
||||
OpenPage = class OpenPage extends this.OS.GUI.BaseApplication {
|
||||
constructor(args) {
|
||||
@ -7,19 +7,89 @@
|
||||
}
|
||||
|
||||
main() {
|
||||
var el, me, userid;
|
||||
// load session class
|
||||
if (!OpenPage.editorSession) {
|
||||
require(["webodf/editor/EditorSession"], function(ES) {
|
||||
return OpenPage.EditorSession = ES;
|
||||
});
|
||||
}
|
||||
this.eventSubscriptions = new core.EventSubscriptions();
|
||||
this.initToolbox();
|
||||
this.initCanvas();
|
||||
return this.canvas.load(`${this._api.handler.get}/home://welcome.odt`);
|
||||
}
|
||||
|
||||
initToolbox() {
|
||||
var el, fn, me, name, ref, results;
|
||||
me = this;
|
||||
this.basictool = {
|
||||
undo: this.find("btundo"),
|
||||
redo: this.find("btredo"),
|
||||
bold: this.find("btbold"),
|
||||
italic: this.find("btitalic"),
|
||||
underline: this.find("btunderline"),
|
||||
strike: this.find("btstrike"),
|
||||
note: this.find("btnote"),
|
||||
link: this.find("btlink"),
|
||||
unlink: this.find("btunlink"),
|
||||
image: this.find("btimage"),
|
||||
ac: this.find("btac"),
|
||||
al: this.find("btal"),
|
||||
ar: this.find("btar"),
|
||||
aj: this.find("btaj"),
|
||||
indent: this.find("btindent"),
|
||||
outdent: this.find("btoutdent"),
|
||||
fonts: this.find("font-list"),
|
||||
fontsize: this.find("font-size")
|
||||
};
|
||||
fn = function(name, el) {
|
||||
var act;
|
||||
if (name === "fonts") {
|
||||
act = "onlistselect";
|
||||
} else if (name === "fontsize") {
|
||||
act = "onchange";
|
||||
} else {
|
||||
act = "onbtclick";
|
||||
}
|
||||
return el.set(act, function(e) {
|
||||
if (!me.directFormattingCtl) {
|
||||
return;
|
||||
}
|
||||
if (!me[name]) {
|
||||
return;
|
||||
}
|
||||
me[name](e);
|
||||
return me.editorFocus();
|
||||
});
|
||||
};
|
||||
ref = this.basictool;
|
||||
results = [];
|
||||
for (name in ref) {
|
||||
el = ref[name];
|
||||
results.push(fn(name, el));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
initCanvas() {
|
||||
var el, me;
|
||||
el = this.find("odfcanvas");
|
||||
me = this;
|
||||
el.setAttribute("translate", "no");
|
||||
el.classList.add("notranslate");
|
||||
this.eventNotifier = new core.EventNotifier(["unknown-error", "documentModifiedChanged", "metadataChanged"]);
|
||||
userid = "localuser";
|
||||
require(["webodf/editor/EditorSession"], function(ES) {
|
||||
return OpenPage.EditorSession = ES;
|
||||
});
|
||||
this.userid = "localuser";
|
||||
this.canvas = new odf.OdfCanvas(el);
|
||||
this.documentChanged = function(e) {
|
||||
return console.log(e);
|
||||
};
|
||||
this.metaChanged = function(e) {
|
||||
return console.log(e);
|
||||
};
|
||||
this.textStylingChanged = function(e) {
|
||||
return me.updateToolbar(e);
|
||||
};
|
||||
//@canvas.enableAnnotations(true, true)
|
||||
this.canvas.addListener("statereadychange", function() {
|
||||
return this.canvas.addListener("statereadychange", function() {
|
||||
var op, viewOptions;
|
||||
me.session = new ops.Session(me.canvas);
|
||||
viewOptions = {
|
||||
@ -27,7 +97,7 @@
|
||||
caretAvatarsInitiallyVisible: false,
|
||||
caretBlinksOnRangeSelect: true
|
||||
};
|
||||
me.editorSession = new OpenPage.EditorSession(me.session, userid, {
|
||||
me.editorSession = new OpenPage.EditorSession(me.session, me.userid, {
|
||||
viewOptions: viewOptions,
|
||||
directTextStylingEnabled: true,
|
||||
directParagraphStylingEnabled: true,
|
||||
@ -39,36 +109,331 @@
|
||||
zoomingEnabled: true,
|
||||
reviewModeEnabled: false
|
||||
});
|
||||
// basic format
|
||||
me.directFormattingCtl = me.editorSession.sessionController.getDirectFormattingController();
|
||||
me.directFormattingCtl.subscribe(gui.DirectFormattingController.textStylingChanged, me.textStylingChanged);
|
||||
me.directFormattingCtl.subscribe(gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged);
|
||||
// hyper link controller
|
||||
me.hyperlinkController = me.editorSession.sessionController.getHyperlinkController();
|
||||
me.eventSubscriptions.addFrameSubscription(me.editorSession, OpenPage.EditorSession.signalCursorMoved, function() {
|
||||
return me.updateHyperlinkButtons();
|
||||
});
|
||||
me.eventSubscriptions.addFrameSubscription(me.editorSession, OpenPage.EditorSession.signalParagraphChanged, function() {
|
||||
return me.updateHyperlinkButtons();
|
||||
});
|
||||
me.eventSubscriptions.addFrameSubscription(me.editorSession, OpenPage.EditorSession.signalParagraphStyleModified, function() {
|
||||
return me.updateHyperlinkButtons();
|
||||
});
|
||||
me.editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager());
|
||||
me.editorSession.sessionController.getUndoManager().subscribe(gui.UndoManager.signalDocumentModifiedChanged, function(mod) {
|
||||
return me.eventNotifier.emit("documentModifiedChanged", mod);
|
||||
});
|
||||
me.editorSession.sessionController.getMetadataController().subscribe(gui.MetadataController.signalMetadataChanged, function(changes) {
|
||||
return me.eventNotifier.emit("metadataChanged", changes);
|
||||
});
|
||||
me.editorSession.sessionController.getUndoManager().subscribe(gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged);
|
||||
me.editorSession.sessionController.getMetadataController().subscribe(gui.MetadataController.signalMetadataChanged, me.metaChanged);
|
||||
op = new ops.OpAddMember();
|
||||
op.init({
|
||||
memberid: userid,
|
||||
memberid: me.userid,
|
||||
setProperties: {
|
||||
"fullName": "Xuan Sang LE",
|
||||
"color": "blue"
|
||||
}
|
||||
});
|
||||
me.session.enqueue([op]);
|
||||
me.initFontList(me.editorSession.getDeclaredFonts());
|
||||
me.editorSession.sessionController.insertLocalCursor();
|
||||
me.editorSession.sessionController.startEditing();
|
||||
return me.editorSession.sessionController.getEventManager().focus();
|
||||
return me.editorSession.sessionController.startEditing();
|
||||
});
|
||||
this.canvas.load(`${this._api.handler.get}/home://Downloads/welcome.odt`);
|
||||
return this.eventNotifier.subscribe("documentModifiedChanged", function(d) {
|
||||
return console.log("document is modified");
|
||||
}
|
||||
|
||||
//console.log me.editorSession.getDeclaredFonts()
|
||||
|
||||
initFontList(list) {
|
||||
var j, len, v;
|
||||
for (j = 0, len = list.length; j < len; j++) {
|
||||
v = list[j];
|
||||
v.text = v.name;
|
||||
}
|
||||
return this.basictool.fonts.set("items", list);
|
||||
}
|
||||
|
||||
updateToolbar(changes) {
|
||||
if (changes.hasOwnProperty('isBold')) {
|
||||
// basic style
|
||||
this.basictool.bold.set("selected", changes.isBold);
|
||||
}
|
||||
if (changes.hasOwnProperty('isItalic')) {
|
||||
this.basictool.italic.set("selected", changes.isItalic);
|
||||
}
|
||||
if (changes.hasOwnProperty('hasUnderline')) {
|
||||
this.basictool.underline.set("selected", changes.hasUnderline);
|
||||
}
|
||||
if (changes.hasOwnProperty('hasStrikeThrough')) {
|
||||
this.basictool.strike.set("selected", changes.hasStrikeThrough);
|
||||
}
|
||||
if (changes.hasOwnProperty("fontSize")) {
|
||||
this.basictool.fontsize.set("value", changes.fontSize);
|
||||
}
|
||||
if (changes.hasOwnProperty("fontName")) {
|
||||
this.selectFont(changes.fontName);
|
||||
}
|
||||
if (changes.hasOwnProperty("isAlignedLeft")) {
|
||||
//pharagraph style
|
||||
this.basictool.al.set("selected", changes.isAlignedLeft);
|
||||
}
|
||||
if (changes.hasOwnProperty("isAlignedRight")) {
|
||||
this.basictool.ar.set("selected", changes.isAlignedRight);
|
||||
}
|
||||
if (changes.hasOwnProperty("isAlignedCenter")) {
|
||||
this.basictool.ac.set("selected", changes.isAlignedCenter);
|
||||
}
|
||||
if (changes.hasOwnProperty("isAlignedJustified")) {
|
||||
return this.basictool.aj.set("selected", changes.isAlignedJustified);
|
||||
}
|
||||
}
|
||||
|
||||
updateHyperlinkButtons(e) {
|
||||
var selectedLinks;
|
||||
selectedLinks = this.editorSession.getSelectedHyperlinks();
|
||||
return this.basictool.unlink.set("enable", selectedLinks.length > 0);
|
||||
}
|
||||
|
||||
selectFont(name) {
|
||||
var i, item, items, j, len, v;
|
||||
items = this.basictool.fonts.get("items");
|
||||
for (i = j = 0, len = items.length; j < len; i = ++j) {
|
||||
v = items[i];
|
||||
if (v.name === name) {
|
||||
item = i;
|
||||
}
|
||||
}
|
||||
return this.basictool.fonts.set("selected", item);
|
||||
}
|
||||
|
||||
editorFocus() {
|
||||
return this.editorSession.sessionController.getEventManager().focus();
|
||||
}
|
||||
|
||||
bold(e) {
|
||||
//console.log @, e
|
||||
return this.directFormattingCtl.setBold(!this.basictool.bold.get("selected"));
|
||||
}
|
||||
|
||||
italic(e) {
|
||||
return this.directFormattingCtl.setItalic(!this.basictool.italic.get("selected"));
|
||||
}
|
||||
|
||||
underline(e) {
|
||||
return this.directFormattingCtl.setHasUnderline(!this.basictool.underline.get("selected"));
|
||||
}
|
||||
|
||||
strike(e) {
|
||||
return this.directFormattingCtl.setHasStrikethrough(!this.basictool.strike.get("selected"));
|
||||
}
|
||||
|
||||
fonts(e) {
|
||||
return this.directFormattingCtl.setFontName(e.data.name);
|
||||
}
|
||||
|
||||
fontsize(e) {
|
||||
return this.directFormattingCtl.setFontSize(e);
|
||||
}
|
||||
|
||||
al(e) {
|
||||
return this.directFormattingCtl.alignParagraphLeft();
|
||||
}
|
||||
|
||||
ar(e) {
|
||||
return this.directFormattingCtl.alignParagraphRight();
|
||||
}
|
||||
|
||||
ac(e) {
|
||||
return this.directFormattingCtl.alignParagraphCenter();
|
||||
}
|
||||
|
||||
aj(e) {
|
||||
return this.directFormattingCtl.alignParagraphJustified();
|
||||
}
|
||||
|
||||
indent(e) {
|
||||
return this.directFormattingCtl.indent();
|
||||
}
|
||||
|
||||
outdent(e) {
|
||||
return this.directFormattingCtl.outdent();
|
||||
}
|
||||
|
||||
link(e) {
|
||||
var data, linkTarget, linksInSelection, me, selection, textSerializer;
|
||||
// get the link first
|
||||
me = this;
|
||||
textSerializer = new odf.TextSerializer();
|
||||
selection = this.editorSession.getSelectedRange();
|
||||
linksInSelection = this.editorSession.getSelectedHyperlinks();
|
||||
linkTarget = linksInSelection[0] ? odf.OdfUtils.getHyperlinkTarget(linksInSelection[0]) : "http://";
|
||||
data = {
|
||||
link: linkTarget,
|
||||
text: "",
|
||||
readonly: true,
|
||||
action: "new"
|
||||
};
|
||||
if (selection && selection.collapsed && linksInSelection.length === 1) {
|
||||
// selection is collapsed within a single link
|
||||
// text in this case is read only
|
||||
data.text = textSerializer.writeToString(linksInSelection[0]);
|
||||
data.action = "edit";
|
||||
} else if (selection && !selection.collapsed) {
|
||||
// user select part of link or a block of text
|
||||
// user convert a selection to a link
|
||||
data.text = textSerializer.writeToString(selection.cloneContents());
|
||||
} else {
|
||||
data.readonly = false;
|
||||
}
|
||||
return this.openDialog(new HyperLinkDialog(), function(d) {
|
||||
var selectedLinkRange, selectionController;
|
||||
selectionController = me.editorSession.sessionController.getSelectionController();
|
||||
if (d.readonly) {
|
||||
// edit the existing link
|
||||
if (d.action === "edit") {
|
||||
selectedLinkRange = selection.cloneRange();
|
||||
selectedLinkRange.selectNode(linksInSelection[0]);
|
||||
selectionController.selectRange(selectedLinkRange, true);
|
||||
}
|
||||
me.hyperlinkController.removeHyperlinks();
|
||||
return me.hyperlinkController.addHyperlink(d.link);
|
||||
} else {
|
||||
me.hyperlinkController.addHyperlink(d.link, d.text);
|
||||
linksInSelection = me.editorSession.getSelectedHyperlinks();
|
||||
selectedLinkRange = selection.cloneRange();
|
||||
selectedLinkRange.selectNode(linksInSelection[0]);
|
||||
return selectionController.selectRange(selectedLinkRange, true);
|
||||
}
|
||||
}, "__(Insert/edit link)", data);
|
||||
}
|
||||
|
||||
unlink(e) {
|
||||
return this.hyperlinkController.removeHyperlinks();
|
||||
}
|
||||
|
||||
closeDocument() {
|
||||
var me, op;
|
||||
// finish editing
|
||||
if (!(this.editorSession && this.session)) {
|
||||
return;
|
||||
}
|
||||
me = this;
|
||||
this.eventSubscriptions.unsubscribeAll();
|
||||
this.editorSession.sessionController.endEditing();
|
||||
this.editorSession.sessionController.removeLocalCursor();
|
||||
// remove user
|
||||
op = new ops.OpRemoveMember();
|
||||
op.init({
|
||||
memberid: this.userid
|
||||
});
|
||||
this.session.enqueue([op]);
|
||||
// close the session
|
||||
return this.session.close(function(e) {
|
||||
if (e) {
|
||||
return me.error("Cannot close session " + e);
|
||||
}
|
||||
me.editorSession.sessionController.getMetadataController().unsubscribe(gui.MetadataController.signalMetadataChanged, me.metaChanged);
|
||||
me.editorSession.sessionController.getUndoManager().unsubscribe(gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged);
|
||||
me.directFormattingCtl.unsubscribe(gui.DirectFormattingController.textStylingChanged, me.textStylingChanged);
|
||||
me.directFormattingCtl.unsubscribe(gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged);
|
||||
// destry editorSession
|
||||
return me.editorSession.destroy(function(e) {
|
||||
if (e) {
|
||||
return me.error("Cannot destroy editor session " + e);
|
||||
}
|
||||
me.editorSession = void 0;
|
||||
// destroy session
|
||||
return me.session.destroy(function(e) {
|
||||
if (e) {
|
||||
return me.error("Cannot destroy document session " + e);
|
||||
}
|
||||
core.Async.destroyAll([me.canvas.destroy], function(e) {
|
||||
if (e) {
|
||||
return me.error("Cannot destroy canvas" + e);
|
||||
}
|
||||
return me.notify("Document closed");
|
||||
});
|
||||
me.session = void 0;
|
||||
return me.directFormattingCtl = void 0;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
cleanup(e) {
|
||||
return this.closeDocument();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.OS.register("OpenPage", OpenPage);
|
||||
|
||||
HyperLinkDialog = class HyperLinkDialog extends this.OS.GUI.BasicDialog {
|
||||
constructor() {
|
||||
super("HyperLinkDialog", {
|
||||
tags: [
|
||||
{
|
||||
tag: "afx-label",
|
||||
att: 'text="__(Text)" data-height="23" class="header"'
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
att: 'data-height="30"'
|
||||
},
|
||||
{
|
||||
tag: "afx-label",
|
||||
att: 'text="__(Link)" data-height="23" class="header"'
|
||||
},
|
||||
{
|
||||
tag: "input",
|
||||
att: 'data-height="30"'
|
||||
},
|
||||
{
|
||||
tag: "div",
|
||||
att: ' data-height="5"'
|
||||
}
|
||||
],
|
||||
width: 350,
|
||||
height: 150,
|
||||
resizable: false,
|
||||
buttons: [
|
||||
{
|
||||
label: "Ok",
|
||||
onclick: function(d) {
|
||||
var data;
|
||||
data = {
|
||||
text: (d.find("content1")).value,
|
||||
link: (d.find("content3")).value,
|
||||
readonly: d.data.readonly,
|
||||
action: d.data.action
|
||||
};
|
||||
if (d.handler) {
|
||||
d.handler(data);
|
||||
}
|
||||
return d.quit();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "__(Cancel)",
|
||||
onclick: function(d) {
|
||||
return d.quit();
|
||||
}
|
||||
}
|
||||
],
|
||||
filldata: function(d) {
|
||||
if (!d.data) {
|
||||
return;
|
||||
}
|
||||
(d.find("content1")).value = d.data.text;
|
||||
(d.find("content3")).value = d.data.link;
|
||||
return $(d.find("content1")).prop('disabled', d.data.readonly);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
/*
|
||||
|
@ -1,7 +1,36 @@
|
||||
<afx-app-window apptitle="Open Page" width="600" height="500" data-id="OpenPage">
|
||||
<afx-app-window apptitle="Open Page" width="650" height="500" data-id="OpenPage">
|
||||
<afx-hbox >
|
||||
<div data-id="container">
|
||||
<div data-id="odfcanvas"></div>
|
||||
</div>
|
||||
<afx-vbox>
|
||||
<afx-hbox data-id="toolbox" data-height="28">
|
||||
<div data-width="5"></div>
|
||||
<afx-button data-width = "25" data-id="btundo" iconclass = "fa fa-undo"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btredo" iconclass = "fa fa-rotate-right" ></afx-button>
|
||||
<afx-button data-width = "25" data-id="btbold" iconclass = "fa fa-bold"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btitalic" iconclass = "fa fa-italic"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btunderline" iconclass = "fa fa-underline"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btstrike" iconclass = "fa fa-strikethrough"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btnote" iconclass = "fa fa-sticky-note"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btlink" iconclass = "fa fa-link"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btunlink" iconclass = "fa fa-unlink"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btimage" iconclass = "fa fa-image"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btac" iconclass = "fa fa-align-center"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btal" iconclass = "fa fa-align-left" ></afx-button>
|
||||
<afx-button data-width = "25" data-id="btar" iconclass = "fa fa-align-right"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btaj" iconclass = "fa fa-align-justify"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btindent" iconclass = "fa fa-indent"></afx-button>
|
||||
<afx-button data-width = "25" data-id="btoutdent" iconclass = "fa fa-outdent"></afx-button>
|
||||
<afx-list-view dropdown = "true" data-width="80" data-id="format-list"></afx-list-view>
|
||||
<div data-width="5"></div>
|
||||
<afx-nspinner data-width = "50" data-id="font-size" ></afx-nspinner>
|
||||
<div data-width="5"></div>
|
||||
<afx-list-view dropdown = "true" data-width="150" data-id="font-list"></afx-list-view>
|
||||
<div data-width="5"></div>
|
||||
</afx-hbox>
|
||||
<div data-height="5"></div>
|
||||
<div data-id="container">
|
||||
<div data-id="odfcanvas"></div>
|
||||
</div>
|
||||
</afx-vbox>
|
||||
|
||||
</afx-hbox>
|
||||
</afx-app-window>
|
32
OpenPage/coffees/dialogs.coffee
Normal file
32
OpenPage/coffees/dialogs.coffee
Normal file
@ -0,0 +1,32 @@
|
||||
class HyperLinkDialog extends this.OS.GUI.BasicDialog
|
||||
constructor: () ->
|
||||
super "HyperLinkDialog", {
|
||||
tags: [
|
||||
{ tag: "afx-label", att: 'text="__(Text)" data-height="23" class="header"' },
|
||||
{ tag: "input", att: 'data-height="30"' },
|
||||
{ tag: "afx-label", att: 'text="__(Link)" data-height="23" class="header"' },
|
||||
{ tag: "input", att: 'data-height="30"' },
|
||||
{ tag: "div", att: ' data-height="5"' }
|
||||
],
|
||||
width: 350,
|
||||
height: 150,
|
||||
resizable: false,
|
||||
buttons: [
|
||||
{
|
||||
label: "Ok", onclick: (d) ->
|
||||
data =
|
||||
text: (d.find "content1").value,
|
||||
link: (d.find "content3").value,
|
||||
readonly: d.data.readonly,
|
||||
action: d.data.action
|
||||
d.handler data if d.handler
|
||||
d.quit()
|
||||
},
|
||||
{ label: "__(Cancel)", onclick: (d) -> d.quit() }
|
||||
],
|
||||
filldata: (d) ->
|
||||
return unless d.data
|
||||
(d.find "content1").value = d.data.text
|
||||
(d.find "content3").value = d.data.link
|
||||
$(d.find "content1").prop('disabled', d.data.readonly)
|
||||
}
|
@ -3,19 +3,64 @@ class OpenPage extends this.OS.GUI.BaseApplication
|
||||
super "OpenPage", args
|
||||
|
||||
main: () ->
|
||||
# load session class
|
||||
if not OpenPage.editorSession
|
||||
require ["webodf/editor/EditorSession"], (ES) ->
|
||||
OpenPage.EditorSession = ES
|
||||
@eventSubscriptions = new core.EventSubscriptions()
|
||||
@initToolbox()
|
||||
@initCanvas()
|
||||
@canvas.load "#{@_api.handler.get}/home://welcome.odt"
|
||||
|
||||
initToolbox: () ->
|
||||
me = @
|
||||
@basictool =
|
||||
undo: @find("btundo"),
|
||||
redo: @find("btredo"),
|
||||
bold: @find("btbold"),
|
||||
italic:@find("btitalic"),
|
||||
underline:@find("btunderline"),
|
||||
strike: @find("btstrike"),
|
||||
note: @find("btnote"),
|
||||
link: @find("btlink"),
|
||||
unlink: @find("btunlink"),
|
||||
image:@find("btimage"),
|
||||
ac: @find("btac"),
|
||||
al: @find("btal"),
|
||||
ar: @find("btar"),
|
||||
aj: @find("btaj"),
|
||||
indent: @find("btindent"),
|
||||
outdent: @find("btoutdent"),
|
||||
fonts: @find("font-list"),
|
||||
fontsize: @find("font-size")
|
||||
fn = (name, el) ->
|
||||
if name is "fonts"
|
||||
act = "onlistselect"
|
||||
else if name is "fontsize"
|
||||
act = "onchange"
|
||||
else
|
||||
act = "onbtclick"
|
||||
el.set act, (e) ->
|
||||
return unless me.directFormattingCtl
|
||||
return unless me[name]
|
||||
me[name](e)
|
||||
me.editorFocus()
|
||||
for name, el of @basictool
|
||||
fn name, el
|
||||
|
||||
initCanvas: () ->
|
||||
el = @find "odfcanvas"
|
||||
me = @
|
||||
el.setAttribute "translate", "no"
|
||||
el.classList.add "notranslate"
|
||||
@eventNotifier = new core.EventNotifier [
|
||||
"unknown-error",
|
||||
"documentModifiedChanged",
|
||||
"metadataChanged"
|
||||
]
|
||||
userid = "localuser"
|
||||
require ["webodf/editor/EditorSession"], (ES) ->
|
||||
OpenPage.EditorSession = ES
|
||||
@userid = "localuser"
|
||||
@canvas = new odf.OdfCanvas(el)
|
||||
@documentChanged = (e) ->
|
||||
console.log e
|
||||
@metaChanged = (e) ->
|
||||
console.log e
|
||||
@textStylingChanged = (e) ->
|
||||
me.updateToolbar e
|
||||
#@canvas.enableAnnotations(true, true)
|
||||
@canvas.addListener "statereadychange", ()->
|
||||
me.session = new ops.Session(me.canvas)
|
||||
@ -24,7 +69,7 @@ class OpenPage extends this.OS.GUI.BaseApplication
|
||||
caretAvatarsInitiallyVisible: false,
|
||||
caretBlinksOnRangeSelect: true
|
||||
|
||||
me.editorSession = new OpenPage.EditorSession(me.session,userid, {
|
||||
me.editorSession = new OpenPage.EditorSession(me.session,me.userid, {
|
||||
viewOptions: viewOptions,
|
||||
directTextStylingEnabled: true,
|
||||
directParagraphStylingEnabled: true,
|
||||
@ -36,25 +81,181 @@ class OpenPage extends this.OS.GUI.BaseApplication
|
||||
zoomingEnabled: true,
|
||||
reviewModeEnabled: false
|
||||
})
|
||||
# basic format
|
||||
me.directFormattingCtl = me.editorSession.sessionController.getDirectFormattingController()
|
||||
me.directFormattingCtl.subscribe gui.DirectFormattingController.textStylingChanged, me.textStylingChanged
|
||||
me.directFormattingCtl.subscribe gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged
|
||||
# hyper link controller
|
||||
me.hyperlinkController = me.editorSession.sessionController.getHyperlinkController()
|
||||
me.eventSubscriptions.addFrameSubscription me.editorSession, OpenPage.EditorSession.signalCursorMoved, ()-> me.updateHyperlinkButtons()
|
||||
me.eventSubscriptions.addFrameSubscription me.editorSession, OpenPage.EditorSession.signalParagraphChanged, ()-> me.updateHyperlinkButtons()
|
||||
me.eventSubscriptions.addFrameSubscription me.editorSession, OpenPage.EditorSession.signalParagraphStyleModified, ()-> me.updateHyperlinkButtons()
|
||||
|
||||
me.editorSession.sessionController.setUndoManager new gui.TrivialUndoManager()
|
||||
me.editorSession.sessionController.getUndoManager().subscribe gui.UndoManager.signalDocumentModifiedChanged, (mod) ->
|
||||
me.eventNotifier.emit "documentModifiedChanged", mod
|
||||
me.editorSession.sessionController.getMetadataController().subscribe gui.MetadataController.signalMetadataChanged, (changes) ->
|
||||
me.eventNotifier.emit "metadataChanged", changes
|
||||
me.editorSession.sessionController.getUndoManager().subscribe gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged
|
||||
me.editorSession.sessionController.getMetadataController().subscribe gui.MetadataController.signalMetadataChanged, me.metaChanged
|
||||
op = new ops.OpAddMember()
|
||||
op.init {
|
||||
memberid: userid,
|
||||
memberid: me.userid,
|
||||
setProperties:{
|
||||
"fullName": "Xuan Sang LE",
|
||||
"color": "blue"
|
||||
}
|
||||
}
|
||||
me.session.enqueue([op])
|
||||
me.initFontList me.editorSession.getDeclaredFonts()
|
||||
me.editorSession.sessionController.insertLocalCursor()
|
||||
me.editorSession.sessionController.startEditing()
|
||||
me.editorSession.sessionController.getEventManager().focus()
|
||||
@canvas.load "#{@_api.handler.get}/home://Downloads/welcome.odt"
|
||||
@eventNotifier.subscribe "documentModifiedChanged", (d) ->
|
||||
console.log "document is modified"
|
||||
#console.log me.editorSession.getDeclaredFonts()
|
||||
#
|
||||
|
||||
initFontList: (list) ->
|
||||
v.text = v.name for v in list
|
||||
@basictool.fonts.set "items", list
|
||||
|
||||
updateToolbar: (changes) ->
|
||||
# basic style
|
||||
(@basictool.bold.set "selected", changes.isBold) if changes.hasOwnProperty 'isBold'
|
||||
(@basictool.italic.set "selected", changes.isItalic) if changes.hasOwnProperty 'isItalic'
|
||||
(@basictool.underline.set "selected", changes.hasUnderline) if changes.hasOwnProperty 'hasUnderline'
|
||||
(@basictool.strike.set "selected", changes.hasStrikeThrough) if changes.hasOwnProperty 'hasStrikeThrough'
|
||||
(@basictool.fontsize.set "value", changes.fontSize) if changes.hasOwnProperty "fontSize"
|
||||
@selectFont changes.fontName if changes.hasOwnProperty "fontName"
|
||||
#pharagraph style
|
||||
@basictool.al.set "selected", changes.isAlignedLeft if changes.hasOwnProperty "isAlignedLeft"
|
||||
@basictool.ar.set "selected", changes.isAlignedRight if changes.hasOwnProperty "isAlignedRight"
|
||||
@basictool.ac.set "selected", changes.isAlignedCenter if changes.hasOwnProperty "isAlignedCenter"
|
||||
@basictool.aj.set "selected", changes.isAlignedJustified if changes.hasOwnProperty "isAlignedJustified"
|
||||
|
||||
updateHyperlinkButtons: (e) ->
|
||||
selectedLinks = @editorSession.getSelectedHyperlinks()
|
||||
@basictool.unlink.set "enable", selectedLinks.length > 0
|
||||
|
||||
selectFont: (name) ->
|
||||
items = @basictool.fonts.get "items"
|
||||
item = i for v, i in items when v.name is name
|
||||
@basictool.fonts.set "selected", item
|
||||
|
||||
editorFocus: () ->
|
||||
@editorSession.sessionController.getEventManager().focus()
|
||||
|
||||
bold: (e) ->
|
||||
#console.log @, e
|
||||
@directFormattingCtl.setBold (not @basictool.bold.get "selected")
|
||||
|
||||
italic: (e) ->
|
||||
@directFormattingCtl.setItalic (not @basictool.italic.get "selected")
|
||||
|
||||
underline: (e) ->
|
||||
@directFormattingCtl.setHasUnderline (not @basictool.underline.get "selected")
|
||||
|
||||
strike: (e) ->
|
||||
@directFormattingCtl.setHasStrikethrough (not @basictool.strike.get "selected")
|
||||
|
||||
fonts: (e) ->
|
||||
@directFormattingCtl.setFontName e.data.name
|
||||
|
||||
fontsize: (e) ->
|
||||
@directFormattingCtl.setFontSize e
|
||||
|
||||
al: (e) ->
|
||||
@directFormattingCtl.alignParagraphLeft()
|
||||
|
||||
ar: (e) ->
|
||||
@directFormattingCtl.alignParagraphRight()
|
||||
|
||||
ac: (e) ->
|
||||
@directFormattingCtl.alignParagraphCenter()
|
||||
|
||||
aj: (e) ->
|
||||
@directFormattingCtl.alignParagraphJustified()
|
||||
|
||||
indent: (e) ->
|
||||
@directFormattingCtl.indent()
|
||||
|
||||
outdent: (e) ->
|
||||
@directFormattingCtl.outdent()
|
||||
|
||||
link: (e) ->
|
||||
# get the link first
|
||||
me = @
|
||||
textSerializer = new odf.TextSerializer()
|
||||
selection = @editorSession.getSelectedRange()
|
||||
linksInSelection = @editorSession.getSelectedHyperlinks()
|
||||
linkTarget = if linksInSelection[0] then odf.OdfUtils.getHyperlinkTarget(linksInSelection[0]) else "http://"
|
||||
data =
|
||||
link: linkTarget,
|
||||
text: "",
|
||||
readonly: true,
|
||||
action: "new"
|
||||
if selection and selection.collapsed and linksInSelection.length == 1
|
||||
# selection is collapsed within a single link
|
||||
# text in this case is read only
|
||||
data.text = textSerializer.writeToString linksInSelection[0]
|
||||
data.action = "edit"
|
||||
else if selection and !selection.collapsed
|
||||
# user select part of link or a block of text
|
||||
# user convert a selection to a link
|
||||
data.text = textSerializer.writeToString selection.cloneContents()
|
||||
else
|
||||
data.readonly = false
|
||||
@openDialog new HyperLinkDialog(), (d) ->
|
||||
selectionController = me.editorSession.sessionController.getSelectionController()
|
||||
if d.readonly
|
||||
# edit the existing link
|
||||
if d.action is "edit"
|
||||
selectedLinkRange = selection.cloneRange()
|
||||
selectedLinkRange.selectNode(linksInSelection[0])
|
||||
selectionController.selectRange(selectedLinkRange, true)
|
||||
me.hyperlinkController.removeHyperlinks()
|
||||
me.hyperlinkController.addHyperlink d.link
|
||||
else
|
||||
me.hyperlinkController.addHyperlink d.link, d.text
|
||||
linksInSelection = me.editorSession.getSelectedHyperlinks()
|
||||
selectedLinkRange = selection.cloneRange()
|
||||
selectedLinkRange.selectNode(linksInSelection[0])
|
||||
selectionController.selectRange(selectedLinkRange, true)
|
||||
, "__(Insert/edit link)", data
|
||||
|
||||
unlink: (e) ->
|
||||
@hyperlinkController.removeHyperlinks()
|
||||
|
||||
closeDocument: () ->
|
||||
# finish editing
|
||||
return unless @editorSession and @session
|
||||
me = @
|
||||
@eventSubscriptions.unsubscribeAll()
|
||||
@editorSession.sessionController.endEditing()
|
||||
@editorSession.sessionController.removeLocalCursor()
|
||||
# remove user
|
||||
op = new ops.OpRemoveMember()
|
||||
op.init {
|
||||
memberid: @userid
|
||||
}
|
||||
@session.enqueue [op]
|
||||
# close the session
|
||||
@session.close (e) ->
|
||||
return (me.error "Cannot close session " + e) if e
|
||||
me.editorSession.sessionController.getMetadataController().unsubscribe gui.MetadataController.signalMetadataChanged, me.metaChanged
|
||||
me.editorSession.sessionController.getUndoManager().unsubscribe gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged
|
||||
me.directFormattingCtl.unsubscribe gui.DirectFormattingController.textStylingChanged, me.textStylingChanged
|
||||
me.directFormattingCtl.unsubscribe gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged
|
||||
# destry editorSession
|
||||
me.editorSession.destroy (e) ->
|
||||
return (me.error "Cannot destroy editor session " + e) if e
|
||||
me.editorSession = undefined
|
||||
# destroy session
|
||||
me.session.destroy (e) ->
|
||||
return (me.error "Cannot destroy document session " + e) if e
|
||||
core.Async.destroyAll [me.canvas.destroy], (e) ->
|
||||
return me.error "Cannot destroy canvas" + e if e
|
||||
me.notify "Document closed"
|
||||
me.session = undefined
|
||||
me.directFormattingCtl = undefined
|
||||
#
|
||||
|
||||
|
||||
cleanup: (e) ->
|
||||
@closeDocument()
|
||||
|
||||
this.OS.register "OpenPage", OpenPage
|
@ -1,6 +1,42 @@
|
||||
afx-app-window[data-id="OpenPage"] div[data-id="container"]
|
||||
{
|
||||
overflow: auto;
|
||||
margin:0 auto;
|
||||
padding:0px
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
text-align: center;
|
||||
background-color: #f2f1f0;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="OpenPage"] div[data-id="odfcanvas"]
|
||||
{
|
||||
cursor: text;
|
||||
margin:auto;
|
||||
box-shadow: 1px 1px 3px 3px #9f9F9F;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"]
|
||||
{
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 3px 3px 3px #9f9F9F;
|
||||
}
|
||||
afx-app-window[data-id="HyperLinkDialog"] afx-label.header span
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button{
|
||||
border: 1px solid #f5f5f5;
|
||||
background-color: transparent;
|
||||
width:100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button:hover, afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button.btactive button
|
||||
{
|
||||
border: 1px solid #759DC0;
|
||||
background-color: transparent;
|
||||
border-radius:5px;
|
||||
color:#759DC0;
|
||||
}
|
@ -1 +1 @@
|
||||
{"name":"OpenPage","root":"home://Documents/workspace/antosdk-apps/OpenPage","css":["css/main.css"],"javascripts":["javascripts/webodf.js","javascripts/EditorSession.js"],"coffees":["coffees/main.coffee"],"copies":["assets/scheme.html","package.json","README.md"]}
|
||||
{"name":"OpenPage","root":"home://myws/antosdk-apps/OpenPage","css":["css/main.css"],"javascripts":["javascripts/webodf.js","javascripts/EditorSession.js"],"coffees":["coffees/main.coffee","coffees/dialogs.coffee"],"copies":["assets/scheme.html","package.json","README.md"]}
|
Loading…
Reference in New Issue
Block a user