webodf update
This commit is contained in:
parent
86952308ce
commit
3deb473927
@ -58,8 +58,9 @@ html, body, #mainContainer {
|
|||||||
-webkit-transform-origin: top center;
|
-webkit-transform-origin: top center;
|
||||||
-moz-transform-origin: top center;
|
-moz-transform-origin: top center;
|
||||||
-o-transform-origin: top center;
|
-o-transform-origin: top center;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#collaboration {
|
#collaboration {
|
||||||
@ -87,7 +88,7 @@ html, body, #mainContainer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#people {
|
#members {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -120,14 +121,14 @@ html, body, #mainContainer {
|
|||||||
box-shadow: 0px 0px 15px red;
|
box-shadow: 0px 0px 15px red;
|
||||||
}
|
}
|
||||||
|
|
||||||
#people > #nameInfo {
|
#members > #nameInfo {
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
padding-bottom: 3px;
|
padding-bottom: 3px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #eef;
|
background-color: #eef;
|
||||||
}
|
}
|
||||||
|
|
||||||
#peopleList .userListButton {
|
#memberList .memberListButton {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@ -141,7 +142,7 @@ html, body, #mainContainer {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#peopleList .userListLabel {
|
#memberList .memberListLabel {
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
@ -149,11 +150,11 @@ html, body, #mainContainer {
|
|||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
text-align: center justify;
|
text-align: center justify;
|
||||||
}
|
}
|
||||||
div.userListLabel[fullname]:before {
|
div.memberListLabel[fullname]:before {
|
||||||
content: attr(fullname) "";
|
content: attr(fullname) "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#peopleList img {
|
#memberList img {
|
||||||
box-shadow: 0px 0px 5px rgb(90, 90, 90) inset;
|
box-shadow: 0px 0px 5px rgb(90, 90, 90) inset;
|
||||||
background-color: rgb(200, 200, 200);
|
background-color: rgb(200, 200, 200);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@ -164,7 +165,7 @@ div.userListLabel[fullname]:before {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#peopleList img:hover {
|
#memberList img:hover {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,3 +315,4 @@ cursor div:after {
|
|||||||
top: 100%;
|
top: 100%;
|
||||||
left: 43%;
|
left: 43%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@
|
|||||||
define("webodf/editor/Editor", [
|
define("webodf/editor/Editor", [
|
||||||
"dojo/i18n!webodf/editor/nls/myResources",
|
"dojo/i18n!webodf/editor/nls/myResources",
|
||||||
"webodf/editor/EditorSession",
|
"webodf/editor/EditorSession",
|
||||||
"webodf/editor/UserList",
|
"webodf/editor/MemberList",
|
||||||
"dijit/layout/BorderContainer",
|
"dijit/layout/BorderContainer",
|
||||||
"dijit/layout/ContentPane",
|
"dijit/layout/ContentPane",
|
||||||
"webodf/editor/widgets"],
|
"webodf/editor/widgets"],
|
||||||
|
|
||||||
function (myResources,
|
function (myResources,
|
||||||
EditorSession,
|
EditorSession,
|
||||||
UserList,
|
MemberList,
|
||||||
BorderContainer,
|
BorderContainer,
|
||||||
ContentPane,
|
ContentPane,
|
||||||
loadWidgets) {
|
loadWidgets) {
|
||||||
@ -52,7 +52,7 @@ define("webodf/editor/Editor", [
|
|||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {{networked:boolean=,
|
* @param {{networked:boolean=,
|
||||||
* memberid:string=,
|
* memberid:!string,
|
||||||
* loadCallback:function()=,
|
* loadCallback:function()=,
|
||||||
* saveCallback:function()=,
|
* saveCallback:function()=,
|
||||||
* cursorAddedCallback:function(!string)=,
|
* cursorAddedCallback:function(!string)=,
|
||||||
@ -65,14 +65,13 @@ define("webodf/editor/Editor", [
|
|||||||
|
|
||||||
var self = this,
|
var self = this,
|
||||||
// Private
|
// Private
|
||||||
userid,
|
|
||||||
memberid = args.memberid,
|
memberid = args.memberid,
|
||||||
session,
|
session,
|
||||||
editorSession,
|
editorSession,
|
||||||
userList,
|
memberList,
|
||||||
networked = args.networked === true,
|
networked = args.networked === true,
|
||||||
opRouter,
|
opRouter,
|
||||||
userModel,
|
memberModel,
|
||||||
loadOdtFile = args.loadCallback,
|
loadOdtFile = args.loadCallback,
|
||||||
saveOdtFile = args.saveCallback,
|
saveOdtFile = args.saveCallback,
|
||||||
cursorAddedHandler = args.cursorAddedCallback,
|
cursorAddedHandler = args.cursorAddedCallback,
|
||||||
@ -99,17 +98,17 @@ define("webodf/editor/Editor", [
|
|||||||
*/
|
*/
|
||||||
function initGuiAndDoc(initialDocumentUrl, editorReadyCallback) {
|
function initGuiAndDoc(initialDocumentUrl, editorReadyCallback) {
|
||||||
var odfElement, mainContainer,
|
var odfElement, mainContainer,
|
||||||
editorPane, peoplePane,
|
editorPane, memberListPane,
|
||||||
inviteButton,
|
inviteButton,
|
||||||
viewOptions = {
|
viewOptions = {
|
||||||
editInfoMarkersInitiallyVisible: networked,
|
editInfoMarkersInitiallyVisible: networked,
|
||||||
caretAvatarsInitiallyVisible: networked,
|
caretAvatarsInitiallyVisible: networked,
|
||||||
caretBlinksOnRangeSelect: true
|
caretBlinksOnRangeSelect: true
|
||||||
},
|
},
|
||||||
peopleListDiv = document.getElementById('peopleList');
|
memberListDiv = document.getElementById('memberList');
|
||||||
|
|
||||||
if (networked) {
|
if (networked) {
|
||||||
runtime.assert(peopleListDiv, "missing peopleList div in HTML");
|
runtime.assert(memberListDiv, "missing memberList div in HTML");
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.loadClass('odf.OdfCanvas');
|
runtime.loadClass('odf.OdfCanvas');
|
||||||
@ -158,19 +157,14 @@ define("webodf/editor/Editor", [
|
|||||||
// Allow annotations
|
// Allow annotations
|
||||||
odfCanvas.enableAnnotations(true);
|
odfCanvas.enableAnnotations(true);
|
||||||
|
|
||||||
if (!memberid) {
|
|
||||||
// legacy - memberid should be passed in the constructor
|
|
||||||
memberid = (userid || 'undefined') + "___" + Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
session = new ops.Session(odfCanvas);
|
session = new ops.Session(odfCanvas);
|
||||||
editorSession = new EditorSession(session, memberid, {
|
editorSession = new EditorSession(session, memberid, {
|
||||||
viewOptions: viewOptions
|
viewOptions: viewOptions
|
||||||
});
|
});
|
||||||
editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager());
|
editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager());
|
||||||
|
|
||||||
if (peopleListDiv) {
|
if (memberListDiv) {
|
||||||
userList = new UserList(editorSession, peopleListDiv);
|
memberList = new MemberList(editorSession, memberListDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registerCallbackForShutdown) {
|
if (registerCallbackForShutdown) {
|
||||||
@ -192,12 +186,12 @@ define("webodf/editor/Editor", [
|
|||||||
}, 'editor');
|
}, 'editor');
|
||||||
mainContainer.addChild(editorPane);
|
mainContainer.addChild(editorPane);
|
||||||
|
|
||||||
if (networked && peopleListDiv) {
|
if (networked && memberListDiv) {
|
||||||
peoplePane = new ContentPane({
|
memberListPane = new ContentPane({
|
||||||
region: 'right',
|
region: 'right',
|
||||||
title: translator("people")
|
title: translator("members")
|
||||||
}, 'people');
|
}, 'members');
|
||||||
mainContainer.addChild(peoplePane);
|
mainContainer.addChild(memberListPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
mainContainer.startup();
|
mainContainer.startup();
|
||||||
@ -205,7 +199,7 @@ define("webodf/editor/Editor", [
|
|||||||
if (window.inviteButtonProxy) {
|
if (window.inviteButtonProxy) {
|
||||||
inviteButton = document.getElementById('inviteButton');
|
inviteButton = document.getElementById('inviteButton');
|
||||||
if (inviteButton) {
|
if (inviteButton) {
|
||||||
inviteButton.innerText = translator("invitePeople");
|
inviteButton.innerText = translator("inviteMembers");
|
||||||
inviteButton.style.display = "block";
|
inviteButton.style.display = "block";
|
||||||
inviteButton.onclick = window.inviteButtonProxy.clicked;
|
inviteButton.onclick = window.inviteButtonProxy.clicked;
|
||||||
}
|
}
|
||||||
@ -269,12 +263,12 @@ define("webodf/editor/Editor", [
|
|||||||
*/
|
*/
|
||||||
self.loadSession = function (sessionId, editorReadyCallback) {
|
self.loadSession = function (sessionId, editorReadyCallback) {
|
||||||
initGuiAndDoc(server.getGenesisUrl(sessionId), function () {
|
initGuiAndDoc(server.getGenesisUrl(sessionId), function () {
|
||||||
// get router and user model
|
// get router and member model
|
||||||
opRouter = opRouter || serverFactory.createOperationRouter(sessionId, memberid, server);
|
opRouter = opRouter || serverFactory.createOperationRouter(sessionId, memberid, server);
|
||||||
session.setOperationRouter(opRouter);
|
session.setOperationRouter(opRouter);
|
||||||
|
|
||||||
userModel = userModel || serverFactory.createUserModel(server);
|
memberModel = memberModel || serverFactory.createMemberModel(sessionId, server);
|
||||||
session.setUserModel(userModel);
|
session.setMemberModel(memberModel);
|
||||||
|
|
||||||
opRouter.requestReplay(function done() {
|
opRouter.requestReplay(function done() {
|
||||||
var odtDocument = session.getOdtDocument();
|
var odtDocument = session.getOdtDocument();
|
||||||
@ -295,9 +289,9 @@ define("webodf/editor/Editor", [
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// access to user model
|
// access to member model
|
||||||
self.getUserModel = function () {
|
self.getMemberModel = function () {
|
||||||
return userModel;
|
return memberModel;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return Editor;
|
return Editor;
|
||||||
|
@ -70,8 +70,8 @@ define("webodf/editor/EditorSession", [
|
|||||||
formatting = odtDocument.getFormatting(),
|
formatting = odtDocument.getFormatting(),
|
||||||
styleHelper = new gui.StyleHelper(formatting),
|
styleHelper = new gui.StyleHelper(formatting),
|
||||||
eventNotifier = new core.EventNotifier([
|
eventNotifier = new core.EventNotifier([
|
||||||
EditorSession.signalUserAdded,
|
EditorSession.signalMemberAdded,
|
||||||
EditorSession.signalUserRemoved,
|
EditorSession.signalMemberRemoved,
|
||||||
EditorSession.signalCursorMoved,
|
EditorSession.signalCursorMoved,
|
||||||
EditorSession.signalParagraphChanged,
|
EditorSession.signalParagraphChanged,
|
||||||
EditorSession.signalStyleCreated,
|
EditorSession.signalStyleCreated,
|
||||||
@ -164,7 +164,7 @@ define("webodf/editor/EditorSession", [
|
|||||||
ncName = createNCName(name);
|
ncName = createNCName(name);
|
||||||
|
|
||||||
// create default paragraph style
|
// create default paragraph style
|
||||||
// memberid is used to avoid id conflicts with ids created by other users
|
// memberid is used to avoid id conflicts with ids created by other members
|
||||||
result = ncName + "_" + ncMemberId;
|
result = ncName + "_" + ncMemberId;
|
||||||
// then loop until result is really unique
|
// then loop until result is really unique
|
||||||
while (formatting.hasParagraphStyle(result)) {
|
while (formatting.hasParagraphStyle(result)) {
|
||||||
@ -196,12 +196,12 @@ define("webodf/editor/EditorSession", [
|
|||||||
|
|
||||||
// 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.
|
// 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.signalCursorAdded, function (cursor) {
|
odtDocument.subscribe(ops.OdtDocument.signalCursorAdded, function (cursor) {
|
||||||
self.emit(EditorSession.signalUserAdded, cursor.getMemberId());
|
self.emit(EditorSession.signalMemberAdded, cursor.getMemberId());
|
||||||
trackCursor(cursor);
|
trackCursor(cursor);
|
||||||
});
|
});
|
||||||
|
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, function (memberId) {
|
odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, function (memberId) {
|
||||||
self.emit(EditorSession.signalUserRemoved, memberId);
|
self.emit(EditorSession.signalMemberRemoved, memberId);
|
||||||
});
|
});
|
||||||
|
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, function (cursor) {
|
odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, function (cursor) {
|
||||||
@ -251,12 +251,12 @@ define("webodf/editor/EditorSession", [
|
|||||||
eventNotifier.subscribe(eventid, cb);
|
eventNotifier.subscribe(eventid, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getUserDetailsAndUpdates = function (memberId, subscriber) {
|
this.getMemberDetailsAndUpdates = function (memberId, subscriber) {
|
||||||
return session.getUserModel().getUserDetailsAndUpdates(memberId, subscriber);
|
return session.getMemberModel().getMemberDetailsAndUpdates(memberId, subscriber);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.unsubscribeUserDetailsUpdates = function (memberId, subscriber) {
|
this.unsubscribeMemberDetailsUpdates = function (memberId, subscriber) {
|
||||||
return session.getUserModel().unsubscribeUserDetailsUpdates(memberId, subscriber);
|
return session.getMemberModel().unsubscribeMemberDetailsUpdates(memberId, subscriber);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getCursorPosition = function () {
|
this.getCursorPosition = function () {
|
||||||
@ -458,7 +458,7 @@ define("webodf/editor/EditorSession", [
|
|||||||
|
|
||||||
this.deleteStyle = function (styleName) {
|
this.deleteStyle = function (styleName) {
|
||||||
var op;
|
var op;
|
||||||
op = new ops.OpDeleteParagraphStyle();
|
op = new ops.OpRemoveParagraphStyle();
|
||||||
op.init({
|
op.init({
|
||||||
memberid: memberid,
|
memberid: memberid,
|
||||||
styleName: styleName
|
styleName: styleName
|
||||||
@ -541,8 +541,8 @@ define("webodf/editor/EditorSession", [
|
|||||||
init();
|
init();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@const*/EditorSession.signalUserAdded = "userAdded";
|
/**@const*/EditorSession.signalMemberAdded = "memberAdded";
|
||||||
/**@const*/EditorSession.signalUserRemoved = "userRemoved";
|
/**@const*/EditorSession.signalMemberRemoved = "memberRemoved";
|
||||||
/**@const*/EditorSession.signalCursorMoved = "cursorMoved";
|
/**@const*/EditorSession.signalCursorMoved = "cursorMoved";
|
||||||
/**@const*/EditorSession.signalParagraphChanged = "paragraphChanged";
|
/**@const*/EditorSession.signalParagraphChanged = "paragraphChanged";
|
||||||
/**@const*/EditorSession.signalStyleCreated = "styleCreated";
|
/**@const*/EditorSession.signalStyleCreated = "styleCreated";
|
||||||
|
@ -33,32 +33,33 @@
|
|||||||
* @source: http://gitorious.org/webodf/webodf/
|
* @source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
/*global define,runtime */
|
/*global define,runtime */
|
||||||
define("webodf/editor/UserList",
|
|
||||||
|
define("webodf/editor/MemberList",
|
||||||
["webodf/editor/EditorSession"],
|
["webodf/editor/EditorSession"],
|
||||||
|
|
||||||
function (EditorSession) {
|
function (EditorSession) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
return function UserList(editorSession, userListDiv) {
|
return function MemberList(editorSession, memberListDiv) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
editorSession.subscribe(EditorSession.signalUserAdded, function (memberId) {
|
editorSession.subscribe(EditorSession.signalMemberAdded, function (memberId) {
|
||||||
self.addUser(memberId);
|
self.addMember(memberId);
|
||||||
});
|
});
|
||||||
|
|
||||||
editorSession.subscribe(EditorSession.signalUserRemoved, function (memberId) {
|
editorSession.subscribe(EditorSession.signalMemberRemoved, function (memberId) {
|
||||||
self.removeUser(memberId);
|
self.removeMember(memberId);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!string} memberId
|
* @param {!string} memberId
|
||||||
*/
|
*/
|
||||||
function updateAvatarButton(memberId, userDetails) {
|
function updateAvatarButton(memberId, memberDetails) {
|
||||||
var node = userListDiv.firstChild;
|
var node = memberListDiv.firstChild;
|
||||||
if (userDetails === null) {
|
if (memberDetails === null) {
|
||||||
// 'null' here means finally unknown user
|
// 'null' here means finally unknown member
|
||||||
// (and not that the data is still loading)
|
// (and not that the data is still loading)
|
||||||
userDetails = {
|
memberDetails = {
|
||||||
memberid: memberId, fullname: "Unknown",
|
memberid: memberId, fullname: "Unknown",
|
||||||
color: "black", imageurl: "avatar-joe.png"
|
color: "black", imageurl: "avatar-joe.png"
|
||||||
};
|
};
|
||||||
@ -69,11 +70,11 @@ define("webodf/editor/UserList",
|
|||||||
while (node) {
|
while (node) {
|
||||||
if (node.localName === "img") {
|
if (node.localName === "img") {
|
||||||
// update avatar image
|
// update avatar image
|
||||||
node.src = userDetails.imageurl;
|
node.src = memberDetails.imageurl;
|
||||||
// update border color
|
// update border color
|
||||||
node.style.borderColor = userDetails.color;
|
node.style.borderColor = memberDetails.color;
|
||||||
} else if (node.localName === "div") {
|
} else if (node.localName === "div") {
|
||||||
node.setAttribute('fullname', userDetails.fullname);
|
node.setAttribute('fullname', memberDetails.fullname);
|
||||||
}
|
}
|
||||||
node = node.nextSibling;
|
node = node.nextSibling;
|
||||||
}
|
}
|
||||||
@ -87,15 +88,15 @@ define("webodf/editor/UserList",
|
|||||||
* @param {!string} memberId
|
* @param {!string} memberId
|
||||||
*/
|
*/
|
||||||
function createAvatarButton(memberId) {
|
function createAvatarButton(memberId) {
|
||||||
runtime.assert(userListDiv, "userListDiv unavailable");
|
runtime.assert(memberListDiv, "memberListDiv unavailable");
|
||||||
var doc = userListDiv.ownerDocument,
|
var doc = memberListDiv.ownerDocument,
|
||||||
htmlns = doc.documentElement.namespaceURI,
|
htmlns = doc.documentElement.namespaceURI,
|
||||||
avatarDiv = doc.createElementNS(htmlns, "div"),
|
avatarDiv = doc.createElementNS(htmlns, "div"),
|
||||||
imageElement = doc.createElement("img"),
|
imageElement = doc.createElement("img"),
|
||||||
fullnameNode = doc.createElement("div");
|
fullnameNode = doc.createElement("div");
|
||||||
|
|
||||||
avatarDiv.className = "userListButton";
|
avatarDiv.className = "memberListButton";
|
||||||
fullnameNode.className = "userListLabel";
|
fullnameNode.className = "memberListLabel";
|
||||||
avatarDiv.appendChild(imageElement);
|
avatarDiv.appendChild(imageElement);
|
||||||
avatarDiv.appendChild(fullnameNode);
|
avatarDiv.appendChild(fullnameNode);
|
||||||
avatarDiv.memberId = memberId; // TODO: namespace?
|
avatarDiv.memberId = memberId; // TODO: namespace?
|
||||||
@ -112,7 +113,7 @@ define("webodf/editor/UserList",
|
|||||||
caret.toggleHandleVisibility();
|
caret.toggleHandleVisibility();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
userListDiv.appendChild(avatarDiv);
|
memberListDiv.appendChild(avatarDiv);
|
||||||
|
|
||||||
// preset bogus data
|
// preset bogus data
|
||||||
// TODO: indicate loading state
|
// TODO: indicate loading state
|
||||||
@ -124,10 +125,10 @@ define("webodf/editor/UserList",
|
|||||||
* @param {!string} memberId
|
* @param {!string} memberId
|
||||||
*/
|
*/
|
||||||
function removeAvatarButton(memberId) {
|
function removeAvatarButton(memberId) {
|
||||||
var node = userListDiv.firstChild;
|
var node = memberListDiv.firstChild;
|
||||||
while (node) {
|
while (node) {
|
||||||
if (node.memberId === memberId) {
|
if (node.memberId === memberId) {
|
||||||
userListDiv.removeChild(node);
|
memberListDiv.removeChild(node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node = node.nextSibling;
|
node = node.nextSibling;
|
||||||
@ -137,16 +138,16 @@ define("webodf/editor/UserList",
|
|||||||
/**
|
/**
|
||||||
* @param {!string} memberId
|
* @param {!string} memberId
|
||||||
*/
|
*/
|
||||||
this.addUser = function (memberId) {
|
this.addMember = function (memberId) {
|
||||||
createAvatarButton(memberId);
|
createAvatarButton(memberId);
|
||||||
editorSession.getUserDetailsAndUpdates(memberId, updateAvatarButton);
|
editorSession.getMemberDetailsAndUpdates(memberId, updateAvatarButton);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!string} memberId
|
* @param {!string} memberId
|
||||||
*/
|
*/
|
||||||
this.removeUser = function (memberId) {
|
this.removeMember = function (memberId) {
|
||||||
editorSession.unsubscribeUserDetailsUpdates(memberId, updateAvatarButton);
|
editorSession.unsubscribeMemberDetailsUpdates(memberId, updateAvatarButton);
|
||||||
removeAvatarButton(memberId);
|
removeAvatarButton(memberId);
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -1,159 +0,0 @@
|
|||||||
/**
|
|
||||||
* @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.
|
|
||||||
*
|
|
||||||
* 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: http://gitorious.org/webodf/webodf/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*global ops, runtime */
|
|
||||||
|
|
||||||
function PullBoxSessionList(server) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var cachedSessionData = {},
|
|
||||||
subscribers = [],
|
|
||||||
/** HACK: allow to stop pulling, so that does not mess up the logs
|
|
||||||
* Remove before merging to master */
|
|
||||||
pullingActive = true;
|
|
||||||
|
|
||||||
function onSessionData(sessionData) {
|
|
||||||
var i,
|
|
||||||
isNew = ! cachedSessionData.hasOwnProperty(sessionData.id);
|
|
||||||
|
|
||||||
// cache
|
|
||||||
cachedSessionData[sessionData.id] = sessionData;
|
|
||||||
runtime.log("get session data for:"+sessionData.title+", is new:"+isNew);
|
|
||||||
|
|
||||||
for (i = 0; i < subscribers.length; i += 1) {
|
|
||||||
if (isNew) {
|
|
||||||
subscribers[i].onCreated(sessionData);
|
|
||||||
} else {
|
|
||||||
subscribers[i].onUpdated(sessionData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSessionRemoved(sessionId) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
if (cachedSessionData.hasOwnProperty(sessionId)) {
|
|
||||||
delete cachedSessionData[sessionId];
|
|
||||||
|
|
||||||
for (i = 0; i < subscribers.length; i += 1) {
|
|
||||||
subscribers[i].onRemoved(sessionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function pullSessionList() {
|
|
||||||
if (!pullingActive) { return; }
|
|
||||||
|
|
||||||
server.call("session-list", function(responseData) {
|
|
||||||
var response = runtime.fromJson(responseData),
|
|
||||||
sessionList, i,
|
|
||||||
unupdatedSessions = {};
|
|
||||||
|
|
||||||
runtime.log("session-list reply: " + responseData);
|
|
||||||
|
|
||||||
if (response.hasOwnProperty("session_list")) {
|
|
||||||
// collect known sessions
|
|
||||||
for (i in cachedSessionData) {
|
|
||||||
if (cachedSessionData.hasOwnProperty(i)) {
|
|
||||||
unupdatedSessions[i] = ""; // some dummy value, unused
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add/update with all delivered sessions
|
|
||||||
sessionList = response.session_list;
|
|
||||||
for (i = 0; i < sessionList.length; i++) {
|
|
||||||
if (unupdatedSessions.hasOwnProperty(sessionList[i].id)) {
|
|
||||||
delete unupdatedSessions[sessionList[i].id];
|
|
||||||
}
|
|
||||||
onSessionData(sessionList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove unupdated sessions
|
|
||||||
for (i in unupdatedSessions) {
|
|
||||||
if (unupdatedSessions.hasOwnProperty(i)) {
|
|
||||||
onSessionRemoved(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// next update in 5 secs
|
|
||||||
runtime.getWindow().setTimeout(pullSessionList, 5000);
|
|
||||||
} else {
|
|
||||||
runtime.log("Meh, sessionlist data broken: " + responseData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getSessions = function (subscriber) {
|
|
||||||
var i,
|
|
||||||
sessionList = [];
|
|
||||||
|
|
||||||
if (subscriber) {
|
|
||||||
subscribers.push(subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in cachedSessionData) {
|
|
||||||
if (cachedSessionData.hasOwnProperty(i)) {
|
|
||||||
sessionList.push(cachedSessionData[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sessionList;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.unsubscribe = function (subscriber) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
for (i=0; i<subscribers.length; i+=1) {
|
|
||||||
if (subscribers[i] === subscriber) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime.assert((i < subscribers.length),
|
|
||||||
"tried to unsubscribe when not subscribed.");
|
|
||||||
|
|
||||||
subscribers.splice(i,1);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.stopPulling = function () {
|
|
||||||
pullingActive = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
pullSessionList();
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright (C) 2012-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.
|
|
||||||
*
|
|
||||||
* 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: http://gitorious.org/webodf/webodf/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*global ops, runtime */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A model which provides information about sessions.
|
|
||||||
* @interface
|
|
||||||
*/
|
|
||||||
SessionList = function SessionList() {"use strict"; };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {{onCreated:function(!Object),
|
|
||||||
* onUpdated:function(!Object),
|
|
||||||
* onRemoved:function(!string) }} subscriber
|
|
||||||
* @return {undefined}
|
|
||||||
*/
|
|
||||||
SessionList.prototype.getSessions = function (subscriber) {"use strict"; };
|
|
@ -248,26 +248,22 @@ var webodfEditor = (function () {
|
|||||||
* and start the editor on the network.
|
* and start the editor on the network.
|
||||||
*
|
*
|
||||||
* @param {!string} sessionId
|
* @param {!string} sessionId
|
||||||
* @param {!string} userid
|
* @param {!string} memberId
|
||||||
* @param {?string} token
|
* @param {?string} token
|
||||||
* @param {?Object} editorOptions
|
* @param {?Object} editorOptions
|
||||||
* @param {?function(!Object)} editorReadyCallback
|
* @param {?function(!Object)} editorReadyCallback
|
||||||
*/
|
*/
|
||||||
function createNetworkedEditor(sessionId, userid, token, editorOptions, editorReadyCallback) {
|
function createNetworkedEditor(sessionId, memberId, token, editorOptions, editorReadyCallback) {
|
||||||
|
|
||||||
runtime.assert(sessionId, "sessionId needs to be specified");
|
runtime.assert(sessionId, "sessionId needs to be specified");
|
||||||
|
runtime.assert(memberId, "memberId needs to be specified");
|
||||||
runtime.assert(editorInstance === null, "cannot boot with instanciated editor");
|
runtime.assert(editorInstance === null, "cannot boot with instanciated editor");
|
||||||
|
|
||||||
editorOptions = editorOptions || {};
|
editorOptions = editorOptions || {};
|
||||||
editorOptions.memberid = userid + "___" + Date.now();
|
editorOptions.memberid = memberId;
|
||||||
editorOptions.networked = true;
|
editorOptions.networked = true;
|
||||||
editorOptions.networkSecurityToken = token;
|
editorOptions.networkSecurityToken = token;
|
||||||
|
|
||||||
// if pre-authentication has happened:
|
|
||||||
if (token) {
|
|
||||||
server.setToken(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
require({ }, ["webodf/editor/Editor"],
|
require({ }, ["webodf/editor/Editor"],
|
||||||
function (Editor) {
|
function (Editor) {
|
||||||
// TODO: the networkSecurityToken needs to be retrieved via now.login
|
// TODO: the networkSecurityToken needs to be retrieved via now.login
|
||||||
@ -280,7 +276,7 @@ var webodfEditor = (function () {
|
|||||||
editorReadyCallback(editorInstance);
|
editorReadyCallback(editorInstance);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -365,7 +361,8 @@ var webodfEditor = (function () {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function boot(args) {
|
function boot(args) {
|
||||||
var editorOptions = {}, loginProcedure = startLoginProcess;
|
var editorOptions = {},
|
||||||
|
loginProcedure = startLoginProcess;
|
||||||
runtime.assert(!booting, "editor creation already in progress");
|
runtime.assert(!booting, "editor creation already in progress");
|
||||||
|
|
||||||
args = args || {};
|
args = args || {};
|
||||||
@ -399,13 +396,25 @@ var webodfEditor = (function () {
|
|||||||
|
|
||||||
// start the editor with network
|
// start the editor with network
|
||||||
function handleNetworkedSituation() {
|
function handleNetworkedSituation() {
|
||||||
loginProcedure(function (sessionId, userid, token) {
|
var joinSession = server.joinSession;
|
||||||
createNetworkedEditor(sessionId, userid, token, editorOptions, function (ed) {
|
|
||||||
if (args.callback) {
|
if (args.joinSession) {
|
||||||
args.callback(ed);
|
joinSession = args.joinSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loginProcedure(function (sessionId, userId, token) {
|
||||||
|
// if pre-authentication has happened:
|
||||||
|
if (token) {
|
||||||
|
server.setToken(token);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
joinSession(userId, sessionId, function(memberId) {
|
||||||
|
createNetworkedEditor(sessionId, memberId, token, editorOptions, function (ed) {
|
||||||
|
if (args.callback) {
|
||||||
|
args.callback(ed);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
js/editor/resources/fonts/fonts.css
Normal file
0
js/editor/resources/fonts/fonts.css
Normal file
@ -54,10 +54,11 @@ ServerFactory.prototype.createServer = function () {"use strict"; };
|
|||||||
ServerFactory.prototype.createOperationRouter = function (sessionId, memberId, server) {"use strict"; };
|
ServerFactory.prototype.createOperationRouter = function (sessionId, memberId, server) {"use strict"; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {!string} sessionId
|
||||||
* @param {!ops.Server} server
|
* @param {!ops.Server} server
|
||||||
* @return {!ops.UserModel}
|
* @return {!ops.MemberModel}
|
||||||
*/
|
*/
|
||||||
ServerFactory.prototype.createUserModel = function (server) {"use strict"; };
|
ServerFactory.prototype.createMemberModel = function (sessionId, server) {"use strict"; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!ops.Server} server
|
* @param {!ops.Server} server
|
||||||
|
@ -41,7 +41,7 @@ define("webodf/editor/server/nowjs/serverFactory", [
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
runtime.loadClass("ops.NowjsServer");
|
runtime.loadClass("ops.NowjsServer");
|
||||||
runtime.loadClass("ops.NowjsUserModel");
|
runtime.loadClass("ops.NowjsMemberModel");
|
||||||
runtime.loadClass("ops.NowjsOperationRouter");
|
runtime.loadClass("ops.NowjsOperationRouter");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,8 +55,8 @@ define("webodf/editor/server/nowjs/serverFactory", [
|
|||||||
this.createOperationRouter = function (sid, mid, server) {
|
this.createOperationRouter = function (sid, mid, server) {
|
||||||
return new ops.NowjsOperationRouter(sid, mid, server);
|
return new ops.NowjsOperationRouter(sid, mid, server);
|
||||||
};
|
};
|
||||||
this.createUserModel = function (server) {
|
this.createMemberModel = function (sid, server) {
|
||||||
return new ops.NowjsUserModel(server);
|
return new ops.NowjsMemberModel(server);
|
||||||
};
|
};
|
||||||
this.createSessionList = function (server) {
|
this.createSessionList = function (server) {
|
||||||
return new NowjsSessionList(server);
|
return new NowjsSessionList(server);
|
||||||
|
@ -41,7 +41,7 @@ define("webodf/editor/server/pullbox/serverFactory", [
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
runtime.loadClass("ops.PullBoxServer");
|
runtime.loadClass("ops.PullBoxServer");
|
||||||
runtime.loadClass("ops.PullBoxUserModel");
|
runtime.loadClass("ops.PullBoxMemberModel");
|
||||||
runtime.loadClass("ops.PullBoxOperationRouter");
|
runtime.loadClass("ops.PullBoxOperationRouter");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,8 +55,8 @@ define("webodf/editor/server/pullbox/serverFactory", [
|
|||||||
this.createOperationRouter = function (sid, mid, server) {
|
this.createOperationRouter = function (sid, mid, server) {
|
||||||
return new ops.PullBoxOperationRouter(sid, mid, server);
|
return new ops.PullBoxOperationRouter(sid, mid, server);
|
||||||
};
|
};
|
||||||
this.createUserModel = function (server) {
|
this.createMemberModel = function (sid, server) {
|
||||||
return new ops.PullBoxUserModel(server);
|
return new ops.PullBoxMemberModel(sid, server);
|
||||||
};
|
};
|
||||||
this.createSessionList = function (server) {
|
this.createSessionList = function (server) {
|
||||||
return new PullBoxSessionList(server);
|
return new PullBoxSessionList(server);
|
||||||
|
@ -77,14 +77,16 @@ define("webodf/editor/server/pullbox/sessionList", [], function () {
|
|||||||
function pullSessionList() {
|
function pullSessionList() {
|
||||||
if (!pullingActive) { return; }
|
if (!pullingActive) { return; }
|
||||||
|
|
||||||
server.call("session-list", function(responseData) {
|
server.call({
|
||||||
|
command: "query_sessiondata_list"
|
||||||
|
}, function(responseData) {
|
||||||
var response = runtime.fromJson(responseData),
|
var response = runtime.fromJson(responseData),
|
||||||
sessionList, i,
|
sessionList, i,
|
||||||
unupdatedSessions = {};
|
unupdatedSessions = {};
|
||||||
|
|
||||||
runtime.log("session-list reply: " + responseData);
|
runtime.log("query_sessiondata_list reply: " + responseData);
|
||||||
|
|
||||||
if (response.hasOwnProperty("session_list")) {
|
if (response.hasOwnProperty("sessiondata_list")) {
|
||||||
// collect known sessions
|
// collect known sessions
|
||||||
for (i in cachedSessionData) {
|
for (i in cachedSessionData) {
|
||||||
if (cachedSessionData.hasOwnProperty(i)) {
|
if (cachedSessionData.hasOwnProperty(i)) {
|
||||||
@ -93,7 +95,7 @@ define("webodf/editor/server/pullbox/sessionList", [], function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add/update with all delivered sessions
|
// add/update with all delivered sessions
|
||||||
sessionList = response.session_list;
|
sessionList = response.sessiondata_list;
|
||||||
for (i = 0; i < sessionList.length; i++) {
|
for (i = 0; i < sessionList.length; i++) {
|
||||||
if (unupdatedSessions.hasOwnProperty(sessionList[i].id)) {
|
if (unupdatedSessions.hasOwnProperty(sessionList[i].id)) {
|
||||||
delete unupdatedSessions[sessionList[i].id];
|
delete unupdatedSessions[sessionList[i].id];
|
||||||
|
@ -2994,6 +2994,7 @@ core.Utils = function Utils() {
|
|||||||
this.hashString = hashString
|
this.hashString = hashString
|
||||||
};
|
};
|
||||||
core.DomUtils = function DomUtils() {
|
core.DomUtils = function DomUtils() {
|
||||||
|
var self = this;
|
||||||
function findStablePoint(container, offset) {
|
function findStablePoint(container, offset) {
|
||||||
if(offset < container.childNodes.length) {
|
if(offset < container.childNodes.length) {
|
||||||
container = container.childNodes[offset];
|
container = container.childNodes[offset];
|
||||||
@ -3108,7 +3109,26 @@ core.DomUtils = function DomUtils() {
|
|||||||
var nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length;
|
var nodeLength = node.nodeType === Node.TEXT_NODE ? node.length : node.childNodes.length;
|
||||||
return range.comparePoint(node, 0) <= 0 && range.comparePoint(node, nodeLength) >= 0
|
return range.comparePoint(node, 0) <= 0 && range.comparePoint(node, nodeLength) >= 0
|
||||||
}
|
}
|
||||||
this.rangeIntersectsNode = rangeIntersectsNode
|
this.rangeIntersectsNode = rangeIntersectsNode;
|
||||||
|
function containsNode(parent, descendant) {
|
||||||
|
return parent === descendant || parent.contains(descendant)
|
||||||
|
}
|
||||||
|
this.containsNode = containsNode;
|
||||||
|
function containsNodeForBrokenWebKit(parent, descendant) {
|
||||||
|
return parent === descendant || Boolean(parent.compareDocumentPosition(descendant) & Node.DOCUMENT_POSITION_CONTAINED_BY)
|
||||||
|
}
|
||||||
|
function init() {
|
||||||
|
var window = runtime.getWindow(), appVersion, webKitOrSafari;
|
||||||
|
if(window === null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appVersion = window.navigator.appVersion.toLowerCase();
|
||||||
|
webKitOrSafari = appVersion.indexOf("chrome") === -1 && (appVersion.indexOf("applewebkit") !== -1 || appVersion.indexOf("safari") !== -1);
|
||||||
|
if(webKitOrSafari) {
|
||||||
|
self.containsNode = containsNodeForBrokenWebKit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
init()
|
||||||
};
|
};
|
||||||
runtime.loadClass("core.DomUtils");
|
runtime.loadClass("core.DomUtils");
|
||||||
core.Cursor = function Cursor(document, memberId) {
|
core.Cursor = function Cursor(document, memberId) {
|
||||||
@ -5724,7 +5744,7 @@ xmldom.XPath = function() {
|
|||||||
@source: http://www.webodf.org/
|
@source: http://www.webodf.org/
|
||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
gui.AnnotationViewManager = function AnnotationViewManager(odfFragment, annotationsPane) {
|
gui.AnnotationViewManager = function AnnotationViewManager(odfCanvas, odfFragment, annotationsPane) {
|
||||||
var annotations = [], doc = odfFragment.ownerDocument, odfUtils = new odf.OdfUtils, CONNECTOR_MARGIN = 30, NOTE_MARGIN = 20, window = runtime.getWindow();
|
var annotations = [], doc = odfFragment.ownerDocument, odfUtils = new odf.OdfUtils, CONNECTOR_MARGIN = 30, NOTE_MARGIN = 20, window = runtime.getWindow();
|
||||||
runtime.assert(Boolean(window), "Expected to be run in an environment which has a global window, like a browser.");
|
runtime.assert(Boolean(window), "Expected to be run in an environment which has a global window, like a browser.");
|
||||||
function wrapAnnotation(annotation) {
|
function wrapAnnotation(annotation) {
|
||||||
@ -5782,21 +5802,21 @@ gui.AnnotationViewManager = function AnnotationViewManager(odfFragment, annotati
|
|||||||
return Math.sqrt(xs + ys)
|
return Math.sqrt(xs + ys)
|
||||||
}
|
}
|
||||||
function renderAnnotation(annotation) {
|
function renderAnnotation(annotation) {
|
||||||
var annotationNote = annotation.node.parentNode, connectorHorizontal = annotationNote.nextSibling, connectorAngular = connectorHorizontal.nextSibling, annotationWrapper = annotationNote.parentNode, connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, creatorNode = annotation.node.getElementsByTagNameNS(odf.Namespaces.dcns, "creator")[0], creatorName;
|
var annotationNote = annotation.node.parentNode, connectorHorizontal = annotationNote.nextSibling, connectorAngular = connectorHorizontal.nextSibling, annotationWrapper = annotationNote.parentNode, connectorAngle = 0, previousAnnotation = annotations[annotations.indexOf(annotation) - 1], previousRect, creatorNode = annotation.node.getElementsByTagNameNS(odf.Namespaces.dcns, "creator")[0], creatorName, zoomLevel = odfCanvas.getZoomLevel();
|
||||||
annotationNote.style.left = annotationsPane.getBoundingClientRect().left - annotationWrapper.getBoundingClientRect().left + "px";
|
annotationNote.style.left = (annotationsPane.getBoundingClientRect().left - annotationWrapper.getBoundingClientRect().left) / zoomLevel + "px";
|
||||||
annotationNote.style.width = annotationsPane.getBoundingClientRect().width + "px";
|
annotationNote.style.width = annotationsPane.getBoundingClientRect().width / zoomLevel + "px";
|
||||||
connectorHorizontal.style.width = parseFloat(annotationNote.style.left) - CONNECTOR_MARGIN + "px";
|
connectorHorizontal.style.width = parseFloat(annotationNote.style.left) - CONNECTOR_MARGIN + "px";
|
||||||
if(previousAnnotation) {
|
if(previousAnnotation) {
|
||||||
previousRect = previousAnnotation.node.parentNode.getBoundingClientRect();
|
previousRect = previousAnnotation.node.parentNode.getBoundingClientRect();
|
||||||
if(annotationWrapper.getBoundingClientRect().top - previousRect.bottom <= NOTE_MARGIN) {
|
if((annotationWrapper.getBoundingClientRect().top - previousRect.bottom) / zoomLevel <= NOTE_MARGIN) {
|
||||||
annotationNote.style.top = Math.abs(annotationWrapper.getBoundingClientRect().top - previousRect.bottom) + NOTE_MARGIN + "px"
|
annotationNote.style.top = Math.abs(annotationWrapper.getBoundingClientRect().top - previousRect.bottom) / zoomLevel + NOTE_MARGIN + "px"
|
||||||
}else {
|
}else {
|
||||||
annotationNote.style.top = "0px"
|
annotationNote.style.top = "0px"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectorAngular.style.left = connectorHorizontal.getBoundingClientRect().width + "px";
|
connectorAngular.style.left = connectorHorizontal.getBoundingClientRect().width / zoomLevel + "px";
|
||||||
connectorAngular.style.width = lineDistance({x:connectorAngular.getBoundingClientRect().left, y:connectorAngular.getBoundingClientRect().top}, {x:annotationNote.getBoundingClientRect().left, y:annotationNote.getBoundingClientRect().top}) + "px";
|
connectorAngular.style.width = lineDistance({x:connectorAngular.getBoundingClientRect().left / zoomLevel, y:connectorAngular.getBoundingClientRect().top / zoomLevel}, {x:annotationNote.getBoundingClientRect().left / zoomLevel, y:annotationNote.getBoundingClientRect().top / zoomLevel}) + "px";
|
||||||
connectorAngle = Math.asin((annotationNote.getBoundingClientRect().top - connectorAngular.getBoundingClientRect().top) / parseFloat(connectorAngular.style.width));
|
connectorAngle = Math.asin((annotationNote.getBoundingClientRect().top - connectorAngular.getBoundingClientRect().top) / (zoomLevel * parseFloat(connectorAngular.style.width)));
|
||||||
connectorAngular.style.transform = "rotate(" + connectorAngle + "rad)";
|
connectorAngular.style.transform = "rotate(" + connectorAngle + "rad)";
|
||||||
connectorAngular.style.MozTransform = "rotate(" + connectorAngle + "rad)";
|
connectorAngular.style.MozTransform = "rotate(" + connectorAngle + "rad)";
|
||||||
connectorAngular.style.WebkitTransform = "rotate(" + connectorAngle + "rad)";
|
connectorAngular.style.WebkitTransform = "rotate(" + connectorAngle + "rad)";
|
||||||
@ -8618,18 +8638,14 @@ odf.OdfCanvas = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(url) {
|
if(url) {
|
||||||
if(/^(?:http|https|ftp):\/\//.test(url)) {
|
try {
|
||||||
callback(url)
|
part = container.getPart(url);
|
||||||
}else {
|
part.onchange = function(part) {
|
||||||
try {
|
callback(part.url)
|
||||||
part = container.getPart(url);
|
};
|
||||||
part.onchange = function(part) {
|
part.load()
|
||||||
callback(part.url)
|
}catch(e) {
|
||||||
};
|
runtime.log("slight problem: " + e)
|
||||||
part.load()
|
|
||||||
}catch(e) {
|
|
||||||
runtime.log("slight problem: " + e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
url = getUrlFromBinaryDataElement(image);
|
url = getUrlFromBinaryDataElement(image);
|
||||||
@ -8917,7 +8933,7 @@ odf.OdfCanvas = function() {
|
|||||||
}
|
}
|
||||||
odf.OdfCanvas = function OdfCanvas(element) {
|
odf.OdfCanvas = function OdfCanvas(element) {
|
||||||
runtime.assert(element !== null && element !== undefined, "odf.OdfCanvas constructor needs DOM element");
|
runtime.assert(element !== null && element !== undefined, "odf.OdfCanvas constructor needs DOM element");
|
||||||
var doc = element.ownerDocument, odfcontainer, formatting = new odf.Formatting, selectionWatcher = new SelectionWatcher(element), pageSwitcher, fontcss, stylesxmlcss, positioncss, editable = false, zoomLevel = 1, eventHandlers = {}, editparagraph, loadingQueue = new LoadingQueue;
|
var self = this, doc = element.ownerDocument, odfcontainer, formatting = new odf.Formatting, selectionWatcher = new SelectionWatcher(element), pageSwitcher, fontcss, stylesxmlcss, positioncss, editable = false, zoomLevel = 1, eventHandlers = {}, editparagraph, loadingQueue = new LoadingQueue;
|
||||||
addWebODFStyleSheet(doc);
|
addWebODFStyleSheet(doc);
|
||||||
pageSwitcher = new PageSwitcher(addStyleSheet(doc));
|
pageSwitcher = new PageSwitcher(addStyleSheet(doc));
|
||||||
fontcss = addStyleSheet(doc);
|
fontcss = addStyleSheet(doc);
|
||||||
@ -9029,7 +9045,7 @@ odf.OdfCanvas = function() {
|
|||||||
if(annotationManager) {
|
if(annotationManager) {
|
||||||
annotationManager.forgetAnnotations()
|
annotationManager.forgetAnnotations()
|
||||||
}
|
}
|
||||||
annotationManager = new gui.AnnotationViewManager(odfnode.body, annotationsPane);
|
annotationManager = new gui.AnnotationViewManager(self, odfnode.body, annotationsPane);
|
||||||
modifyAnnotations(odfnode.body)
|
modifyAnnotations(odfnode.body)
|
||||||
}else {
|
}else {
|
||||||
if(annotationsPane.parentNode) {
|
if(annotationsPane.parentNode) {
|
||||||
@ -9331,6 +9347,8 @@ ops.Server.prototype.networkStatus = function() {
|
|||||||
};
|
};
|
||||||
ops.Server.prototype.login = function(login, password, successCb, failCb) {
|
ops.Server.prototype.login = function(login, password, successCb, failCb) {
|
||||||
};
|
};
|
||||||
|
ops.Server.prototype.joinSession = function(userId, sessionId, successCb, failCb) {
|
||||||
|
};
|
||||||
ops.Server.prototype.getGenesisUrl = function(sessionId) {
|
ops.Server.prototype.getGenesisUrl = function(sessionId) {
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
@ -9368,16 +9386,10 @@ ops.Server.prototype.getGenesisUrl = function(sessionId) {
|
|||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
ops.NowjsServer = function NowjsServer() {
|
ops.NowjsServer = function NowjsServer() {
|
||||||
var self = this, nowObject;
|
var nowObject;
|
||||||
this.getNowObject = function() {
|
this.getNowObject = function() {
|
||||||
return nowObject
|
return nowObject
|
||||||
};
|
};
|
||||||
function createOperationRouter(sid, mid) {
|
|
||||||
return new ops.NowjsOperationRouter(sid, mid, self)
|
|
||||||
}
|
|
||||||
function createUserModel() {
|
|
||||||
return new ops.NowjsUserModel(self)
|
|
||||||
}
|
|
||||||
this.getGenesisUrl = function(sessionId) {
|
this.getGenesisUrl = function(sessionId) {
|
||||||
return"/session/" + sessionId + "/genesis"
|
return"/session/" + sessionId + "/genesis"
|
||||||
};
|
};
|
||||||
@ -9421,8 +9433,12 @@ ops.NowjsServer = function NowjsServer() {
|
|||||||
nowObject.login(login, password, successCb, failCb)
|
nowObject.login(login, password, successCb, failCb)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.createOperationRouter = createOperationRouter;
|
this.joinSession = function(userId, sessionId, successCb, failCb) {
|
||||||
this.createUserModel = createUserModel
|
nowObject.joinSession(userId, sessionId, function(memberId) {
|
||||||
|
nowObject.memberid = memberId;
|
||||||
|
successCb(memberId)
|
||||||
|
}, failCb)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -9523,6 +9539,19 @@ ops.PullBoxServer = function PullBoxServer(args) {
|
|||||||
failCb(responseData)
|
failCb(responseData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
};
|
||||||
|
this.joinSession = function(userId, sessionId, successCb, failCb) {
|
||||||
|
call({command:"join_session", args:{user_id:userId, es_id:sessionId}}, function(responseData) {
|
||||||
|
var response = (runtime.fromJson(responseData));
|
||||||
|
runtime.log("join_session reply: " + responseData);
|
||||||
|
if(response.hasOwnProperty("success") && response.success) {
|
||||||
|
successCb(response.member_id)
|
||||||
|
}else {
|
||||||
|
if(failCb) {
|
||||||
|
failCb()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
@ -10635,7 +10664,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() {
|
|||||||
};
|
};
|
||||||
this.transform = function(otherOp, hasPriority) {
|
this.transform = function(otherOp, hasPriority) {
|
||||||
var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype;
|
var otherOpspec = otherOp.spec(), otherOpType = otherOpspec.optype;
|
||||||
if(otherOpType === "DeleteParagraphStyle") {
|
if(otherOpType === "RemoveParagraphStyle") {
|
||||||
if(otherOpspec.styleName === styleName) {
|
if(otherOpspec.styleName === styleName) {
|
||||||
styleName = ""
|
styleName = ""
|
||||||
}
|
}
|
||||||
@ -10759,7 +10788,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
if(otherOpType === "DeleteParagraphStyle") {
|
if(otherOpType === "RemoveParagraphStyle") {
|
||||||
if(otherOpspec.styleName === styleName) {
|
if(otherOpspec.styleName === styleName) {
|
||||||
return[]
|
return[]
|
||||||
}
|
}
|
||||||
@ -10866,7 +10895,7 @@ ops.OpAddParagraphStyle = function OpAddParagraphStyle() {
|
|||||||
};
|
};
|
||||||
this.transform = function(otherOp, hasPriority) {
|
this.transform = function(otherOp, hasPriority) {
|
||||||
var otherSpec = otherOp.spec();
|
var otherSpec = otherOp.spec();
|
||||||
if((otherSpec.optype === "UpdateParagraphStyle" || otherSpec.optype === "DeleteParagraphStyle") && otherSpec.styleName === styleName) {
|
if((otherSpec.optype === "UpdateParagraphStyle" || otherSpec.optype === "RemoveParagraphStyle") && otherSpec.styleName === styleName) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return[self]
|
return[self]
|
||||||
@ -10949,8 +10978,8 @@ ops.OpAddParagraphStyle = function OpAddParagraphStyle() {
|
|||||||
@source: http://www.webodf.org/
|
@source: http://www.webodf.org/
|
||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
ops.OpDeleteParagraphStyle = function OpDeleteParagraphStyle() {
|
ops.OpRemoveParagraphStyle = function OpRemoveParagraphStyle() {
|
||||||
var self = this, optype = "DeleteParagraphStyle", memberid, timestamp, styleName;
|
var self = this, optype = "RemoveParagraphStyle", memberid, timestamp, styleName;
|
||||||
this.init = function(data) {
|
this.init = function(data) {
|
||||||
memberid = data.memberid;
|
memberid = data.memberid;
|
||||||
timestamp = data.timestamp;
|
timestamp = data.timestamp;
|
||||||
@ -11137,7 +11166,7 @@ runtime.loadClass("ops.OpSplitParagraph");
|
|||||||
runtime.loadClass("ops.OpSetParagraphStyle");
|
runtime.loadClass("ops.OpSetParagraphStyle");
|
||||||
runtime.loadClass("ops.OpUpdateParagraphStyle");
|
runtime.loadClass("ops.OpUpdateParagraphStyle");
|
||||||
runtime.loadClass("ops.OpAddParagraphStyle");
|
runtime.loadClass("ops.OpAddParagraphStyle");
|
||||||
runtime.loadClass("ops.OpDeleteParagraphStyle");
|
runtime.loadClass("ops.OpRemoveParagraphStyle");
|
||||||
runtime.loadClass("ops.OpAddAnnotation");
|
runtime.loadClass("ops.OpAddAnnotation");
|
||||||
ops.OperationFactory = function OperationFactory() {
|
ops.OperationFactory = function OperationFactory() {
|
||||||
var specs;
|
var specs;
|
||||||
@ -11158,7 +11187,7 @@ ops.OperationFactory = function OperationFactory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function init() {
|
function init() {
|
||||||
specs = {AddCursor:constructor(ops.OpAddCursor), ApplyDirectStyling:constructor(ops.OpApplyDirectStyling), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), AddParagraphStyle:constructor(ops.OpAddParagraphStyle), DeleteParagraphStyle:constructor(ops.OpDeleteParagraphStyle),
|
specs = {AddCursor:constructor(ops.OpAddCursor), ApplyDirectStyling:constructor(ops.OpApplyDirectStyling), InsertTable:constructor(ops.OpInsertTable), InsertText:constructor(ops.OpInsertText), RemoveText:constructor(ops.OpRemoveText), SplitParagraph:constructor(ops.OpSplitParagraph), SetParagraphStyle:constructor(ops.OpSetParagraphStyle), UpdateParagraphStyle:constructor(ops.OpUpdateParagraphStyle), AddParagraphStyle:constructor(ops.OpAddParagraphStyle), RemoveParagraphStyle:constructor(ops.OpRemoveParagraphStyle),
|
||||||
MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor), AddAnnotation:constructor(ops.OpAddAnnotation)}
|
MoveCursor:constructor(ops.OpMoveCursor), RemoveCursor:constructor(ops.OpRemoveCursor), AddAnnotation:constructor(ops.OpAddAnnotation)}
|
||||||
}
|
}
|
||||||
init()
|
init()
|
||||||
@ -11555,7 +11584,7 @@ runtime.loadClass("ops.OpSplitParagraph");
|
|||||||
runtime.loadClass("ops.OpSetParagraphStyle");
|
runtime.loadClass("ops.OpSetParagraphStyle");
|
||||||
runtime.loadClass("ops.OpAddParagraphStyle");
|
runtime.loadClass("ops.OpAddParagraphStyle");
|
||||||
runtime.loadClass("ops.OpUpdateParagraphStyle");
|
runtime.loadClass("ops.OpUpdateParagraphStyle");
|
||||||
runtime.loadClass("ops.OpDeleteParagraphStyle");
|
runtime.loadClass("ops.OpRemoveParagraphStyle");
|
||||||
ops.OperationTransformer = function OperationTransformer() {
|
ops.OperationTransformer = function OperationTransformer() {
|
||||||
var operationFactory;
|
var operationFactory;
|
||||||
function transformOpVsOp(opA, opB) {
|
function transformOpVsOp(opA, opB) {
|
||||||
@ -11731,17 +11760,6 @@ ops.EditInfo = function EditInfo(container, odtDocument) {
|
|||||||
return sortEdits()
|
return sortEdits()
|
||||||
};
|
};
|
||||||
this.addEdit = function(memberid, timestamp) {
|
this.addEdit = function(memberid, timestamp) {
|
||||||
var id, userid = memberid.split("___")[0];
|
|
||||||
if(!editHistory[memberid]) {
|
|
||||||
for(id in editHistory) {
|
|
||||||
if(editHistory.hasOwnProperty(id)) {
|
|
||||||
if(id.split("___")[0] === userid) {
|
|
||||||
delete editHistory[id];
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editHistory[memberid] = {time:timestamp}
|
editHistory[memberid] = {time:timestamp}
|
||||||
};
|
};
|
||||||
this.clearEdits = function() {
|
this.clearEdits = function() {
|
||||||
@ -11890,7 +11908,7 @@ gui.Caret = function Caret(cursor, avatarInitiallyVisible, blinkOnRangeSelect) {
|
|||||||
caretOffsetTopLeft.y += caretElement.offsetTop;
|
caretOffsetTopLeft.y += caretElement.offsetTop;
|
||||||
return{left:caretOffsetTopLeft.x - margin, top:caretOffsetTopLeft.y - margin, right:caretOffsetTopLeft.x + caretElement.scrollWidth - 1 + margin, bottom:caretOffsetTopLeft.y + caretElement.scrollHeight - 1 + margin}
|
return{left:caretOffsetTopLeft.x - margin, top:caretOffsetTopLeft.y - margin, right:caretOffsetTopLeft.x + caretElement.scrollWidth - 1 + margin, bottom:caretOffsetTopLeft.y + caretElement.scrollHeight - 1 + margin}
|
||||||
}
|
}
|
||||||
this.refreshCursor = function() {
|
this.refreshCursorBlinking = function() {
|
||||||
if(blinkOnRangeSelect || cursor.getSelectedRange().collapsed) {
|
if(blinkOnRangeSelect || cursor.getSelectedRange().collapsed) {
|
||||||
shouldBlink = true;
|
shouldBlink = true;
|
||||||
blink(true)
|
blink(true)
|
||||||
@ -12168,6 +12186,8 @@ gui.Clipboard = function Clipboard() {
|
|||||||
}
|
}
|
||||||
init()
|
init()
|
||||||
};
|
};
|
||||||
|
runtime.loadClass("core.DomUtils");
|
||||||
|
runtime.loadClass("odf.OdfUtils");
|
||||||
runtime.loadClass("ops.OpAddCursor");
|
runtime.loadClass("ops.OpAddCursor");
|
||||||
runtime.loadClass("ops.OpRemoveCursor");
|
runtime.loadClass("ops.OpRemoveCursor");
|
||||||
runtime.loadClass("ops.OpMoveCursor");
|
runtime.loadClass("ops.OpMoveCursor");
|
||||||
@ -12181,7 +12201,8 @@ runtime.loadClass("gui.KeyboardHandler");
|
|||||||
runtime.loadClass("gui.StyleHelper");
|
runtime.loadClass("gui.StyleHelper");
|
||||||
gui.SessionController = function() {
|
gui.SessionController = function() {
|
||||||
gui.SessionController = function SessionController(session, inputMemberId) {
|
gui.SessionController = function SessionController(session, inputMemberId) {
|
||||||
var odtDocument = session.getOdtDocument(), odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, clickHandler = new gui.ClickHandler, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), keyboardMovementsFilter = new core.PositionFilterChain, baseFilter = odtDocument.getPositionFilter(), undoManager = null;
|
var window = (runtime.getWindow()), odtDocument = session.getOdtDocument(), domUtils = new core.DomUtils, odfUtils = new odf.OdfUtils, clipboard = new gui.Clipboard, clickHandler = new gui.ClickHandler, keyDownHandler = new gui.KeyboardHandler, keyPressHandler = new gui.KeyboardHandler, styleHelper = new gui.StyleHelper(odtDocument.getFormatting()), keyboardMovementsFilter = new core.PositionFilterChain, baseFilter = odtDocument.getPositionFilter(), undoManager = null;
|
||||||
|
runtime.assert(window !== null, "Expected to be run in an environment which has a global window, like a browser.");
|
||||||
keyboardMovementsFilter.addFilter("BaseFilter", baseFilter);
|
keyboardMovementsFilter.addFilter("BaseFilter", baseFilter);
|
||||||
keyboardMovementsFilter.addFilter("RootFilter", odtDocument.createRootFilter(inputMemberId));
|
keyboardMovementsFilter.addFilter("RootFilter", odtDocument.createRootFilter(inputMemberId));
|
||||||
function listenEvent(eventTarget, eventType, eventHandler, includeDirect) {
|
function listenEvent(eventTarget, eventType, eventHandler, includeDirect) {
|
||||||
@ -12258,21 +12279,67 @@ gui.SessionController = function() {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
function findClosestPosition(node) {
|
||||||
|
var canvasElement = odtDocument.getOdfCanvas().getElement(), newNode = odtDocument.getRootNode(), newOffset = 0, beforeCanvas, iterator;
|
||||||
|
beforeCanvas = canvasElement.compareDocumentPosition(node) & Node.DOCUMENT_POSITION_PRECEDING;
|
||||||
|
if(!beforeCanvas) {
|
||||||
|
iterator = gui.SelectionMover.createPositionIterator(newNode);
|
||||||
|
iterator.moveToEnd();
|
||||||
|
newNode = iterator.container();
|
||||||
|
newOffset = iterator.unfilteredDomOffset()
|
||||||
|
}
|
||||||
|
return{node:newNode, offset:newOffset}
|
||||||
|
}
|
||||||
|
function getSelection(e) {
|
||||||
|
var canvasElement = odtDocument.getOdfCanvas().getElement(), selection = window.getSelection(), anchorNode, anchorOffset, focusNode, focusOffset, anchorNodeInsideCanvas, focusNodeInsideCanvas, caretPos, node;
|
||||||
|
if(selection.anchorNode === null && selection.focusNode === null) {
|
||||||
|
caretPos = caretPositionFromPoint(e.clientX, e.clientY);
|
||||||
|
if(!caretPos) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
anchorNode = (caretPos.container);
|
||||||
|
anchorOffset = caretPos.offset;
|
||||||
|
focusNode = anchorNode;
|
||||||
|
focusOffset = anchorOffset
|
||||||
|
}else {
|
||||||
|
anchorNode = (selection.anchorNode);
|
||||||
|
anchorOffset = selection.anchorOffset;
|
||||||
|
focusNode = (selection.focusNode);
|
||||||
|
focusOffset = selection.focusOffset
|
||||||
|
}
|
||||||
|
runtime.assert(anchorNode !== null && focusNode !== null, "anchorNode is null or focusNode is null");
|
||||||
|
anchorNodeInsideCanvas = domUtils.containsNode(canvasElement, anchorNode);
|
||||||
|
focusNodeInsideCanvas = domUtils.containsNode(canvasElement, focusNode);
|
||||||
|
if(!anchorNodeInsideCanvas && !focusNodeInsideCanvas) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if(!anchorNodeInsideCanvas) {
|
||||||
|
node = findClosestPosition(anchorNode);
|
||||||
|
anchorNode = node.node;
|
||||||
|
anchorOffset = node.offset
|
||||||
|
}
|
||||||
|
if(!focusNodeInsideCanvas) {
|
||||||
|
node = findClosestPosition(focusNode);
|
||||||
|
focusNode = node.node;
|
||||||
|
focusOffset = node.offset
|
||||||
|
}
|
||||||
|
canvasElement.focus();
|
||||||
|
return{anchorNode:anchorNode, anchorOffset:anchorOffset, focusNode:focusNode, focusOffset:focusOffset}
|
||||||
|
}
|
||||||
function selectRange(e) {
|
function selectRange(e) {
|
||||||
runtime.setTimeout(function() {
|
runtime.setTimeout(function() {
|
||||||
var selection = runtime.getWindow().getSelection(), oldPosition = odtDocument.getCursorPosition(inputMemberId), range, caretPos, stepsToAnchor, stepsToFocus, op;
|
var selection = getSelection(e), oldPosition, stepsToAnchor, stepsToFocus, op;
|
||||||
if(selection.anchorNode === null && selection.focusNode === null) {
|
if(selection === null) {
|
||||||
caretPos = caretPositionFromPoint(e.clientX, e.clientY);
|
return
|
||||||
if(caretPos) {
|
|
||||||
range = odtDocument.getDOM().createRange();
|
|
||||||
range.setStart(caretPos.container, caretPos.offset);
|
|
||||||
range.collapse(true);
|
|
||||||
selection.addRange(range)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
stepsToAnchor = countStepsToNode(selection.anchorNode, selection.anchorOffset);
|
stepsToAnchor = countStepsToNode(selection.anchorNode, selection.anchorOffset);
|
||||||
stepsToFocus = countStepsToNode(selection.focusNode, selection.focusOffset);
|
if(selection.focusNode === selection.anchorNode && selection.focusOffset === selection.anchorOffset) {
|
||||||
|
stepsToFocus = stepsToAnchor
|
||||||
|
}else {
|
||||||
|
stepsToFocus = countStepsToNode(selection.focusNode, selection.focusOffset)
|
||||||
|
}
|
||||||
if(stepsToFocus !== null && stepsToFocus !== 0 || stepsToAnchor !== null && stepsToAnchor !== 0) {
|
if(stepsToFocus !== null && stepsToFocus !== 0 || stepsToAnchor !== null && stepsToAnchor !== 0) {
|
||||||
|
oldPosition = odtDocument.getCursorPosition(inputMemberId);
|
||||||
op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor);
|
op = createOpMoveCursor(oldPosition + stepsToAnchor, stepsToFocus - stepsToAnchor);
|
||||||
session.enqueue(op)
|
session.enqueue(op)
|
||||||
}
|
}
|
||||||
@ -12282,18 +12349,22 @@ gui.SessionController = function() {
|
|||||||
selectRange(e)
|
selectRange(e)
|
||||||
}
|
}
|
||||||
function selectWord() {
|
function selectWord() {
|
||||||
var currentNode, i, c, op, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), cursorNode = odtDocument.getCursor(inputMemberId).getNode(), oldPosition = odtDocument.getCursorPosition(inputMemberId), alphaNumeric = /[A-Za-z0-9]/, stepsToStart = 0, stepsToEnd = 0;
|
var canvasElement = odtDocument.getOdfCanvas().getElement(), alphaNumeric = /[A-Za-z0-9]/, stepsToStart = 0, stepsToEnd = 0, iterator, cursorNode, oldPosition, currentNode, i, c, op;
|
||||||
|
if(!domUtils.containsNode(canvasElement, window.getSelection().focusNode)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode());
|
||||||
|
cursorNode = odtDocument.getCursor(inputMemberId).getNode();
|
||||||
iterator.setUnfilteredPosition(cursorNode, 0);
|
iterator.setUnfilteredPosition(cursorNode, 0);
|
||||||
if(iterator.previousPosition()) {
|
if(iterator.previousPosition()) {
|
||||||
currentNode = iterator.getCurrentNode();
|
currentNode = iterator.getCurrentNode();
|
||||||
if(currentNode.nodeType === Node.TEXT_NODE) {
|
if(currentNode.nodeType === Node.TEXT_NODE) {
|
||||||
for(i = currentNode.data.length - 1;i >= 0;i -= 1) {
|
for(i = currentNode.data.length - 1;i >= 0;i -= 1) {
|
||||||
c = currentNode.data[i];
|
c = currentNode.data[i];
|
||||||
if(alphaNumeric.test(c)) {
|
if(!alphaNumeric.test(c)) {
|
||||||
stepsToStart -= 1
|
|
||||||
}else {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
stepsToStart -= 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12303,25 +12374,31 @@ gui.SessionController = function() {
|
|||||||
if(currentNode.nodeType === Node.TEXT_NODE) {
|
if(currentNode.nodeType === Node.TEXT_NODE) {
|
||||||
for(i = 0;i < currentNode.data.length;i += 1) {
|
for(i = 0;i < currentNode.data.length;i += 1) {
|
||||||
c = currentNode.data[i];
|
c = currentNode.data[i];
|
||||||
if(alphaNumeric.test(c)) {
|
if(!alphaNumeric.test(c)) {
|
||||||
stepsToEnd += 1
|
|
||||||
}else {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
stepsToEnd += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(stepsToStart !== 0 || stepsToEnd !== 0) {
|
if(stepsToStart !== 0 || stepsToEnd !== 0) {
|
||||||
|
oldPosition = odtDocument.getCursorPosition(inputMemberId);
|
||||||
op = createOpMoveCursor(oldPosition + stepsToStart, Math.abs(stepsToStart) + Math.abs(stepsToEnd));
|
op = createOpMoveCursor(oldPosition + stepsToStart, Math.abs(stepsToStart) + Math.abs(stepsToEnd));
|
||||||
session.enqueue(op)
|
session.enqueue(op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function selectParagraph() {
|
function selectParagraph() {
|
||||||
var stepsToStart, stepsToEnd, op, iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode()), paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode()), oldPosition = odtDocument.getCursorPosition(inputMemberId);
|
var canvasElement = odtDocument.getOdfCanvas().getElement(), iterator, paragraphNode, oldPosition, stepsToStart, stepsToEnd, op;
|
||||||
|
if(!domUtils.containsNode(canvasElement, window.getSelection().focusNode)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
paragraphNode = odtDocument.getParagraphElement(odtDocument.getCursor(inputMemberId).getNode());
|
||||||
stepsToStart = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, 0);
|
stepsToStart = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, 0);
|
||||||
|
iterator = gui.SelectionMover.createPositionIterator(odtDocument.getRootNode());
|
||||||
iterator.moveToEndOfNode(paragraphNode);
|
iterator.moveToEndOfNode(paragraphNode);
|
||||||
stepsToEnd = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, iterator.unfilteredDomOffset());
|
stepsToEnd = odtDocument.getDistanceFromCursor(inputMemberId, paragraphNode, iterator.unfilteredDomOffset());
|
||||||
if(stepsToStart !== 0 || stepsToEnd !== 0) {
|
if(stepsToStart !== 0 || stepsToEnd !== 0) {
|
||||||
|
oldPosition = odtDocument.getCursorPosition(inputMemberId);
|
||||||
op = createOpMoveCursor(oldPosition + stepsToStart, Math.abs(stepsToStart) + Math.abs(stepsToEnd));
|
op = createOpMoveCursor(oldPosition + stepsToStart, Math.abs(stepsToStart) + Math.abs(stepsToEnd));
|
||||||
session.enqueue(op)
|
session.enqueue(op)
|
||||||
}
|
}
|
||||||
@ -12540,7 +12617,7 @@ gui.SessionController = function() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
function maintainCursorSelection() {
|
function maintainCursorSelection() {
|
||||||
var cursor = odtDocument.getCursor(inputMemberId), selection = runtime.getWindow().getSelection();
|
var cursor = odtDocument.getCursor(inputMemberId), selection = window.getSelection();
|
||||||
if(cursor) {
|
if(cursor) {
|
||||||
selection.removeAllRanges();
|
selection.removeAllRanges();
|
||||||
selection.addRange(cursor.getSelectedRange().cloneRange())
|
selection.addRange(cursor.getSelectedRange().cloneRange())
|
||||||
@ -12583,7 +12660,7 @@ gui.SessionController = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function handlePaste(e) {
|
function handlePaste(e) {
|
||||||
var plainText, window = runtime.getWindow();
|
var plainText;
|
||||||
if(window.clipboardData && window.clipboardData.getData) {
|
if(window.clipboardData && window.clipboardData.getData) {
|
||||||
plainText = window.clipboardData.getData("Text")
|
plainText = window.clipboardData.getData("Text")
|
||||||
}else {
|
}else {
|
||||||
@ -12655,7 +12732,7 @@ gui.SessionController = function() {
|
|||||||
listenEvent(canvasElement, "copy", handleCopy);
|
listenEvent(canvasElement, "copy", handleCopy);
|
||||||
listenEvent(canvasElement, "beforepaste", handleBeforePaste, true);
|
listenEvent(canvasElement, "beforepaste", handleBeforePaste, true);
|
||||||
listenEvent(canvasElement, "paste", handlePaste);
|
listenEvent(canvasElement, "paste", handlePaste);
|
||||||
listenEvent(canvasElement, "mouseup", clickHandler.handleMouseUp);
|
listenEvent(window, "mouseup", clickHandler.handleMouseUp);
|
||||||
listenEvent(canvasElement, "contextmenu", handleContextMenu);
|
listenEvent(canvasElement, "contextmenu", handleContextMenu);
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection);
|
odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, maintainCursorSelection);
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack);
|
odtDocument.subscribe(ops.OdtDocument.signalOperationExecuted, updateUndoStack);
|
||||||
@ -12679,7 +12756,7 @@ gui.SessionController = function() {
|
|||||||
removeEvent(canvasElement, "copy", handleCopy);
|
removeEvent(canvasElement, "copy", handleCopy);
|
||||||
removeEvent(canvasElement, "paste", handlePaste);
|
removeEvent(canvasElement, "paste", handlePaste);
|
||||||
removeEvent(canvasElement, "beforepaste", handleBeforePaste);
|
removeEvent(canvasElement, "beforepaste", handleBeforePaste);
|
||||||
removeEvent(canvasElement, "mouseup", clickHandler.handleMouseUp);
|
removeEvent(window, "mouseup", clickHandler.handleMouseUp);
|
||||||
removeEvent(canvasElement, "contextmenu", handleContextMenu);
|
removeEvent(canvasElement, "contextmenu", handleContextMenu);
|
||||||
op = new ops.OpRemoveCursor;
|
op = new ops.OpRemoveCursor;
|
||||||
op.init({memberid:inputMemberId});
|
op.init({memberid:inputMemberId});
|
||||||
@ -12711,7 +12788,7 @@ gui.SessionController = function() {
|
|||||||
return undoManager
|
return undoManager
|
||||||
};
|
};
|
||||||
function init() {
|
function init() {
|
||||||
var isMacOS = runtime.getWindow().navigator.appVersion.toLowerCase().indexOf("mac") !== -1, modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode;
|
var isMacOS = window.navigator.appVersion.toLowerCase().indexOf("mac") !== -1, modifier = gui.KeyboardHandler.Modifier, keyCode = gui.KeyboardHandler.KeyCode;
|
||||||
keyDownHandler.bind(keyCode.Tab, modifier.None, function() {
|
keyDownHandler.bind(keyCode.Tab, modifier.None, function() {
|
||||||
insertText("\t");
|
insertText("\t");
|
||||||
return true
|
return true
|
||||||
@ -12779,15 +12856,9 @@ gui.SessionController = function() {
|
|||||||
};
|
};
|
||||||
return gui.SessionController
|
return gui.SessionController
|
||||||
}();
|
}();
|
||||||
ops.UserModel = function UserModel() {
|
|
||||||
};
|
|
||||||
ops.UserModel.prototype.getUserDetailsAndUpdates = function(memberId, subscriber) {
|
|
||||||
};
|
|
||||||
ops.UserModel.prototype.unsubscribeUserDetailsUpdates = function(memberId, subscriber) {
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (C) 2012 KO GmbH <copyright@kogmbh.com>
|
Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com>
|
||||||
|
|
||||||
@licstart
|
@licstart
|
||||||
The JavaScript code in this page is free software: you can redistribute it
|
The JavaScript code in this page is free software: you can redistribute it
|
||||||
@ -12819,19 +12890,88 @@ ops.UserModel.prototype.unsubscribeUserDetailsUpdates = function(memberId, subsc
|
|||||||
@source: http://www.webodf.org/
|
@source: http://www.webodf.org/
|
||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
ops.TrivialUserModel = function TrivialUserModel() {
|
ops.MemberModel = function MemberModel() {
|
||||||
var users = {};
|
};
|
||||||
users.bob = {memberid:"bob", fullname:"Bob Pigeon", color:"red", imageurl:"avatar-pigeon.png"};
|
ops.MemberModel.prototype.getMemberDetailsAndUpdates = function(memberId, subscriber) {
|
||||||
users.alice = {memberid:"alice", fullname:"Alice Bee", color:"green", imageurl:"avatar-flower.png"};
|
};
|
||||||
users.you = {memberid:"you", fullname:"I, Robot", color:"blue", imageurl:"avatar-joe.png"};
|
ops.MemberModel.prototype.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) {
|
||||||
this.getUserDetailsAndUpdates = function(memberId, subscriber) {
|
};
|
||||||
var userid = memberId.split("___")[0];
|
/*
|
||||||
subscriber(memberId, users[userid] || null)
|
|
||||||
|
Copyright (C) 2012-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.
|
||||||
|
|
||||||
|
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: http://gitorious.org/webodf/webodf/
|
||||||
|
*/
|
||||||
|
ops.TrivialMemberModel = function TrivialMemberModel() {
|
||||||
|
this.getMemberDetailsAndUpdates = function(memberId, subscriber) {
|
||||||
|
subscriber(memberId, null)
|
||||||
};
|
};
|
||||||
this.unsubscribeUserDetailsUpdates = function(memberId, subscriber) {
|
this.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ops.NowjsUserModel = function NowjsUserModel(server) {
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 2012-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.
|
||||||
|
|
||||||
|
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: http://gitorious.org/webodf/webodf/
|
||||||
|
*/
|
||||||
|
ops.NowjsMemberModel = function NowjsMemberModel(server) {
|
||||||
var cachedUserData = {}, memberDataSubscribers = {}, nowObject = server.getNowObject();
|
var cachedUserData = {}, memberDataSubscribers = {}, nowObject = server.getNowObject();
|
||||||
function userIdFromMemberId(memberId) {
|
function userIdFromMemberId(memberId) {
|
||||||
return memberId.split("___")[0]
|
return memberId.split("___")[0]
|
||||||
@ -12846,7 +12986,7 @@ ops.NowjsUserModel = function NowjsUserModel(server) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.getUserDetailsAndUpdates = function(memberId, subscriber) {
|
this.getMemberDetailsAndUpdates = function(memberId, subscriber) {
|
||||||
var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] || [], i;
|
var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] || [], i;
|
||||||
memberDataSubscribers[userId] = subscribers;
|
memberDataSubscribers[userId] = subscribers;
|
||||||
runtime.assert(subscriber !== undefined, "missing callback");
|
runtime.assert(subscriber !== undefined, "missing callback");
|
||||||
@ -12856,7 +12996,7 @@ ops.NowjsUserModel = function NowjsUserModel(server) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i < subscribers.length) {
|
if(i < subscribers.length) {
|
||||||
runtime.log("double subscription request for " + memberId + " in NowjsUserModel::getUserDetailsAndUpdates")
|
runtime.log("double subscription request for " + memberId + " in NowjsMemberModel::getMemberDetailsAndUpdates")
|
||||||
}else {
|
}else {
|
||||||
subscribers.push({memberId:memberId, subscriber:subscriber});
|
subscribers.push({memberId:memberId, subscriber:subscriber});
|
||||||
if(subscribers.length === 1) {
|
if(subscribers.length === 1) {
|
||||||
@ -12867,7 +13007,7 @@ ops.NowjsUserModel = function NowjsUserModel(server) {
|
|||||||
subscriber(memberId, userData)
|
subscriber(memberId, userData)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.unsubscribeUserDetailsUpdates = function(memberId, subscriber) {
|
this.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) {
|
||||||
var i, userId = userIdFromMemberId(memberId), subscribers = memberDataSubscribers[userId];
|
var i, userId = userIdFromMemberId(memberId), subscribers = memberDataSubscribers[userId];
|
||||||
runtime.assert(subscriber !== undefined, "missing subscriber parameter or null");
|
runtime.assert(subscriber !== undefined, "missing subscriber parameter or null");
|
||||||
runtime.assert(subscribers, "tried to unsubscribe when no one is subscribed ('" + memberId + "')");
|
runtime.assert(subscribers, "tried to unsubscribe when no one is subscribed ('" + memberId + "')");
|
||||||
@ -12926,61 +13066,53 @@ ops.NowjsUserModel = function NowjsUserModel(server) {
|
|||||||
@source: http://www.webodf.org/
|
@source: http://www.webodf.org/
|
||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
ops.PullBoxUserModel = function PullBoxUserModel(server) {
|
ops.PullBoxMemberModel = function PullBoxMemberModel(sessionId, server) {
|
||||||
var cachedUserData = {}, memberDataSubscribers = {}, serverPullingActivated = false, pullingIntervall = 2E4;
|
var cachedMemberData = {}, memberDataSubscribers = {}, serverPullingActivated = false, pullingIntervall = 2E4;
|
||||||
function userIdFromMemberId(memberId) {
|
function cacheMemberDatum(memberData) {
|
||||||
return memberId.split("___")[0]
|
|
||||||
}
|
|
||||||
function cacheUserDatum(userData) {
|
|
||||||
var subscribers, i;
|
var subscribers, i;
|
||||||
subscribers = memberDataSubscribers[userData.userid];
|
subscribers = memberDataSubscribers[memberData.memberid];
|
||||||
if(subscribers) {
|
if(subscribers) {
|
||||||
cachedUserData[userData.userid] = userData;
|
cachedMemberData[memberData.memberid] = memberData;
|
||||||
for(i = 0;i < subscribers.length;i += 1) {
|
for(i = 0;i < subscribers.length;i += 1) {
|
||||||
subscribers[i].subscriber(subscribers[i].memberId, userData)
|
subscribers[i](memberData.memberid, memberData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function pullUserData() {
|
function pullMemberData() {
|
||||||
var i, userIds = [];
|
var i, memberIds = Object.keys(memberDataSubscribers);
|
||||||
for(i in memberDataSubscribers) {
|
runtime.log("member-list request for : " + memberIds.join(","));
|
||||||
if(memberDataSubscribers.hasOwnProperty(i)) {
|
server.call({command:"query_memberdata_list", args:{es_id:sessionId, member_ids:memberIds}}, function(responseData) {
|
||||||
userIds.push(i)
|
var response = (runtime.fromJson(responseData)), memberDataList, newMemberData, oldMemberData;
|
||||||
}
|
runtime.log("member-list reply: " + responseData);
|
||||||
}
|
if(response.hasOwnProperty("memberdata_list")) {
|
||||||
runtime.log("user-list request for : " + userIds.join(","));
|
memberDataList = response.memberdata_list;
|
||||||
server.call({command:"user-list", args:{user_ids:userIds}}, function(responseData) {
|
for(i = 0;i < memberDataList.length;i += 1) {
|
||||||
var response = (runtime.fromJson(responseData)), userList, newUserData, oldUserData;
|
newMemberData = {memberid:memberDataList[i].member_id, fullname:memberDataList[i].display_name, imageurl:memberDataList[i].avatar_url, color:memberDataList[i].color};
|
||||||
runtime.log("user-list reply: " + responseData);
|
oldMemberData = cachedMemberData.hasOwnProperty(newMemberData.memberid) ? cachedMemberData[newMemberData.memberid] : null;
|
||||||
if(response.hasOwnProperty("userdata_list")) {
|
if(!oldMemberData || oldMemberData.fullname !== newMemberData.fullname || oldMemberData.imageurl !== newMemberData.imageurl || oldMemberData.color !== newMemberData.color) {
|
||||||
userList = response.userdata_list;
|
cacheMemberDatum(newMemberData)
|
||||||
for(i = 0;i < userList.length;i += 1) {
|
|
||||||
newUserData = {userid:userList[i].uid, fullname:userList[i].fullname, imageurl:"/user/" + userList[i].avatarId + "/avatar.png", color:userList[i].color};
|
|
||||||
oldUserData = cachedUserData.hasOwnProperty(userList[i].uid) ? cachedUserData[userList[i].uid] : null;
|
|
||||||
if(!oldUserData || oldUserData.fullname !== newUserData.fullname || oldUserData.imageurl !== newUserData.imageurl || oldUserData.color !== newUserData.color) {
|
|
||||||
cacheUserDatum(newUserData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
runtime.log("Meh, userlist data broken: " + responseData)
|
runtime.log("Meh, memberdata list broken: " + responseData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function periodicPullUserData() {
|
function periodicPullMemberData() {
|
||||||
if(!serverPullingActivated) {
|
if(!serverPullingActivated) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pullUserData();
|
pullMemberData();
|
||||||
runtime.setTimeout(periodicPullUserData, pullingIntervall)
|
runtime.setTimeout(periodicPullMemberData, pullingIntervall)
|
||||||
}
|
}
|
||||||
function activatePeriodicUserDataPulling() {
|
function activatePeriodicMemberDataPulling() {
|
||||||
if(serverPullingActivated) {
|
if(serverPullingActivated) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
serverPullingActivated = true;
|
serverPullingActivated = true;
|
||||||
runtime.setTimeout(periodicPullUserData, pullingIntervall)
|
runtime.setTimeout(periodicPullMemberData, pullingIntervall)
|
||||||
}
|
}
|
||||||
function deactivatePeriodicUserDataPulling() {
|
function deactivatePeriodicMemberDataPulling() {
|
||||||
var key;
|
var key;
|
||||||
if(!serverPullingActivated) {
|
if(!serverPullingActivated) {
|
||||||
return
|
return
|
||||||
@ -12992,35 +13124,35 @@ ops.PullBoxUserModel = function PullBoxUserModel(server) {
|
|||||||
}
|
}
|
||||||
serverPullingActivated = false
|
serverPullingActivated = false
|
||||||
}
|
}
|
||||||
this.getUserDetailsAndUpdates = function(memberId, subscriber) {
|
this.getMemberDetailsAndUpdates = function(memberId, subscriber) {
|
||||||
var userId = userIdFromMemberId(memberId), userData = cachedUserData[userId], subscribers = memberDataSubscribers[userId] || [], i;
|
var memberData = cachedMemberData[memberId], subscribers = memberDataSubscribers[memberId] || [], i;
|
||||||
memberDataSubscribers[userId] = subscribers;
|
memberDataSubscribers[memberId] = subscribers;
|
||||||
runtime.assert(subscriber !== undefined, "missing callback");
|
runtime.assert(subscriber !== undefined, "missing callback");
|
||||||
for(i = 0;i < subscribers.length;i += 1) {
|
for(i = 0;i < subscribers.length;i += 1) {
|
||||||
if(subscribers[i].subscriber === subscriber && subscribers[i].memberId === memberId) {
|
if(subscribers[i] === subscriber) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i < subscribers.length) {
|
if(i < subscribers.length) {
|
||||||
runtime.log("double subscription request for " + memberId + " in PullBoxUserModel::getUserDetailsAndUpdates")
|
runtime.log("double subscription request for " + memberId + " in PullBoxMemberModel::getMemberDetailsAndUpdates")
|
||||||
}else {
|
}else {
|
||||||
subscribers.push({memberId:memberId, subscriber:subscriber});
|
subscribers.push(subscriber);
|
||||||
if(subscribers.length === 1) {
|
if(subscribers.length === 1) {
|
||||||
pullUserData()
|
pullMemberData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(userData) {
|
if(memberData) {
|
||||||
subscriber(memberId, userData)
|
subscriber(memberId, memberData)
|
||||||
}
|
}
|
||||||
activatePeriodicUserDataPulling()
|
activatePeriodicMemberDataPulling()
|
||||||
};
|
};
|
||||||
this.unsubscribeUserDetailsUpdates = function(memberId, subscriber) {
|
this.unsubscribeMemberDetailsUpdates = function(memberId, subscriber) {
|
||||||
var i, userId = userIdFromMemberId(memberId), subscribers = memberDataSubscribers[userId];
|
var i, subscribers = memberDataSubscribers[memberId];
|
||||||
runtime.assert(subscriber !== undefined, "missing subscriber parameter or null");
|
runtime.assert(subscriber !== undefined, "missing subscriber parameter or null");
|
||||||
runtime.assert(subscribers, "tried to unsubscribe when no one is subscribed ('" + memberId + "')");
|
runtime.assert(subscribers, "tried to unsubscribe when no one is subscribed ('" + memberId + "')");
|
||||||
if(subscribers) {
|
if(subscribers) {
|
||||||
for(i = 0;i < subscribers.length;i += 1) {
|
for(i = 0;i < subscribers.length;i += 1) {
|
||||||
if(subscribers[i].subscriber === subscriber && subscribers[i].memberId === memberId) {
|
if(subscribers[i] === subscriber) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13028,9 +13160,9 @@ ops.PullBoxUserModel = function PullBoxUserModel(server) {
|
|||||||
subscribers.splice(i, 1);
|
subscribers.splice(i, 1);
|
||||||
if(subscribers.length === 0) {
|
if(subscribers.length === 0) {
|
||||||
runtime.log("no more subscribers for: " + memberId);
|
runtime.log("no more subscribers for: " + memberId);
|
||||||
delete memberDataSubscribers[userId];
|
delete memberDataSubscribers[memberId];
|
||||||
delete cachedUserData[userId];
|
delete cachedMemberData[memberId];
|
||||||
deactivatePeriodicUserDataPulling()
|
deactivatePeriodicMemberDataPulling()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -13193,14 +13325,7 @@ ops.NowjsOperationRouter = function NowjsOperationRouter(sessionId, memberid, se
|
|||||||
done_cb()
|
done_cb()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
|
||||||
function init() {
|
|
||||||
nowObject.memberid = memberid;
|
|
||||||
nowObject.joinSession(sessionId, function(sessionJoinSuccess) {
|
|
||||||
runtime.assert(sessionJoinSuccess, "Trying to join a session which does not exists or where we are already in")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
init()
|
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -13336,10 +13461,10 @@ ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId
|
|||||||
syncLock = true;
|
syncLock = true;
|
||||||
syncedClientOpspecs = unsyncedClientOpspecQueue;
|
syncedClientOpspecs = unsyncedClientOpspecQueue;
|
||||||
unsyncedClientOpspecQueue = [];
|
unsyncedClientOpspecQueue = [];
|
||||||
server.call({command:"sync-ops", args:{es_id:sessionId, member_id:memberId, seq_head:String(lastServerSeq), client_ops:syncedClientOpspecs}}, function(responseData) {
|
server.call({command:"sync_ops", args:{es_id:sessionId, member_id:memberId, seq_head:String(lastServerSeq), client_ops:syncedClientOpspecs}}, function(responseData) {
|
||||||
var shouldRetryInstantly = false, response = (runtime.fromJson(responseData));
|
var shouldRetryInstantly = false, response = (runtime.fromJson(responseData));
|
||||||
runtime.log("sync-ops reply: " + responseData);
|
runtime.log("sync-ops reply: " + responseData);
|
||||||
if(response.result === "newOps") {
|
if(response.result === "new_ops") {
|
||||||
if(response.ops.length > 0) {
|
if(response.ops.length > 0) {
|
||||||
if(unsyncedClientOpspecQueue.length === 0) {
|
if(unsyncedClientOpspecQueue.length === 0) {
|
||||||
receiveOpSpecsFromNetwork(compressOpSpecs(response.ops))
|
receiveOpSpecsFromNetwork(compressOpSpecs(response.ops))
|
||||||
@ -13347,18 +13472,18 @@ ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId
|
|||||||
runtime.log("meh, have new ops locally meanwhile, have to do transformations.");
|
runtime.log("meh, have new ops locally meanwhile, have to do transformations.");
|
||||||
hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops))
|
hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops))
|
||||||
}
|
}
|
||||||
lastServerSeq = response.headSeq
|
lastServerSeq = response.head_seq
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
if(response.result === "added") {
|
if(response.result === "added") {
|
||||||
runtime.log("All added to server");
|
runtime.log("All added to server");
|
||||||
lastServerSeq = response.headSeq
|
lastServerSeq = response.head_seq
|
||||||
}else {
|
}else {
|
||||||
if(response.result === "conflict") {
|
if(response.result === "conflict") {
|
||||||
unsyncedClientOpspecQueue = syncedClientOpspecs.concat(unsyncedClientOpspecQueue);
|
unsyncedClientOpspecQueue = syncedClientOpspecs.concat(unsyncedClientOpspecQueue);
|
||||||
runtime.log("meh, server has new ops meanwhile, have to do transformations.");
|
runtime.log("meh, server has new ops meanwhile, have to do transformations.");
|
||||||
hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops));
|
hasUnresolvableConflict = !handleOpsSyncConflict(compressOpSpecs(response.ops));
|
||||||
lastServerSeq = response.headSeq;
|
lastServerSeq = response.head_seq;
|
||||||
if(!hasUnresolvableConflict) {
|
if(!hasUnresolvableConflict) {
|
||||||
shouldRetryInstantly = true
|
shouldRetryInstantly = true
|
||||||
}
|
}
|
||||||
@ -13423,15 +13548,7 @@ ops.PullBoxOperationRouter = function PullBoxOperationRouter(sessionId, memberId
|
|||||||
playbackFunction(timedOp);
|
playbackFunction(timedOp);
|
||||||
unsyncedClientOpspecQueue.push(opspec);
|
unsyncedClientOpspecQueue.push(opspec);
|
||||||
triggerPushingOps()
|
triggerPushingOps()
|
||||||
};
|
|
||||||
function init() {
|
|
||||||
server.call({command:"join-session", args:{session_id:sessionId, member_id:memberId}}, function(responseData) {
|
|
||||||
var response = Boolean(runtime.fromJson(responseData));
|
|
||||||
runtime.log("join-session reply: " + responseData);
|
|
||||||
runtime.assert(response, "Trying to join a session which does not exists or where we are already in")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
init()
|
|
||||||
};
|
};
|
||||||
gui.EditInfoHandle = function EditInfoHandle(parentElement) {
|
gui.EditInfoHandle = function EditInfoHandle(parentElement) {
|
||||||
var edits = [], handle, document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI, editinfons = "urn:webodf:names:editinfo";
|
var edits = [], handle, document = (parentElement.ownerDocument), htmlns = document.documentElement.namespaceURI, editinfons = "urn:webodf:names:editinfo";
|
||||||
@ -13561,7 +13678,7 @@ gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) {
|
|||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (C) 2012 KO GmbH <copyright@kogmbh.com>
|
Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com>
|
||||||
|
|
||||||
@licstart
|
@licstart
|
||||||
The JavaScript code in this page is free software: you can redistribute it
|
The JavaScript code in this page is free software: you can redistribute it
|
||||||
@ -13594,7 +13711,7 @@ gui.EditInfoMarker = function EditInfoMarker(editInfo, initialVisibility) {
|
|||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
runtime.loadClass("gui.Caret");
|
runtime.loadClass("gui.Caret");
|
||||||
runtime.loadClass("ops.TrivialUserModel");
|
runtime.loadClass("ops.TrivialMemberModel");
|
||||||
runtime.loadClass("ops.EditInfo");
|
runtime.loadClass("ops.EditInfo");
|
||||||
runtime.loadClass("gui.EditInfoMarker");
|
runtime.loadClass("gui.EditInfoMarker");
|
||||||
gui.SessionViewOptions = function() {
|
gui.SessionViewOptions = function() {
|
||||||
@ -13604,7 +13721,7 @@ gui.SessionViewOptions = function() {
|
|||||||
};
|
};
|
||||||
gui.SessionView = function() {
|
gui.SessionView = function() {
|
||||||
function configOption(userValue, defaultValue) {
|
function configOption(userValue, defaultValue) {
|
||||||
return userValue !== undefined ? userValue : defaultValue
|
return userValue !== undefined ? Boolean(userValue) : defaultValue
|
||||||
}
|
}
|
||||||
function SessionView(viewOptions, session, caretManager) {
|
function SessionView(viewOptions, session, caretManager) {
|
||||||
var avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true), blinkOnRangeSelect = configOption(viewOptions.caretBlinksOnRangeSelect, true);
|
var avatarInfoStyles, editInfons = "urn:webodf:names:editinfo", editInfoMap = {}, showEditInfoMarkers = configOption(viewOptions.editInfoMarkersInitiallyVisible, true), showCaretAvatars = configOption(viewOptions.caretAvatarsInitiallyVisible, true), blinkOnRangeSelect = configOption(viewOptions.caretBlinksOnRangeSelect, true);
|
||||||
@ -13708,26 +13825,26 @@ gui.SessionView = function() {
|
|||||||
this.getCaret = function(memberid) {
|
this.getCaret = function(memberid) {
|
||||||
return caretManager.getCaret(memberid)
|
return caretManager.getCaret(memberid)
|
||||||
};
|
};
|
||||||
function renderMemberData(memberId, userData) {
|
function renderMemberData(memberId, memberData) {
|
||||||
var caret = caretManager.getCaret(memberId);
|
var caret = caretManager.getCaret(memberId);
|
||||||
if(userData === undefined) {
|
if(memberData === undefined) {
|
||||||
runtime.log('UserModel sent undefined data for member "' + memberId + '".');
|
runtime.log('MemberModel sent undefined data for member "' + memberId + '".');
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(userData === null) {
|
if(memberData === null) {
|
||||||
userData = {memberid:memberId, fullname:"Unknown Identity", color:"black", imageurl:"avatar-joe.png"}
|
memberData = {memberid:memberId, fullname:"Unknown Identity", color:"black", imageurl:"avatar-joe.png"}
|
||||||
}
|
}
|
||||||
if(caret) {
|
if(caret) {
|
||||||
caret.setAvatarImageUrl(userData.imageurl);
|
caret.setAvatarImageUrl(memberData.imageurl);
|
||||||
caret.setColor(userData.color)
|
caret.setColor(memberData.color)
|
||||||
}
|
}
|
||||||
setAvatarInfoStyle(memberId, userData.fullname, userData.color)
|
setAvatarInfoStyle(memberId, memberData.fullname, memberData.color)
|
||||||
}
|
}
|
||||||
function onCursorAdded(cursor) {
|
function onCursorAdded(cursor) {
|
||||||
var memberId = cursor.getMemberId(), userModel = session.getUserModel();
|
var memberId = cursor.getMemberId(), memberModel = session.getMemberModel();
|
||||||
caretManager.registerCursor(cursor, showCaretAvatars, blinkOnRangeSelect);
|
caretManager.registerCursor(cursor, showCaretAvatars, blinkOnRangeSelect);
|
||||||
renderMemberData(memberId, null);
|
renderMemberData(memberId, null);
|
||||||
userModel.getUserDetailsAndUpdates(memberId, renderMemberData);
|
memberModel.getMemberDetailsAndUpdates(memberId, renderMemberData);
|
||||||
runtime.log("+++ View here +++ eagerly created an Caret for '" + memberId + "'! +++")
|
runtime.log("+++ View here +++ eagerly created an Caret for '" + memberId + "'! +++")
|
||||||
}
|
}
|
||||||
function onCursorRemoved(memberid) {
|
function onCursorRemoved(memberid) {
|
||||||
@ -13739,7 +13856,7 @@ gui.SessionView = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!hasMemberEditInfo) {
|
if(!hasMemberEditInfo) {
|
||||||
session.getUserModel().unsubscribeUserDetailsUpdates(memberid, renderMemberData)
|
session.getMemberModel().unsubscribeMemberDetailsUpdates(memberid, renderMemberData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function init() {
|
function init() {
|
||||||
@ -13762,7 +13879,7 @@ gui.SessionView = function() {
|
|||||||
}();
|
}();
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Copyright (C) 2012 KO GmbH <copyright@kogmbh.com>
|
Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com>
|
||||||
|
|
||||||
@licstart
|
@licstart
|
||||||
The JavaScript code in this page is free software: you can redistribute it
|
The JavaScript code in this page is free software: you can redistribute it
|
||||||
@ -13797,35 +13914,44 @@ gui.SessionView = function() {
|
|||||||
runtime.loadClass("gui.Caret");
|
runtime.loadClass("gui.Caret");
|
||||||
gui.CaretManager = function CaretManager(sessionController) {
|
gui.CaretManager = function CaretManager(sessionController) {
|
||||||
var carets = {};
|
var carets = {};
|
||||||
|
function getCaret(memberId) {
|
||||||
|
return carets.hasOwnProperty(memberId) ? carets[memberId] : null
|
||||||
|
}
|
||||||
function getCanvasElement() {
|
function getCanvasElement() {
|
||||||
return sessionController.getSession().getOdtDocument().getOdfCanvas().getElement()
|
return sessionController.getSession().getOdtDocument().getOdfCanvas().getElement()
|
||||||
}
|
}
|
||||||
function removeCaret(memberId) {
|
function removeCaret(memberId) {
|
||||||
if(memberId === sessionController.getInputMemberId()) {
|
if(memberId === sessionController.getInputMemberId()) {
|
||||||
getCanvasElement().removeAttribute("tabindex", 0)
|
getCanvasElement().removeAttribute("tabindex")
|
||||||
}
|
}
|
||||||
delete carets[memberId]
|
delete carets[memberId]
|
||||||
}
|
}
|
||||||
function refreshCaret(cursor) {
|
function refreshLocalCaretBlinking(cursor) {
|
||||||
var caret = carets[cursor.getMemberId()];
|
var caret, memberId = cursor.getMemberId();
|
||||||
if(caret) {
|
if(memberId === sessionController.getInputMemberId()) {
|
||||||
caret.refreshCursor()
|
caret = getCaret(memberId);
|
||||||
|
if(caret) {
|
||||||
|
caret.refreshCursorBlinking()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function ensureLocalCaretVisible(info) {
|
function ensureLocalCaretVisible(info) {
|
||||||
var caret = carets[info.memberId];
|
var caret;
|
||||||
if(info.memberId === sessionController.getInputMemberId() && caret) {
|
if(info.memberId === sessionController.getInputMemberId()) {
|
||||||
caret.ensureVisible()
|
caret = getCaret(info.memberId);
|
||||||
|
if(caret) {
|
||||||
|
caret.ensureVisible()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function focusLocalCaret() {
|
function focusLocalCaret() {
|
||||||
var caret = carets[sessionController.getInputMemberId()];
|
var caret = getCaret(sessionController.getInputMemberId());
|
||||||
if(caret) {
|
if(caret) {
|
||||||
caret.setFocus()
|
caret.setFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function blurLocalCaret() {
|
function blurLocalCaret() {
|
||||||
var caret = carets[sessionController.getInputMemberId()];
|
var caret = getCaret(sessionController.getInputMemberId());
|
||||||
if(caret) {
|
if(caret) {
|
||||||
caret.removeFocus()
|
caret.removeFocus()
|
||||||
}
|
}
|
||||||
@ -13841,9 +13967,7 @@ gui.CaretManager = function CaretManager(sessionController) {
|
|||||||
}
|
}
|
||||||
return caret
|
return caret
|
||||||
};
|
};
|
||||||
this.getCaret = function(memberid) {
|
this.getCaret = getCaret;
|
||||||
return carets[memberid]
|
|
||||||
};
|
|
||||||
this.getCarets = function() {
|
this.getCarets = function() {
|
||||||
return Object.keys(carets).map(function(memberid) {
|
return Object.keys(carets).map(function(memberid) {
|
||||||
return carets[memberid]
|
return carets[memberid]
|
||||||
@ -13852,7 +13976,7 @@ gui.CaretManager = function CaretManager(sessionController) {
|
|||||||
function init() {
|
function init() {
|
||||||
var session = sessionController.getSession(), odtDocument = session.getOdtDocument(), canvasElement = getCanvasElement();
|
var session = sessionController.getSession(), odtDocument = session.getOdtDocument(), canvasElement = getCanvasElement();
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible);
|
odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, ensureLocalCaretVisible);
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, refreshCaret);
|
odtDocument.subscribe(ops.OdtDocument.signalCursorMoved, refreshLocalCaretBlinking);
|
||||||
odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, removeCaret);
|
odtDocument.subscribe(ops.OdtDocument.signalCursorRemoved, removeCaret);
|
||||||
canvasElement.onfocus = focusLocalCaret;
|
canvasElement.onfocus = focusLocalCaret;
|
||||||
canvasElement.onblur = blurLocalCaret
|
canvasElement.onblur = blurLocalCaret
|
||||||
@ -15038,14 +15162,14 @@ ops.OdtDocument.signalUndoStackChanged = "undo/changed";
|
|||||||
@source: http://www.webodf.org/
|
@source: http://www.webodf.org/
|
||||||
@source: http://gitorious.org/webodf/webodf/
|
@source: http://gitorious.org/webodf/webodf/
|
||||||
*/
|
*/
|
||||||
runtime.loadClass("ops.TrivialUserModel");
|
runtime.loadClass("ops.TrivialMemberModel");
|
||||||
runtime.loadClass("ops.TrivialOperationRouter");
|
runtime.loadClass("ops.TrivialOperationRouter");
|
||||||
runtime.loadClass("ops.OperationFactory");
|
runtime.loadClass("ops.OperationFactory");
|
||||||
runtime.loadClass("ops.OdtDocument");
|
runtime.loadClass("ops.OdtDocument");
|
||||||
ops.Session = function Session(odfCanvas) {
|
ops.Session = function Session(odfCanvas) {
|
||||||
var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), userModel = new ops.TrivialUserModel, operationRouter = null;
|
var self = this, operationFactory = new ops.OperationFactory, odtDocument = new ops.OdtDocument(odfCanvas), memberModel = new ops.TrivialMemberModel, operationRouter = null;
|
||||||
this.setUserModel = function(uModel) {
|
this.setMemberModel = function(uModel) {
|
||||||
userModel = uModel
|
memberModel = uModel
|
||||||
};
|
};
|
||||||
this.setOperationFactory = function(opFactory) {
|
this.setOperationFactory = function(opFactory) {
|
||||||
operationFactory = opFactory;
|
operationFactory = opFactory;
|
||||||
@ -15061,8 +15185,8 @@ ops.Session = function Session(odfCanvas) {
|
|||||||
});
|
});
|
||||||
opRouter.setOperationFactory(operationFactory)
|
opRouter.setOperationFactory(operationFactory)
|
||||||
};
|
};
|
||||||
this.getUserModel = function() {
|
this.getMemberModel = function() {
|
||||||
return userModel
|
return memberModel
|
||||||
};
|
};
|
||||||
this.getOperationFactory = function() {
|
this.getOperationFactory = function() {
|
||||||
return operationFactory
|
return operationFactory
|
||||||
|
1002
js/webodf.js
1002
js/webodf.js
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user