Merge pull request #1040 from Pita/release/releases-1.1.3
Release/releases 1.1.3 -- More of a hotfix than a release but we strongly recommend updating.pull/1058/merge 1.1.3
commit
3caa030c39
|
@ -45,3 +45,26 @@ Returns the `rep` object.
|
||||||
## editorInfo.ace_doInsertUnorderedList(?)
|
## editorInfo.ace_doInsertUnorderedList(?)
|
||||||
## editorInfo.ace_doInsertOrderedList(?)
|
## editorInfo.ace_doInsertOrderedList(?)
|
||||||
## editorInfo.ace_performDocumentApplyAttributesToRange()
|
## editorInfo.ace_performDocumentApplyAttributesToRange()
|
||||||
|
|
||||||
|
## editorInfo.ace_getAuthorInfos()
|
||||||
|
Returns an info object about the author. Object key = author_id and info includes author's bg color value.
|
||||||
|
Use to define your own authorship.
|
||||||
|
## editorInfo.ace_performDocumentReplaceRange(start, end, newText)
|
||||||
|
This function replaces a range (from [x1,y1] to [x2,y2]) with `newText`.
|
||||||
|
## editorInfo.ace_performDocumentReplaceCharRange(startChar, endChar, newText)
|
||||||
|
This function replaces a range (from y1 to y2) with `newText`.
|
||||||
|
## editorInfo.ace_renumberList(lineNum)
|
||||||
|
If you delete a line, calling this method will fix the line numbering.
|
||||||
|
## editorInfo.ace_doReturnKey()
|
||||||
|
Forces a return key at the current carret position.
|
||||||
|
## editorInfo.ace_isBlockElement(element)
|
||||||
|
Returns true if your passed elment is registered as a block element
|
||||||
|
## editorInfo.ace_getLineListType(lineNum)
|
||||||
|
Returns the line's html list type.
|
||||||
|
## editorInfo.ace_caretLine()
|
||||||
|
Returns X position of the caret.
|
||||||
|
## editorInfo.ace_caretColumn()
|
||||||
|
Returns Y position of the caret.
|
||||||
|
## editorInfo.ace_caretDocChar()
|
||||||
|
Returns the Y offset starting from [x=0,y=0]
|
||||||
|
## editorInfo.ace_isWordChar(?)
|
||||||
|
|
|
@ -174,3 +174,71 @@ Things in context:
|
||||||
This hook gets called every time the client receives a message of type `name`. This can most notably be used with the new HTTP API call, "sendClientsMessage", which sends a custom message type to all clients connected to a pad. You can also use this to handle existing types.
|
This hook gets called every time the client receives a message of type `name`. This can most notably be used with the new HTTP API call, "sendClientsMessage", which sends a custom message type to all clients connected to a pad. You can also use this to handle existing types.
|
||||||
|
|
||||||
`collab_client.js` has a pretty extensive list of message types, if you want to take a look.
|
`collab_client.js` has a pretty extensive list of message types, if you want to take a look.
|
||||||
|
|
||||||
|
##aceStartLineAndCharForPoint-aceEndLineAndCharForPoint
|
||||||
|
Called from: src/static/js/ace2_inner.js
|
||||||
|
|
||||||
|
Things in context:
|
||||||
|
|
||||||
|
1. callstack - a bunch of information about the current action
|
||||||
|
2. editorInfo - information about the user who is making the change
|
||||||
|
3. rep - information about where the change is being made
|
||||||
|
4. root - the span element of the current line
|
||||||
|
5. point - the starting/ending element where the cursor highlights
|
||||||
|
6. documentAttributeManager - information about attributes in the document
|
||||||
|
|
||||||
|
This hook is provided to allow a plugin to turn DOM node selection into [line,char] selection.
|
||||||
|
The return value should be an array of [line,char]
|
||||||
|
|
||||||
|
##aceKeyEvent
|
||||||
|
Called from: src/static/js/ace2_inner.js
|
||||||
|
|
||||||
|
Things in context:
|
||||||
|
|
||||||
|
1. callstack - a bunch of information about the current action
|
||||||
|
2. editorInfo - information about the user who is making the change
|
||||||
|
3. rep - information about where the change is being made
|
||||||
|
4. documentAttributeManager - information about attributes in the document
|
||||||
|
5. evt - the fired event
|
||||||
|
|
||||||
|
This hook is provided to allow a plugin to handle key events.
|
||||||
|
The return value should be true if you have handled the event.
|
||||||
|
|
||||||
|
##collectContentLineText
|
||||||
|
Called from: src/static/js/contentcollector.js
|
||||||
|
|
||||||
|
Things in context:
|
||||||
|
|
||||||
|
1. cc - the contentcollector object
|
||||||
|
2. state - the current state of the change being made
|
||||||
|
3. tname - the tag name of this node currently being processed
|
||||||
|
4. text - the text for that line
|
||||||
|
|
||||||
|
This hook allows you to validate/manipulate the text before it's sent to the server side.
|
||||||
|
The return value should be the validated/manipulated text.
|
||||||
|
|
||||||
|
##collectContentLineBreak
|
||||||
|
Called from: src/static/js/contentcollector.js
|
||||||
|
|
||||||
|
Things in context:
|
||||||
|
|
||||||
|
1. cc - the contentcollector object
|
||||||
|
2. state - the current state of the change being made
|
||||||
|
3. tname - the tag name of this node currently being processed
|
||||||
|
|
||||||
|
This hook is provided to allow whether the br tag should induce a new magic domline or not.
|
||||||
|
The return value should be either true(break the line) or false.
|
||||||
|
|
||||||
|
##disableAuthorColorsForThisLine
|
||||||
|
Called from: src/static/js/linestylefilter.js
|
||||||
|
|
||||||
|
Things in context:
|
||||||
|
|
||||||
|
1. linestylefilter - the JavaScript object that's currently processing the ace attributes
|
||||||
|
2. text - the line text
|
||||||
|
3. class - line class
|
||||||
|
|
||||||
|
This hook is provided to allow whether a given line should be deliniated with multiple authors.
|
||||||
|
Multiple authors in one line cause the creation of magic span lines. This might not suit you and
|
||||||
|
now you can disable it and handle your own deliniation.
|
||||||
|
The return value should be either true(disable) or false.
|
||||||
|
|
|
@ -136,3 +136,16 @@ function handleMessage ( hook, context, callback ) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## getLineHTMLForExport
|
||||||
|
Called from: src/node/utils/ExportHtml.js
|
||||||
|
|
||||||
|
Things in context:
|
||||||
|
|
||||||
|
1. apool - pool object
|
||||||
|
2. attribLine - line attributes
|
||||||
|
3. text - line text
|
||||||
|
|
||||||
|
This hook will allow a plug-in developer to re-write each line when exporting to HTML.
|
||||||
|
|
||||||
|
|
|
@ -436,15 +436,22 @@ function handleUserInfoUpdate(client, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a USERINFO_UPDATE, that means that a user have changed his color or name. Anyway, we get both informations
|
* Handles a USER_CHANGES message, where the client submits its local
|
||||||
* This Method is nearly 90% copied out of the Etherpad Source Code. So I can't tell you what happens here exactly
|
* edits as a changeset.
|
||||||
* Look at https://github.com/ether/pad/blob/master/etherpad/src/etherpad/collab/collab_server.js in the function applyUserChanges()
|
*
|
||||||
|
* This handler's job is to update the incoming changeset so that it applies
|
||||||
|
* to the latest revision, then add it to the pad, broadcast the changes
|
||||||
|
* to all other clients, and send a confirmation to the submitting client.
|
||||||
|
*
|
||||||
|
* This function is based on a similar one in the original Etherpad.
|
||||||
|
* See https://github.com/ether/pad/blob/master/etherpad/src/etherpad/collab/collab_server.js in the function applyUserChanges()
|
||||||
|
*
|
||||||
* @param client the client that send this message
|
* @param client the client that send this message
|
||||||
* @param message the message from the client
|
* @param message the message from the client
|
||||||
*/
|
*/
|
||||||
function handleUserChanges(client, message)
|
function handleUserChanges(client, message)
|
||||||
{
|
{
|
||||||
//check if all ok
|
// Make sure all required fields are present
|
||||||
if(message.data.baseRev == null)
|
if(message.data.baseRev == null)
|
||||||
{
|
{
|
||||||
messageLogger.warn("Dropped message, USER_CHANGES Message has no baseRev!");
|
messageLogger.warn("Dropped message, USER_CHANGES Message has no baseRev!");
|
||||||
|
@ -487,22 +494,23 @@ function handleUserChanges(client, message)
|
||||||
{
|
{
|
||||||
//ex. _checkChangesetAndPool
|
//ex. _checkChangesetAndPool
|
||||||
|
|
||||||
//Copied from Etherpad, don't know what it does exactly
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//this looks like a changeset check, it throws errors sometimes
|
// Verify that the changeset has valid syntax and is in canonical form
|
||||||
Changeset.checkRep(changeset);
|
Changeset.checkRep(changeset);
|
||||||
|
|
||||||
|
// Verify that the attribute indexes used in the changeset are all
|
||||||
|
// defined in the accompanying attribute pool.
|
||||||
Changeset.eachAttribNumber(changeset, function(n) {
|
Changeset.eachAttribNumber(changeset, function(n) {
|
||||||
if (! wireApool.getAttrib(n)) {
|
if (! wireApool.getAttrib(n)) {
|
||||||
throw "Attribute pool is missing attribute "+n+" for changeset "+changeset;
|
throw "Attribute pool is missing attribute "+n+" for changeset "+changeset;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//there is an error in this changeset, so just refuse it
|
|
||||||
catch(e)
|
catch(e)
|
||||||
{
|
{
|
||||||
console.warn("Can't apply USER_CHANGES "+changeset+", cause it faild checkRep");
|
// There is an error in this changeset, so just refuse it
|
||||||
|
console.warn("Can't apply USER_CHANGES "+changeset+", because it failed checkRep");
|
||||||
client.json.send({disconnect:"badChangeset"});
|
client.json.send({disconnect:"badChangeset"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +523,10 @@ function handleUserChanges(client, message)
|
||||||
//ex. applyUserChanges
|
//ex. applyUserChanges
|
||||||
apool = pad.pool;
|
apool = pad.pool;
|
||||||
r = baseRev;
|
r = baseRev;
|
||||||
|
|
||||||
|
// The client's changeset might not be based on the latest revision,
|
||||||
|
// since other clients are sending changes at the same time.
|
||||||
|
// Update the changeset so that it can be applied to the latest revision.
|
||||||
//https://github.com/caolan/async#whilst
|
//https://github.com/caolan/async#whilst
|
||||||
async.whilst(
|
async.whilst(
|
||||||
function() { return r < pad.getHeadRevisionNumber(); },
|
function() { return r < pad.getHeadRevisionNumber(); },
|
||||||
|
@ -526,8 +537,13 @@ function handleUserChanges(client, message)
|
||||||
pad.getRevisionChangeset(r, function(err, c)
|
pad.getRevisionChangeset(r, function(err, c)
|
||||||
{
|
{
|
||||||
if(ERR(err, callback)) return;
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
// At this point, both "c" (from the pad) and "changeset" (from the
|
||||||
|
// client) are relative to revision r - 1. The follow function
|
||||||
|
// rebases "changeset" so that it is relative to revision r
|
||||||
|
// and can be applied after "c".
|
||||||
changeset = Changeset.follow(c, changeset, false, apool);
|
changeset = Changeset.follow(c, changeset, false, apool);
|
||||||
|
|
||||||
if ((r - baseRev) % 200 == 0) { // don't let the stack get too deep
|
if ((r - baseRev) % 200 == 0) { // don't let the stack get too deep
|
||||||
async.nextTick(callback);
|
async.nextTick(callback);
|
||||||
} else {
|
} else {
|
||||||
|
@ -558,7 +574,8 @@ function handleUserChanges(client, message)
|
||||||
if (correctionChangeset) {
|
if (correctionChangeset) {
|
||||||
pad.appendRevision(correctionChangeset);
|
pad.appendRevision(correctionChangeset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the pad always ends with an empty line.
|
||||||
if (pad.text().lastIndexOf("\n\n") != pad.text().length-2) {
|
if (pad.text().lastIndexOf("\n\n") != pad.text().length-2) {
|
||||||
var nlChangeset = Changeset.makeSplice(pad.text(), pad.text().length-1, 0, "\n");
|
var nlChangeset = Changeset.makeSplice(pad.text(), pad.text().length-1, 0, "\n");
|
||||||
pad.appendRevision(nlChangeset);
|
pad.appendRevision(nlChangeset);
|
||||||
|
@ -865,6 +882,13 @@ function handleClientReady(client, message)
|
||||||
},
|
},
|
||||||
function(callback)
|
function(callback)
|
||||||
{
|
{
|
||||||
|
//Check that the client is still here. It might have disconnected between callbacks.
|
||||||
|
if(sessioninfos[client.id] === undefined)
|
||||||
|
{
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Check if this author is already on the pad, if yes, kick the other sessions!
|
//Check if this author is already on the pad, if yes, kick the other sessions!
|
||||||
if(pad2sessions[padIds.padId])
|
if(pad2sessions[padIds.padId])
|
||||||
{
|
{
|
||||||
|
@ -879,10 +903,9 @@ function handleClientReady(client, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save in sessioninfos that this session belonges to this pad
|
//Save in sessioninfos that this session belonges to this pad
|
||||||
var sessionId=String(client.id);
|
sessioninfos[client.id].padId = padIds.padId;
|
||||||
sessioninfos[sessionId].padId = padIds.padId;
|
sessioninfos[client.id].readOnlyPadId = padIds.readOnlyPadId;
|
||||||
sessioninfos[sessionId].readOnlyPadId = padIds.readOnlyPadId;
|
sessioninfos[client.id].readonly = padIds.readonly;
|
||||||
sessioninfos[sessionId].readonly = padIds.readonly;
|
|
||||||
|
|
||||||
//check if there is already a pad2sessions entry, if not, create one
|
//check if there is already a pad2sessions entry, if not, create one
|
||||||
if(!pad2sessions[padIds.padId])
|
if(!pad2sessions[padIds.padId])
|
||||||
|
@ -891,7 +914,7 @@ function handleClientReady(client, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Saves in pad2sessions that this session belongs to this pad
|
//Saves in pad2sessions that this session belongs to this pad
|
||||||
pad2sessions[padIds.padId].push(sessionId);
|
pad2sessions[padIds.padId].push(client.id);
|
||||||
|
|
||||||
//prepare all values for the wire
|
//prepare all values for the wire
|
||||||
var atext = Changeset.cloneAText(pad.atext);
|
var atext = Changeset.cloneAText(pad.atext);
|
||||||
|
@ -956,26 +979,22 @@ function handleClientReady(client, message)
|
||||||
clientVars.userName = authorName;
|
clientVars.userName = authorName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sessioninfos[client.id] !== undefined)
|
//If this is a reconnect, we don't have to send the client the ClientVars again
|
||||||
|
if(message.reconnect == true)
|
||||||
{
|
{
|
||||||
//This is a reconnect, so we don't have to send the client the ClientVars again
|
//Save the revision in sessioninfos, we take the revision from the info the client send to us
|
||||||
if(message.reconnect == true)
|
sessioninfos[client.id].rev = message.client_rev;
|
||||||
{
|
|
||||||
//Save the revision in sessioninfos, we take the revision from the info the client send to us
|
|
||||||
sessioninfos[client.id].rev = message.client_rev;
|
|
||||||
}
|
|
||||||
//This is a normal first connect
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Send the clientVars to the Client
|
|
||||||
client.json.send({type: "CLIENT_VARS", data: clientVars});
|
|
||||||
//Save the revision in sessioninfos
|
|
||||||
sessioninfos[client.id].rev = pad.getHeadRevisionNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Save the revision and the author id in sessioninfos
|
|
||||||
sessioninfos[client.id].author = author;
|
|
||||||
}
|
}
|
||||||
|
//This is a normal first connect
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Send the clientVars to the Client
|
||||||
|
client.json.send({type: "CLIENT_VARS", data: clientVars});
|
||||||
|
//Save the current revision in sessioninfos, should be the same as in clientVars
|
||||||
|
sessioninfos[client.id].rev = pad.getHeadRevisionNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
sessioninfos[client.id].author = author;
|
||||||
|
|
||||||
//prepare the notification for the other users on the pad, that this user joined
|
//prepare the notification for the other users on the pad, that this user joined
|
||||||
var messageToTheOtherUsers = {
|
var messageToTheOtherUsers = {
|
||||||
|
|
|
@ -38,7 +38,6 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
args.app.error(function(err, req, res, next){
|
args.app.error(function(err, req, res, next){
|
||||||
res.send(500);
|
res.send(500);
|
||||||
console.error(err.stack ? err.stack : err.toString());
|
console.error(err.stack ? err.stack : err.toString());
|
||||||
exports.gracefulShutdown();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//connect graceful shutdown with sigint and uncaughtexception
|
//connect graceful shutdown with sigint and uncaughtexception
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"name": "Robin Buse" }
|
"name": "Robin Buse" }
|
||||||
],
|
],
|
||||||
"dependencies" : {
|
"dependencies" : {
|
||||||
"yajsml" : "1.1.5",
|
"yajsml" : "1.1.6",
|
||||||
"request" : "2.9.100",
|
"request" : "2.9.100",
|
||||||
"require-kernel" : "1.0.5",
|
"require-kernel" : "1.0.5",
|
||||||
"resolve" : "0.2.x",
|
"resolve" : "0.2.x",
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
// requires: plugins
|
// requires: plugins
|
||||||
// requires: undefined
|
// requires: undefined
|
||||||
|
|
||||||
|
var KERNEL_SOURCE = '../static/js/require-kernel.js';
|
||||||
|
|
||||||
Ace2Editor.registry = {
|
Ace2Editor.registry = {
|
||||||
nextId: 1
|
nextId: 1
|
||||||
};
|
};
|
||||||
|
@ -31,6 +33,14 @@ Ace2Editor.registry = {
|
||||||
var hooks = require('./pluginfw/hooks');
|
var hooks = require('./pluginfw/hooks');
|
||||||
var _ = require('./underscore');
|
var _ = require('./underscore');
|
||||||
|
|
||||||
|
function scriptTag(source) {
|
||||||
|
return (
|
||||||
|
'<script type="text/javascript">\n'
|
||||||
|
+ source.replace(/<\//g, '<\\/') +
|
||||||
|
'</script>'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function Ace2Editor()
|
function Ace2Editor()
|
||||||
{
|
{
|
||||||
var ace2 = Ace2Editor;
|
var ace2 = Ace2Editor;
|
||||||
|
@ -155,24 +165,6 @@ function Ace2Editor()
|
||||||
|
|
||||||
return {embeded: embededFiles, remote: remoteFiles};
|
return {embeded: embededFiles, remote: remoteFiles};
|
||||||
}
|
}
|
||||||
function pushRequireScriptTo(buffer) {
|
|
||||||
var KERNEL_SOURCE = '../static/js/require-kernel.js';
|
|
||||||
var KERNEL_BOOT = '\
|
|
||||||
require.setRootURI("../javascripts/src");\n\
|
|
||||||
require.setLibraryURI("../javascripts/lib");\n\
|
|
||||||
require.setGlobalKeyPath("require");\n\
|
|
||||||
';
|
|
||||||
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) {
|
|
||||||
buffer.push('<script type="text/javascript">');
|
|
||||||
buffer.push(Ace2Editor.EMBEDED[KERNEL_SOURCE]);
|
|
||||||
buffer.push(KERNEL_BOOT);
|
|
||||||
buffer.push('<\/script>');
|
|
||||||
} else {
|
|
||||||
// Remotely src'd script tag will not work in IE; it must be embedded, so
|
|
||||||
// throw an error if it is not.
|
|
||||||
throw new Error("Require script could not be embedded.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function pushStyleTagsFor(buffer, files) {
|
function pushStyleTagsFor(buffer, files) {
|
||||||
var sorted = sortFilesByEmbeded(files);
|
var sorted = sortFilesByEmbeded(files);
|
||||||
var embededFiles = sorted.embeded;
|
var embededFiles = sorted.embeded;
|
||||||
|
@ -236,23 +228,30 @@ require.setGlobalKeyPath("require");\n\
|
||||||
|
|
||||||
pushStyleTagsFor(iframeHTML, includedCSS);
|
pushStyleTagsFor(iframeHTML, includedCSS);
|
||||||
|
|
||||||
var includedJS = [];
|
if (!Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) {
|
||||||
pushRequireScriptTo(iframeHTML);
|
// Remotely src'd script tag will not work in IE; it must be embedded, so
|
||||||
|
// throw an error if it is not.
|
||||||
|
throw new Error("Require kernel could not be found.");
|
||||||
|
}
|
||||||
|
|
||||||
// Inject my plugins into my child.
|
iframeHTML.push(scriptTag(
|
||||||
iframeHTML.push('\
|
Ace2Editor.EMBEDED[KERNEL_SOURCE] + '\n\
|
||||||
<script type="text/javascript">\n\
|
require.setRootURI("../javascripts/src");\n\
|
||||||
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");\n\
|
require.setLibraryURI("../javascripts/lib");\n\
|
||||||
var plugins = require("ep_etherpad-lite/static/js/pluginfw/client_plugins");\n\
|
require.setGlobalKeyPath("require");\n\
|
||||||
hooks.plugins = plugins;\n\
|
\n\
|
||||||
plugins.adoptPluginsFromAncestorsOf(window);\n\
|
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");\n\
|
||||||
</script>\
|
var plugins = require("ep_etherpad-lite/static/js/pluginfw/client_plugins");\n\
|
||||||
');
|
hooks.plugins = plugins;\n\
|
||||||
|
plugins.adoptPluginsFromAncestorsOf(window);\n\
|
||||||
iframeHTML.push('<script type="text/javascript">');
|
\n\
|
||||||
iframeHTML.push('$ = jQuery = require("ep_etherpad-lite/static/js/rjquery").jQuery; // Expose jQuery #HACK');
|
$ = jQuery = require("ep_etherpad-lite/static/js/rjquery").jQuery; // Expose jQuery #HACK\n\
|
||||||
iframeHTML.push('require("ep_etherpad-lite/static/js/ace2_inner");');
|
var Ace2Inner = require("ep_etherpad-lite/static/js/ace2_inner");\n\
|
||||||
iframeHTML.push('<\/script>');
|
\n\
|
||||||
|
plugins.ensure(function () {\n\
|
||||||
|
Ace2Inner.init();\n\
|
||||||
|
});\n\
|
||||||
|
'));
|
||||||
|
|
||||||
iframeHTML.push('<style type="text/css" title="dynamicsyntax"></style>');
|
iframeHTML.push('<style type="text/css" title="dynamicsyntax"></style>');
|
||||||
|
|
||||||
|
@ -266,8 +265,32 @@ require.setGlobalKeyPath("require");\n\
|
||||||
var thisFunctionsName = "ChildAccessibleAce2Editor";
|
var thisFunctionsName = "ChildAccessibleAce2Editor";
|
||||||
(function () {return this}())[thisFunctionsName] = Ace2Editor;
|
(function () {return this}())[thisFunctionsName] = Ace2Editor;
|
||||||
|
|
||||||
var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' + 'window.onload = function() ' + '{ window.onload = null; setTimeout' + '(function() ' + '{ var iframe = document.createElement("IFRAME"); iframe.name = "ace_inner";' + 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' + 'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE
|
var outerScript = '\
|
||||||
'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' + 'iframe.ace_outerWin = window; ' + 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; ' + 'var doc = iframe.contentWindow.document; doc.open(); var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');doc.write(text); doc.close(); ' + '}, 0); }';
|
editorId = ' + JSON.stringify(info.id) + ';\n\
|
||||||
|
editorInfo = parent[' + JSON.stringify(thisFunctionsName) + '].registry[editorId];\n\
|
||||||
|
window.onload = function () {\n\
|
||||||
|
window.onload = null;\n\
|
||||||
|
setTimeout(function () {\n\
|
||||||
|
var iframe = document.createElement("IFRAME");\n\
|
||||||
|
iframe.name = "ace_inner";\n\
|
||||||
|
iframe.scrolling = "no";\n\
|
||||||
|
var outerdocbody = document.getElementById("outerdocbody");\n\
|
||||||
|
iframe.frameBorder = 0;\n\
|
||||||
|
iframe.allowTransparency = true; // for IE\n\
|
||||||
|
outerdocbody.insertBefore(iframe, outerdocbody.firstChild);\n\
|
||||||
|
iframe.ace_outerWin = window;\n\
|
||||||
|
readyFunc = function () {\n\
|
||||||
|
editorInfo.onEditorReady();\n\
|
||||||
|
readyFunc = null;\n\
|
||||||
|
editorInfo = null;\n\
|
||||||
|
};\n\
|
||||||
|
var doc = iframe.contentWindow.document;\n\
|
||||||
|
doc.open();\n\
|
||||||
|
var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');\n\
|
||||||
|
doc.write(text);\n\
|
||||||
|
doc.close();\n\
|
||||||
|
}, 0);\n\
|
||||||
|
}';
|
||||||
|
|
||||||
var outerHTML = [doctype, '<html><head>']
|
var outerHTML = [doctype, '<html><head>']
|
||||||
|
|
||||||
|
@ -285,7 +308,7 @@ require.setGlobalKeyPath("require");\n\
|
||||||
|
|
||||||
// bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
|
// bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
|
||||||
// (throbs busy while typing)
|
// (throbs busy while typing)
|
||||||
outerHTML.push('<link rel="stylesheet" type="text/css" href="data:text/css,"/>', '\x3cscript>\n', outerScript.replace(/<\//g, '<\\/'), '\n\x3c/script>', '</head><body id="outerdocbody"><div id="sidediv"><!-- --></div><div id="linemetricsdiv">x</div><div id="overlaysdiv"><!-- --></div></body></html>');
|
outerHTML.push('<link rel="stylesheet" type="text/css" href="data:text/css,"/>', scriptTag(outerScript), '</head><body id="outerdocbody"><div id="sidediv"><!-- --></div><div id="linemetricsdiv">x</div><div id="overlaysdiv"><!-- --></div></body></html>');
|
||||||
|
|
||||||
var outerFrame = document.createElement("IFRAME");
|
var outerFrame = document.createElement("IFRAME");
|
||||||
outerFrame.name = "ace_outer";
|
outerFrame.name = "ace_outer";
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
var editor, _, $, jQuery, plugins, Ace2Common;
|
var _, $, jQuery, plugins, Ace2Common;
|
||||||
|
|
||||||
Ace2Common = require('./ace2_common');
|
Ace2Common = require('./ace2_common');
|
||||||
|
|
||||||
|
@ -5430,62 +5430,64 @@ function Ace2Inner(){
|
||||||
return documentAttributeManager.setAttributesOnRange.apply(documentAttributeManager, arguments);
|
return documentAttributeManager.setAttributesOnRange.apply(documentAttributeManager, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function(){
|
this.init = function () {
|
||||||
doc = document; // defined as a var in scope outside
|
$(document).ready(function(){
|
||||||
inCallStack("setup", function()
|
doc = document; // defined as a var in scope outside
|
||||||
{
|
inCallStack("setup", function()
|
||||||
var body = doc.getElementById("innerdocbody");
|
|
||||||
root = body; // defined as a var in scope outside
|
|
||||||
if (browser.mozilla) $(root).addClass("mozilla");
|
|
||||||
if (browser.safari) $(root).addClass("safari");
|
|
||||||
if (browser.msie) $(root).addClass("msie");
|
|
||||||
if (browser.msie)
|
|
||||||
{
|
{
|
||||||
// cache CSS background images
|
var body = doc.getElementById("innerdocbody");
|
||||||
try
|
root = body; // defined as a var in scope outside
|
||||||
|
if (browser.mozilla) $(root).addClass("mozilla");
|
||||||
|
if (browser.safari) $(root).addClass("safari");
|
||||||
|
if (browser.msie) $(root).addClass("msie");
|
||||||
|
if (browser.msie)
|
||||||
{
|
{
|
||||||
doc.execCommand("BackgroundImageCache", false, true);
|
// cache CSS background images
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.execCommand("BackgroundImageCache", false, true);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{ /* throws an error in some IE 6 but not others! */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (e)
|
setClassPresence(root, "authorColors", true);
|
||||||
{ /* throws an error in some IE 6 but not others! */
|
setClassPresence(root, "doesWrap", doesWrap);
|
||||||
}
|
|
||||||
}
|
|
||||||
setClassPresence(root, "authorColors", true);
|
|
||||||
setClassPresence(root, "doesWrap", doesWrap);
|
|
||||||
|
|
||||||
initDynamicCSS();
|
initDynamicCSS();
|
||||||
|
|
||||||
enforceEditability();
|
enforceEditability();
|
||||||
|
|
||||||
// set up dom and rep
|
// set up dom and rep
|
||||||
while (root.firstChild) root.removeChild(root.firstChild);
|
while (root.firstChild) root.removeChild(root.firstChild);
|
||||||
var oneEntry = createDomLineEntry("");
|
var oneEntry = createDomLineEntry("");
|
||||||
doRepLineSplice(0, rep.lines.length(), [oneEntry]);
|
doRepLineSplice(0, rep.lines.length(), [oneEntry]);
|
||||||
insertDomLines(null, [oneEntry.domInfo], null);
|
insertDomLines(null, [oneEntry.domInfo], null);
|
||||||
rep.alines = Changeset.splitAttributionLines(
|
rep.alines = Changeset.splitAttributionLines(
|
||||||
Changeset.makeAttribution("\n"), "\n");
|
Changeset.makeAttribution("\n"), "\n");
|
||||||
|
|
||||||
bindTheEventHandlers();
|
bindTheEventHandlers();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
hooks.callAll('aceInitialized', {
|
hooks.callAll('aceInitialized', {
|
||||||
editorInfo: editorInfo,
|
editorInfo: editorInfo,
|
||||||
rep: rep,
|
rep: rep,
|
||||||
documentAttributeManager: documentAttributeManager
|
documentAttributeManager: documentAttributeManager
|
||||||
});
|
});
|
||||||
|
|
||||||
scheduler.setTimeout(function()
|
scheduler.setTimeout(function()
|
||||||
{
|
{
|
||||||
parent.readyFunc(); // defined in code that sets up the inner iframe
|
parent.readyFunc(); // defined in code that sets up the inner iframe
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
isSetUp = true;
|
isSetUp = true;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that plugins are loaded before initializing the editor
|
exports.init = function () {
|
||||||
plugins.ensure(function () {
|
var editor = new Ace2Inner()
|
||||||
var editor = new Ace2Inner();
|
editor.init();
|
||||||
});
|
};
|
||||||
|
|
|
@ -249,13 +249,13 @@ var padeditbar = (function()
|
||||||
{
|
{
|
||||||
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
|
var basePath = document.location.href.substring(0, document.location.href.indexOf("/p/"));
|
||||||
var readonlyLink = basePath + "/p/" + clientVars.readOnlyId;
|
var readonlyLink = basePath + "/p/" + clientVars.readOnlyId;
|
||||||
$('#embedinput').val("<iframe name='embed_readonly' src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
|
$('#embedinput').val("<iframe name='embed_readonly' src='" + readonlyLink + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400></iframe>");
|
||||||
$('#linkinput').val(readonlyLink);
|
$('#linkinput').val(readonlyLink);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var padurl = window.location.href.split("?")[0];
|
var padurl = window.location.href.split("?")[0];
|
||||||
$('#embedinput').val("<iframe name='embed_readwrite' src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400>");
|
$('#embedinput').val("<iframe name='embed_readwrite' src='" + padurl + "?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false' width=600 height=400></iframe>");
|
||||||
$('#linkinput').val(padurl);
|
$('#linkinput').val(padurl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue