Merge pull request #1811 from clkao/author-style-hook

Document author style hook and provide outer_ace dynamic css manager
This commit is contained in:
John McLear 2013-06-15 00:17:09 -07:00
commit ae78c6731d
4 changed files with 125 additions and 89 deletions

View file

@ -261,3 +261,18 @@ This hook is provided to allow whether a given line should be deliniated with mu
Multiple authors in one line cause the creation of magic span lines. This might not suit you and 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. now you can disable it and handle your own deliniation.
The return value should be either true(disable) or false. The return value should be either true(disable) or false.
## aceSetAuthorStyle
Called from: src/static/js/ace2_inner.js
Things in context:
1. dynamicCSS - css manger for inner ace
2. outerDynamicCSS - css manager for outer ace
3. parentDynamicCSS - css manager for parent document
4. info - author style info
5. author - author info
6. authorSelector - css selector for author span in inner ace
This hook is provided to allow author highlight style to be modified.
Registered hooks should return 1 if the plugin handles highlighting. If no plugin returns 1, the core will use the default background-based highlighting.

View file

@ -1,5 +1,5 @@
/** /**
* This code is mostly from the old Etherpad. Please help us to comment this code. * This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it. * This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/ */
@ -86,7 +86,7 @@ function Ace2Editor()
}); });
actionsPendingInit = []; actionsPendingInit = [];
} }
ace2.registry[info.id] = info; ace2.registry[info.id] = info;
// The following functions (prefixed by 'ace_') are exposed by editor, but // The following functions (prefixed by 'ace_') are exposed by editor, but
@ -97,7 +97,7 @@ function Ace2Editor()
'applyChangesToBase', 'applyPreparedChangesetToBase', 'applyChangesToBase', 'applyPreparedChangesetToBase',
'setUserChangeNotificationCallback', 'setAuthorInfo', 'setUserChangeNotificationCallback', 'setAuthorInfo',
'setAuthorSelectionRange', 'callWithAce', 'execCommand', 'replaceRange']; 'setAuthorSelectionRange', 'callWithAce', 'execCommand', 'replaceRange'];
_.each(aceFunctionsPendingInit, function(fnName,i){ _.each(aceFunctionsPendingInit, function(fnName,i){
var prefix = 'ace_'; var prefix = 'ace_';
var name = prefix + fnName; var name = prefix + fnName;
@ -105,18 +105,18 @@ function Ace2Editor()
info[prefix + fnName].apply(this, arguments); info[prefix + fnName].apply(this, arguments);
}); });
}); });
editor.exportText = function() editor.exportText = function()
{ {
if (!loaded) return "(awaiting init)\n"; if (!loaded) return "(awaiting init)\n";
return info.ace_exportText(); return info.ace_exportText();
}; };
editor.getFrame = function() editor.getFrame = function()
{ {
return info.frame || null; return info.frame || null;
}; };
editor.getDebugProperty = function(prop) editor.getDebugProperty = function(prop)
{ {
return info.ace_getDebugProperty(prop); return info.ace_getDebugProperty(prop);
@ -221,16 +221,16 @@ function Ace2Editor()
// calls to these functions ($$INCLUDE_...) are replaced when this file is processed // calls to these functions ($$INCLUDE_...) are replaced when this file is processed
// and compressed, putting the compressed code from the named file directly into the // and compressed, putting the compressed code from the named file directly into the
// source here. // source here.
// these lines must conform to a specific format because they are passed by the build script: // these lines must conform to a specific format because they are passed by the build script:
var includedCSS = []; var includedCSS = [];
var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)}; var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)};
$$INCLUDE_CSS("../static/css/iframe_editor.css"); $$INCLUDE_CSS("../static/css/iframe_editor.css");
$$INCLUDE_CSS("../static/css/pad.css"); $$INCLUDE_CSS("../static/css/pad.css");
$$INCLUDE_CSS("../static/custom/pad.css"); $$INCLUDE_CSS("../static/custom/pad.css");
var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){ return '../static/plugins/' + path }); var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){ return '../static/plugins/' + path });
includedCSS = includedCSS.concat(additionalCSS); includedCSS = includedCSS.concat(additionalCSS);
pushStyleTagsFor(iframeHTML, includedCSS); pushStyleTagsFor(iframeHTML, includedCSS);
if (!Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) { if (!Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) {
@ -304,16 +304,16 @@ window.onload = function () {\n\
$$INCLUDE_CSS("../static/css/iframe_editor.css"); $$INCLUDE_CSS("../static/css/iframe_editor.css");
$$INCLUDE_CSS("../static/css/pad.css"); $$INCLUDE_CSS("../static/css/pad.css");
$$INCLUDE_CSS("../static/custom/pad.css"); $$INCLUDE_CSS("../static/custom/pad.css");
var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){ return '../static/plugins/' + path }); var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){ return '../static/plugins/' + path });
includedCSS = includedCSS.concat(additionalCSS); includedCSS = includedCSS.concat(additionalCSS);
pushStyleTagsFor(outerHTML, includedCSS); pushStyleTagsFor(outerHTML, includedCSS);
// 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,"/>', scriptTag(outerScript), '</head><body id="outerdocbody"><div id="sidediv"><!-- --></div><div id="linemetricsdiv">x</div><div id="overlaysdiv"><!-- --></div></body></html>'); outerHTML.push('<style type="text/css" title="dynamicsyntax"></style>', '<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";

View file

@ -1,5 +1,5 @@
/** /**
* This code is mostly from the old Etherpad. Please help us to comment this code. * This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it. * This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/ */
@ -36,10 +36,10 @@ var isNodeText = Ace2Common.isNodeText,
htmlPrettyEscape = Ace2Common.htmlPrettyEscape, htmlPrettyEscape = Ace2Common.htmlPrettyEscape,
noop = Ace2Common.noop; noop = Ace2Common.noop;
var hooks = require('./pluginfw/hooks'); var hooks = require('./pluginfw/hooks');
function Ace2Inner(){ function Ace2Inner(){
var makeChangesetTracker = require('./changesettracker').makeChangesetTracker; var makeChangesetTracker = require('./changesettracker').makeChangesetTracker;
var colorutils = require('./colorutils').colorutils; var colorutils = require('./colorutils').colorutils;
var makeContentCollector = require('./contentcollector').makeContentCollector; var makeContentCollector = require('./contentcollector').makeContentCollector;
@ -53,9 +53,9 @@ function Ace2Inner(){
var undoModule = require('./undomodule').undoModule; var undoModule = require('./undomodule').undoModule;
var makeVirtualLineView = require('./virtual_lines').makeVirtualLineView; var makeVirtualLineView = require('./virtual_lines').makeVirtualLineView;
var AttributeManager = require('./AttributeManager'); var AttributeManager = require('./AttributeManager');
var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;" var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;"
// changed to false // changed to false
var isSetUp = false; var isSetUp = false;
var THE_TAB = ' '; //4 var THE_TAB = ' '; //4
@ -83,9 +83,9 @@ function Ace2Inner(){
initLineNumbers(); initLineNumbers();
var outsideKeyDown = noop; var outsideKeyDown = noop;
var outsideKeyPress = function(){return true;}; var outsideKeyPress = function(){return true;};
var outsideNotifyDirty = noop; var outsideNotifyDirty = noop;
// selFocusAtStart -- determines whether the selection extends "backwards", so that the focus // selFocusAtStart -- determines whether the selection extends "backwards", so that the focus
@ -101,7 +101,7 @@ function Ace2Inner(){
alines: [], alines: [],
apool: new AttribPool() apool: new AttribPool()
}; };
// lines, alltext, alines, and DOM are set up in setup() // lines, alltext, alines, and DOM are set up in setup()
if (undoModule.enabled) if (undoModule.enabled)
{ {
@ -113,7 +113,7 @@ function Ace2Inner(){
var doesWrap = true; var doesWrap = true;
var hasLineNumbers = true; var hasLineNumbers = true;
var isStyled = true; var isStyled = true;
// space around the innermost iframe element // space around the innermost iframe element
var iframePadLeft = MIN_LINEDIV_WIDTH + LINE_NUMBER_PADDING_RIGHT + EDIT_BODY_PADDING_LEFT; var iframePadLeft = MIN_LINEDIV_WIDTH + LINE_NUMBER_PADDING_RIGHT + EDIT_BODY_PADDING_LEFT;
var iframePadTop = EDIT_BODY_PADDING_TOP; var iframePadTop = EDIT_BODY_PADDING_TOP;
@ -122,7 +122,7 @@ function Ace2Inner(){
var console = (DEBUG && window.console); var console = (DEBUG && window.console);
var documentAttributeManager; var documentAttributeManager;
if (!window.console) if (!window.console)
{ {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
@ -159,7 +159,7 @@ function Ace2Inner(){
var textFace = 'monospace'; var textFace = 'monospace';
var textSize = 12; var textSize = 12;
function textLineHeight() function textLineHeight()
{ {
@ -167,12 +167,14 @@ function Ace2Inner(){
} }
var dynamicCSS = null; var dynamicCSS = null;
var outerDynamicCSS = null;
var parentDynamicCSS = null; var parentDynamicCSS = null;
function initDynamicCSS() function initDynamicCSS()
{ {
dynamicCSS = makeCSSManager("dynamicsyntax"); dynamicCSS = makeCSSManager("dynamicsyntax");
parentDynamicCSS = makeCSSManager("dynamicsyntax", true); outerDynamicCSS = makeCSSManager("dynamicsyntax", "outer");
parentDynamicCSS = makeCSSManager("dynamicsyntax", "parent");
} }
var changesetTracker = makeChangesetTracker(scheduler, rep.apool, { var changesetTracker = makeChangesetTracker(scheduler, rep.apool, {
@ -218,6 +220,7 @@ function Ace2Inner(){
var authorStyleSet = hooks.callAll('aceSetAuthorStyle', { var authorStyleSet = hooks.callAll('aceSetAuthorStyle', {
dynamicCSS: dynamicCSS, dynamicCSS: dynamicCSS,
parentDynamicCSS: parentDynamicCSS, parentDynamicCSS: parentDynamicCSS,
outerDynamicCSS: outerDynamicCSS,
info: info, info: info,
author: author, author: author,
authorSelector: authorSelector, authorSelector: authorSelector,
@ -562,8 +565,8 @@ function Ace2Inner(){
{ {
return rep.lines.atOffset(charOffset).key; return rep.lines.atOffset(charOffset).key;
} }
function dispose() function dispose()
{ {
disposed = true; disposed = true;
@ -918,14 +921,14 @@ function Ace2Inner(){
editorInfo.ace_doReturnKey = doReturnKey; editorInfo.ace_doReturnKey = doReturnKey;
editorInfo.ace_isBlockElement = isBlockElement; editorInfo.ace_isBlockElement = isBlockElement;
editorInfo.ace_getLineListType = getLineListType; editorInfo.ace_getLineListType = getLineListType;
editorInfo.ace_callWithAce = function(fn, callStack, normalize) editorInfo.ace_callWithAce = function(fn, callStack, normalize)
{ {
var wrapper = function() var wrapper = function()
{ {
return fn(editorInfo); return fn(editorInfo);
}; };
if (normalize !== undefined) if (normalize !== undefined)
{ {
var wrapper1 = wrapper; var wrapper1 = wrapper;
@ -951,14 +954,14 @@ function Ace2Inner(){
// @param value the value to set to // @param value the value to set to
editorInfo.ace_setProperty = function(key, value) editorInfo.ace_setProperty = function(key, value)
{ {
// Convinience function returning a setter for a class on an element // Convinience function returning a setter for a class on an element
var setClassPresenceNamed = function(element, cls){ var setClassPresenceNamed = function(element, cls){
return function(value){ return function(value){
setClassPresence(element, cls, !! value) setClassPresence(element, cls, !! value)
} }
}; };
// These properties are exposed // These properties are exposed
var setters = { var setters = {
wraps: setWraps, wraps: setWraps,
@ -973,7 +976,7 @@ function Ace2Inner(){
}, },
grayedout: setClassPresenceNamed(outerWin.document.body, "grayedout"), grayedout: setClassPresenceNamed(outerWin.document.body, "grayedout"),
dmesg: function(){ dmesg = window.dmesg = value; }, dmesg: function(){ dmesg = window.dmesg = value; },
userauthor: function(value){ userauthor: function(value){
thisAuthor = String(value); thisAuthor = String(value);
documentAttributeManager.author = thisAuthor; documentAttributeManager.author = thisAuthor;
}, },
@ -986,10 +989,10 @@ function Ace2Inner(){
document.documentElement.dir = value? 'rtl' : 'ltr' document.documentElement.dir = value? 'rtl' : 'ltr'
} }
}; };
var setter = setters[key.toLowerCase()]; var setter = setters[key.toLowerCase()];
// check if setter is present // check if setter is present
if(setter !== undefined){ if(setter !== undefined){
setter(value) setter(value)
} }
@ -1098,7 +1101,7 @@ function Ace2Inner(){
return false; return false;
} }
}; };
isTimeUp.elapsed = function() isTimeUp.elapsed = function()
{ {
return now() - startTime; return now() - startTime;
@ -1479,7 +1482,7 @@ function Ace2Inner(){
var p = PROFILER("getSelection", false); var p = PROFILER("getSelection", false);
var selection = getSelection(); var selection = getSelection();
p.end(); p.end();
function topLevel(n) function topLevel(n)
{ {
if ((!n) || n == root) return null; if ((!n) || n == root) return null;
@ -1489,7 +1492,7 @@ function Ace2Inner(){
} }
return n; return n;
} }
if (selection) if (selection)
{ {
var node1 = topLevel(selection.startPoint.node); var node1 = topLevel(selection.startPoint.node);
@ -1747,7 +1750,7 @@ function Ace2Inner(){
root:root, root:root,
point:selection.startPoint, point:selection.startPoint,
documentAttributeManager: documentAttributeManager documentAttributeManager: documentAttributeManager
}); });
selStart = (selStartFromHook==null||selStartFromHook.length==0)?getLineAndCharForPoint(selection.startPoint):selStartFromHook; selStart = (selStartFromHook==null||selStartFromHook.length==0)?getLineAndCharForPoint(selection.startPoint):selStartFromHook;
} }
if (selection && !selEnd) if (selection && !selEnd)
@ -1760,7 +1763,7 @@ function Ace2Inner(){
point:selection.endPoint, point:selection.endPoint,
documentAttributeManager: documentAttributeManager documentAttributeManager: documentAttributeManager
}); });
selEnd = (selEndFromHook==null||selEndFromHook.length==0)?getLineAndCharForPoint(selection.endPoint):selEndFromHook; selEnd = (selEndFromHook==null||selEndFromHook.length==0)?getLineAndCharForPoint(selection.endPoint):selEndFromHook;
} }
// selection from content collection can, in various ways, extend past final // selection from content collection can, in various ways, extend past final
@ -1781,7 +1784,7 @@ function Ace2Inner(){
// update rep if we have a new selection // update rep if we have a new selection
// NOTE: IE loses the selection when you click stuff in e.g. the // NOTE: IE loses the selection when you click stuff in e.g. the
// editbar, so removing the selection when it's lost is not a good // editbar, so removing the selection when it's lost is not a good
// idea. // idea.
if (selection) repSelectionChange(selStart, selEnd, selection && selection.focusAtStart); if (selection) repSelectionChange(selStart, selEnd, selection && selection.focusAtStart);
// update browser selection // update browser selection
p.mark("browsel"); p.mark("browsel");
@ -1916,19 +1919,19 @@ function Ace2Inner(){
return rep.selStart[0]; return rep.selStart[0];
} }
editorInfo.ace_caretLine = caretLine; editorInfo.ace_caretLine = caretLine;
function caretColumn() function caretColumn()
{ {
return rep.selStart[1]; return rep.selStart[1];
} }
editorInfo.ace_caretColumn = caretColumn; editorInfo.ace_caretColumn = caretColumn;
function caretDocChar() function caretDocChar()
{ {
return rep.lines.offsetOfIndex(caretLine()) + caretColumn(); return rep.lines.offsetOfIndex(caretLine()) + caretColumn();
} }
editorInfo.ace_caretDocChar = caretDocChar; editorInfo.ace_caretDocChar = caretDocChar;
function handleReturnIndentation() function handleReturnIndentation()
{ {
// on return, indent to level of previous line // on return, indent to level of previous line
@ -2357,8 +2360,8 @@ function Ace2Inner(){
documentAttributeManager.setAttributesOnRange(lineAndColumnFromChar(start), lineAndColumnFromChar(end), attribs); documentAttributeManager.setAttributesOnRange(lineAndColumnFromChar(start), lineAndColumnFromChar(end), attribs);
} }
editorInfo.ace_performDocumentApplyAttributesToCharRange = performDocumentApplyAttributesToCharRange; editorInfo.ace_performDocumentApplyAttributesToCharRange = performDocumentApplyAttributesToCharRange;
function setAttributeOnSelection(attributeName, attributeValue) function setAttributeOnSelection(attributeName, attributeValue)
{ {
if (!(rep.selStart && rep.selEnd)) return; if (!(rep.selStart && rep.selEnd)) return;
@ -2921,7 +2924,7 @@ function Ace2Inner(){
{ {
if (lineClass !== null) lineElem.className = lineClass; if (lineClass !== null) lineElem.className = lineClass;
}; };
result.prepareForAdd = writeClass; result.prepareForAdd = writeClass;
result.finishUpdate = writeClass; result.finishUpdate = writeClass;
result.getInnerHTML = function() result.getInnerHTML = function()
@ -3283,7 +3286,7 @@ function Ace2Inner(){
{ {
return (n.tagName || '').toLowerCase() == "a" && n.href; return (n.tagName || '').toLowerCase() == "a" && n.href;
} }
// only want to catch left-click // only want to catch left-click
if ((!evt.ctrlKey) && (evt.button != 2) && (evt.button != 3)) if ((!evt.ctrlKey) && (evt.button != 2) && (evt.button != 3))
{ {
@ -3319,7 +3322,7 @@ function Ace2Inner(){
{ {
return; return;
} }
var lineNum = rep.selStart[0]; var lineNum = rep.selStart[0];
var listType = getLineListType(lineNum); var listType = getLineListType(lineNum);
@ -3444,9 +3447,9 @@ function Ace2Inner(){
var thisLineListType = getLineListType(theLine); var thisLineListType = getLineListType(theLine);
var prevLineEntry = (theLine > 0 && rep.lines.atIndex(theLine - 1)); var prevLineEntry = (theLine > 0 && rep.lines.atIndex(theLine - 1));
var prevLineBlank = (prevLineEntry && prevLineEntry.text.length == prevLineEntry.lineMarker); var prevLineBlank = (prevLineEntry && prevLineEntry.text.length == prevLineEntry.lineMarker);
var thisLineHasMarker = documentAttributeManager.lineHasMarker(theLine); var thisLineHasMarker = documentAttributeManager.lineHasMarker(theLine);
if (thisLineListType) if (thisLineListType)
{ {
// this line is a list // this line is a list
@ -3521,7 +3524,7 @@ function Ace2Inner(){
return !!REGEX_WORDCHAR.exec(c); return !!REGEX_WORDCHAR.exec(c);
} }
editorInfo.ace_isWordChar = isWordChar; editorInfo.ace_isWordChar = isWordChar;
function isSpaceChar(c) function isSpaceChar(c)
{ {
return !!REGEX_SPACE.exec(c); return !!REGEX_SPACE.exec(c);
@ -4151,7 +4154,7 @@ function Ace2Inner(){
maxIndex: tn.nodeValue.length maxIndex: tn.nodeValue.length
}; };
}; };
var selection = {}; var selection = {};
if (origSelectionRange.compareEndPoints("StartToEnd", origSelectionRange) === 0) if (origSelectionRange.compareEndPoints("StartToEnd", origSelectionRange) === 0)
{ {
@ -4255,7 +4258,7 @@ function Ace2Inner(){
selection.startPoint = pointFromRangeBound(range.startContainer, range.startOffset); selection.startPoint = pointFromRangeBound(range.startContainer, range.startOffset);
selection.endPoint = pointFromRangeBound(range.endContainer, range.endOffset); selection.endPoint = pointFromRangeBound(range.endContainer, range.endOffset);
selection.focusAtStart = (((range.startContainer != range.endContainer) || (range.startOffset != range.endOffset)) && browserSelection.anchorNode && (browserSelection.anchorNode == range.endContainer) && (browserSelection.anchorOffset == range.endOffset)); selection.focusAtStart = (((range.startContainer != range.endContainer) || (range.startOffset != range.endOffset)) && browserSelection.anchorNode && (browserSelection.anchorNode == range.endContainer) && (browserSelection.anchorOffset == range.endOffset));
if(selection.startPoint.node.ownerDocument !== window.document){ if(selection.startPoint.node.ownerDocument !== window.document){
return null; return null;
} }
@ -5020,9 +5023,9 @@ function Ace2Inner(){
} }
} }
} }
var listAttributeName = 'list'; var listAttributeName = 'list';
function getLineListType(lineNum) function getLineListType(lineNum)
{ {
return documentAttributeManager.getAttributeOnLine(lineNum, listAttributeName) return documentAttributeManager.getAttributeOnLine(lineNum, listAttributeName)
@ -5035,7 +5038,7 @@ function Ace2Inner(){
}else{ }else{
documentAttributeManager.setAttributeOnLine(lineNum, listAttributeName, listType); documentAttributeManager.setAttributeOnLine(lineNum, listAttributeName, listType);
} }
//if the list has been removed, it is necessary to renumber //if the list has been removed, it is necessary to renumber
//starting from the *next* line because the list may have been //starting from the *next* line because the list may have been
//separated. If it returns null, it means that the list was not cut, try //separated. If it returns null, it means that the list was not cut, try
@ -5045,7 +5048,7 @@ function Ace2Inner(){
renumberList(lineNum); renumberList(lineNum);
} }
} }
function renumberList(lineNum){ function renumberList(lineNum){
//1-check we are in a list //1-check we are in a list
var type = getLineListType(lineNum); var type = getLineListType(lineNum);
@ -5058,7 +5061,7 @@ function Ace2Inner(){
{ {
return null; return null;
} }
//2-find the first line of the list //2-find the first line of the list
while(lineNum-1 >= 0 && (type=getLineListType(lineNum-1))) while(lineNum-1 >= 0 && (type=getLineListType(lineNum-1)))
{ {
@ -5067,7 +5070,7 @@ function Ace2Inner(){
break; break;
lineNum--; lineNum--;
} }
//3-renumber every list item of the same level from the beginning, level 1 //3-renumber every list item of the same level from the beginning, level 1
//IMPORTANT: never skip a level because there imbrication may be arbitrary //IMPORTANT: never skip a level because there imbrication may be arbitrary
var builder = Changeset.builder(rep.lines.totalWidth()); var builder = Changeset.builder(rep.lines.totalWidth());
@ -5094,7 +5097,7 @@ function Ace2Inner(){
ChangesetUtils.buildKeepRange(rep, builder, loc, (loc = [line, 1]), [ ChangesetUtils.buildKeepRange(rep, builder, loc, (loc = [line, 1]), [
['start', position] ['start', position]
], rep.apool); ], rep.apool);
position++; position++;
line++; line++;
} }
@ -5109,19 +5112,19 @@ function Ace2Inner(){
} }
return line; return line;
} }
applyNumberList(lineNum, 1); applyNumberList(lineNum, 1);
var cs = builder.toString(); var cs = builder.toString();
if (!Changeset.isIdentity(cs)) if (!Changeset.isIdentity(cs))
{ {
performDocumentApplyChangeset(cs); performDocumentApplyChangeset(cs);
} }
//4-apply the modifications //4-apply the modifications
} }
function doInsertList(type) function doInsertList(type)
{ {
@ -5159,7 +5162,7 @@ function Ace2Inner(){
var t = getLineListType(n); var t = getLineListType(n);
mods.push([n, allLinesAreList ? 'indent' + level : (t ? type + level : type + '1')]); mods.push([n, allLinesAreList ? 'indent' + level : (t ? type + level : type + '1')]);
} }
_.each(mods, function(mod){ _.each(mods, function(mod){
setLineListType(mod[0], mod[1]); setLineListType(mod[0], mod[1]);
}); });
@ -5173,7 +5176,7 @@ function Ace2Inner(){
} }
editorInfo.ace_doInsertUnorderedList = doInsertUnorderedList; editorInfo.ace_doInsertUnorderedList = doInsertUnorderedList;
editorInfo.ace_doInsertOrderedList = doInsertOrderedList; editorInfo.ace_doInsertOrderedList = doInsertOrderedList;
var lineNumbersShown; var lineNumbersShown;
var sideDivInner; var sideDivInner;
@ -5189,11 +5192,11 @@ function Ace2Inner(){
var newNumLines = rep.lines.length(); var newNumLines = rep.lines.length();
if (newNumLines < 1) newNumLines = 1; if (newNumLines < 1) newNumLines = 1;
//update height of all current line numbers //update height of all current line numbers
var a = sideDivInner.firstChild; var a = sideDivInner.firstChild;
var b = doc.body.firstChild; var b = doc.body.firstChild;
var n = 0; var n = 0;
if (currentCallStack && currentCallStack.domClean) if (currentCallStack && currentCallStack.domClean)
{ {
@ -5222,8 +5225,8 @@ function Ace2Inner(){
b = b.nextSibling; b = b.nextSibling;
n++; n++;
} }
} }
if (newNumLines != lineNumbersShown) if (newNumLines != lineNumbersShown)
{ {
var container = sideDivInner; var container = sideDivInner;
@ -5233,27 +5236,27 @@ function Ace2Inner(){
{ {
lineNumbersShown++; lineNumbersShown++;
var n = lineNumbersShown; var n = lineNumbersShown;
var div = odoc.createElement("DIV"); var div = odoc.createElement("DIV");
//calculate height for new line number //calculate height for new line number
if(b){ if(b){
var h = (b.clientHeight || b.offsetHeight); var h = (b.clientHeight || b.offsetHeight);
if (b.nextSibling){ if (b.nextSibling){
h = b.nextSibling.offsetTop - b.offsetTop; h = b.nextSibling.offsetTop - b.offsetTop;
} }
} }
if(h){ // apply style to div if(h){ // apply style to div
div.style.height = h +"px"; div.style.height = h +"px";
} }
div.appendChild(odoc.createTextNode(String(n))); div.appendChild(odoc.createTextNode(String(n)));
fragment.appendChild(div); fragment.appendChild(div);
if(b){ if(b){
b = b.nextSibling; b = b.nextSibling;
} }
} }
container.appendChild(fragment); container.appendChild(fragment);
while (lineNumbersShown > newNumLines) while (lineNumbersShown > newNumLines)
{ {
@ -5262,8 +5265,8 @@ function Ace2Inner(){
} }
} }
} }
// Init documentAttributeManager // Init documentAttributeManager
documentAttributeManager = new AttributeManager(rep, performDocumentApplyChangeset); documentAttributeManager = new AttributeManager(rep, performDocumentApplyChangeset);
editorInfo.ace_performDocumentApplyAttributesToRange = function () { editorInfo.ace_performDocumentApplyAttributesToRange = function () {
@ -5309,13 +5312,13 @@ function Ace2Inner(){
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

View file

@ -1,5 +1,5 @@
/** /**
* This code is mostly from the old Etherpad. Please help us to comment this code. * This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it. * This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/ */
@ -20,14 +20,32 @@
* limitations under the License. * limitations under the License.
*/ */
function makeCSSManager(emptyStylesheetTitle, parentCss) function makeCSSManager(emptyStylesheetTitle, doc)
{ {
if (doc === true)
{
doc = 'parent';
} else if (!doc) {
doc = 'inner';
}
function getSheetByTitle(title) function getSheetByTitle(title)
{ {
if (parentCss) var allSheets = window.parent.parent.document.styleSheets; if (doc === 'parent')
else var allSheets = document.styleSheets; {
win = window.parent.parent;
}
else if (doc === 'inner') {
win = window;
}
else if (doc === 'outer') {
win = window.parent;
}
else {
throw "Unknown dynamic style container";
}
var allSheets = win.document.styleSheets;
for (var i = 0; i < allSheets.length; i++) for (var i = 0; i < allSheets.length; i++)
{ {
var s = allSheets[i]; var s = allSheets[i];
@ -38,8 +56,8 @@ function makeCSSManager(emptyStylesheetTitle, parentCss)
} }
return null; return null;
} }
var browserSheet = getSheetByTitle(emptyStylesheetTitle, parentCss); var browserSheet = getSheetByTitle(emptyStylesheetTitle);
function browserRules() function browserRules()
{ {