added AttributeManager, ChangesetUtils
parent
6c647baa02
commit
23cda77b65
|
@ -56,6 +56,7 @@
|
|||
, "rjquery.js"
|
||||
, "AttributePool.js"
|
||||
, "Changeset.js"
|
||||
, "ChangesetUtils.js"
|
||||
, "security.js"
|
||||
, "skiplist.js"
|
||||
, "virtual_lines.js"
|
||||
|
@ -66,6 +67,7 @@
|
|||
, "changesettracker.js"
|
||||
, "linestylefilter.js"
|
||||
, "domline.js"
|
||||
, "AttributeManager.js"
|
||||
, "ace2_inner.js"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
var Changeset = require('./Changeset');
|
||||
var ChangesetUtils = require('./ChangesetUtils');
|
||||
var _ = require('./underscore');
|
||||
|
||||
var AttributeManager = function(rep, applyChangesetCallback)
|
||||
{
|
||||
this.rep = rep;
|
||||
this.applyChangesetCallback = applyChangesetCallback;
|
||||
this.author = '';
|
||||
};
|
||||
|
||||
AttributeManager.prototype = _(AttributeManager.prototype).extend({
|
||||
|
||||
applyChangeset: function(changeset){
|
||||
var cs = changeset.toString();
|
||||
if (!Changeset.isIdentity(cs))
|
||||
{
|
||||
this.applyChangesetCallback(cs);
|
||||
}
|
||||
},
|
||||
|
||||
lineHasMarker: function(lineNum){
|
||||
// get "list" attribute of first char of line
|
||||
return this.getAttributeOnLine(lineNum, 'list');
|
||||
},
|
||||
|
||||
getAttributeOnLine: function(lineNum, attributeName){
|
||||
// get `attributeName` attribute of first char of line
|
||||
var aline = this.rep.alines[lineNum];
|
||||
if (aline)
|
||||
{
|
||||
var opIter = Changeset.opIterator(aline);
|
||||
if (opIter.hasNext())
|
||||
{
|
||||
return Changeset.opAttributeValue(opIter.next(), attributeName, this.rep.apool) || '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/*
|
||||
Sets a specified attribute on a line
|
||||
@param lineNum: the number of the line to set the attribute for
|
||||
@param attributeKey: the name of the attribute to set, e.g. list
|
||||
@param attributeValue: an optional parameter to pass to the attribute (e.g. indention level)
|
||||
|
||||
*/
|
||||
setAttributeOnLine: function(lineNum, attributeName, attributeValue){
|
||||
var loc = [0,0];
|
||||
var builder = Changeset.builder(this.rep.lines.totalWidth());
|
||||
var hasMarker = this.lineHasMarker(lineNum);
|
||||
|
||||
ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));
|
||||
|
||||
if(hasMarker){
|
||||
ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 1]), [
|
||||
[attributeName, attributeValue]
|
||||
], this.rep.apool);
|
||||
}else{
|
||||
// add a line marker
|
||||
builder.insert('*', [
|
||||
['author', this.author],
|
||||
['insertorder', 'first'],
|
||||
[attributeName, attributeValue]
|
||||
], this.rep.apool);
|
||||
}
|
||||
|
||||
return this.applyChangeset(builder);
|
||||
},
|
||||
|
||||
/*
|
||||
Removes a specified attribute on a line
|
||||
@param lineNum: the number of the affected line
|
||||
@param attributeKey: the name of the attribute to remove, e.g. list
|
||||
|
||||
*/
|
||||
removeAttributeOnLine: function(lineNum, attributeName, attributeValue){
|
||||
|
||||
var loc = [0,0];
|
||||
var builder = Changeset.builder(this.rep.lines.totalWidth());
|
||||
var hasMarker = this.lineHasMarker(lineNum);
|
||||
|
||||
// TODO
|
||||
|
||||
if(hasMarker){
|
||||
ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]), [
|
||||
[attributeName, attributeValue]
|
||||
], this.rep.apool);
|
||||
ChangesetUtils.buildRemoveRange(this.rep, builder, loc, (loc = [lineNum, 1]));
|
||||
}
|
||||
|
||||
return this.applyChangeset(builder);
|
||||
},
|
||||
|
||||
/*
|
||||
Sets a specified attribute on a line
|
||||
@param lineNum: the number of the line to set the attribute for
|
||||
@param attributeKey: the name of the attribute to set, e.g. list
|
||||
@param attributeValue: an optional parameter to pass to the attribute (e.g. indention level)
|
||||
*/
|
||||
toggleAttributeOnLine: function(lineNum, attributeName, attributeValue) {
|
||||
return this.getAttributeOnLine(attributeName) ?
|
||||
this.removeAttributeOnLine(lineNum, attributeName) :
|
||||
this.setAttributeOnLine(lineNum, attributeName, attributeValue);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = AttributeManager;
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* This module contains several helper Functions to build Changesets
|
||||
* based on a SkipList
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
exports.buildRemoveRange = function(rep, builder, start, end)
|
||||
{
|
||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
||||
|
||||
if (end[0] > start[0])
|
||||
{
|
||||
builder.remove(endLineOffset - startLineOffset - start[1], end[0] - start[0]);
|
||||
builder.remove(end[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.remove(end[1] - start[1]);
|
||||
}
|
||||
}
|
||||
|
||||
exports.buildKeepRange = function(rep, builder, start, end, attribs, pool)
|
||||
{
|
||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
||||
|
||||
if (end[0] > start[0])
|
||||
{
|
||||
builder.keep(endLineOffset - startLineOffset - start[1], end[0] - start[0], attribs, pool);
|
||||
builder.keep(end[1], 0, attribs, pool);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.keep(end[1] - start[1], 0, attribs, pool);
|
||||
}
|
||||
}
|
||||
|
||||
exports.buildKeepToStartOfRange = function(rep, builder, start)
|
||||
{
|
||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||
|
||||
builder.keep(startLineOffset, start[0]);
|
||||
builder.keep(start[1]);
|
||||
}
|
||||
|
|
@ -45,10 +45,12 @@ function Ace2Inner(){
|
|||
var domline = require('./domline').domline;
|
||||
var AttribPool = require('./AttributePool');
|
||||
var Changeset = require('./Changeset');
|
||||
var ChangesetUtils = require('./ChangesetUtils');
|
||||
var linestylefilter = require('./linestylefilter').linestylefilter;
|
||||
var SkipList = require('./skiplist');
|
||||
var undoModule = require('./undomodule').undoModule;
|
||||
var makeVirtualLineView = require('./virtual_lines').makeVirtualLineView;
|
||||
var AttributeManager = require('./AttributeManager');
|
||||
|
||||
var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;"
|
||||
// changed to false
|
||||
|
@ -97,6 +99,7 @@ function Ace2Inner(){
|
|||
alines: [],
|
||||
apool: new AttribPool()
|
||||
};
|
||||
|
||||
// lines, alltext, alines, and DOM are set up in setup()
|
||||
if (undoModule.enabled)
|
||||
{
|
||||
|
@ -116,6 +119,7 @@ function Ace2Inner(){
|
|||
iframePadRight = 0;
|
||||
|
||||
var console = (DEBUG && window.console);
|
||||
var documentAttributeManager;
|
||||
|
||||
if (!window.console)
|
||||
{
|
||||
|
@ -152,6 +156,7 @@ function Ace2Inner(){
|
|||
|
||||
var textFace = 'monospace';
|
||||
var textSize = 12;
|
||||
|
||||
|
||||
function textLineHeight()
|
||||
{
|
||||
|
@ -926,7 +931,10 @@ function Ace2Inner(){
|
|||
},
|
||||
grayedout: setClassPresenceNamed(outerWin.document.body, "grayedout"),
|
||||
dmesg: function(){ dmesg = window.dmesg = value; },
|
||||
userauthor: function(value){ thisAuthor = String(value); },
|
||||
userauthor: function(value){
|
||||
thisAuthor = String(value);
|
||||
documentAttributeManager.author = thisAuthor;
|
||||
},
|
||||
styled: setStyled,
|
||||
textface: setTextFace,
|
||||
textsize: setTextSize,
|
||||
|
@ -2249,8 +2257,8 @@ function Ace2Inner(){
|
|||
// CCCC\n
|
||||
// end[0]: <CCC end[1] CCC>-------\n
|
||||
var builder = Changeset.builder(rep.lines.totalWidth());
|
||||
buildKeepToStartOfRange(builder, start);
|
||||
buildRemoveRange(builder, start, end);
|
||||
ChangesetUtils.buildKeepToStartOfRange(rep, builder, start);
|
||||
ChangesetUtils.buildRemoveRange(rep, builder, start, end);
|
||||
builder.insert(newText, [
|
||||
['author', thisAuthor]
|
||||
], rep.apool);
|
||||
|
@ -2272,53 +2280,16 @@ function Ace2Inner(){
|
|||
function performDocumentApplyAttributesToRange(start, end, attribs)
|
||||
{
|
||||
var builder = Changeset.builder(rep.lines.totalWidth());
|
||||
buildKeepToStartOfRange(builder, start);
|
||||
buildKeepRange(builder, start, end, attribs, rep.apool);
|
||||
ChangesetUtils.buildKeepToStartOfRange(rep, builder, start);
|
||||
ChangesetUtils.buildKeepRange(rep, builder, start, end, attribs, rep.apool);
|
||||
var cs = builder.toString();
|
||||
performDocumentApplyChangeset(cs);
|
||||
}
|
||||
editorInfo.ace_performDocumentApplyAttributesToRange = performDocumentApplyAttributesToRange;
|
||||
|
||||
function buildKeepToStartOfRange(builder, start)
|
||||
{
|
||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||
|
||||
builder.keep(startLineOffset, start[0]);
|
||||
builder.keep(start[1]);
|
||||
}
|
||||
|
||||
function buildRemoveRange(builder, start, end)
|
||||
{
|
||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
||||
|
||||
if (end[0] > start[0])
|
||||
{
|
||||
builder.remove(endLineOffset - startLineOffset - start[1], end[0] - start[0]);
|
||||
builder.remove(end[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.remove(end[1] - start[1]);
|
||||
}
|
||||
}
|
||||
|
||||
function buildKeepRange(builder, start, end, attribs, pool)
|
||||
{
|
||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
||||
|
||||
if (end[0] > start[0])
|
||||
{
|
||||
builder.keep(endLineOffset - startLineOffset - start[1], end[0] - start[0], attribs, pool);
|
||||
builder.keep(end[1], 0, attribs, pool);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.keep(end[1] - start[1], 0, attribs, pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO move to AttributeManager
|
||||
function setAttributeOnSelection(attributeName, attributeValue)
|
||||
{
|
||||
if (!(rep.selStart && rep.selEnd)) return;
|
||||
|
@ -3276,6 +3247,7 @@ function Ace2Inner(){
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lineNum = rep.selStart[0];
|
||||
var listType = getLineListType(lineNum);
|
||||
|
||||
|
@ -3347,11 +3319,9 @@ function Ace2Inner(){
|
|||
}
|
||||
}
|
||||
|
||||
if (mods.length > 0)
|
||||
{
|
||||
setLineListTypes(mods);
|
||||
}
|
||||
|
||||
_.each(mods, function(mod){
|
||||
setLineListType.apply(this, mod);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
editorInfo.ace_doIndentOutdent = doIndentOutdent;
|
||||
|
@ -4865,27 +4835,31 @@ function Ace2Inner(){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var listAttributeName = 'list';
|
||||
|
||||
function getLineListType(lineNum)
|
||||
{
|
||||
// get "list" attribute of first char of line
|
||||
var aline = rep.alines[lineNum];
|
||||
if (aline)
|
||||
{
|
||||
var opIter = Changeset.opIterator(aline);
|
||||
if (opIter.hasNext())
|
||||
{
|
||||
return Changeset.opAttributeValue(opIter.next(), 'list', rep.apool) || '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
return documentAttributeManager.getAttributeOnLine(lineNum, listAttributeName)
|
||||
}
|
||||
|
||||
function setLineListType(lineNum, listType)
|
||||
{
|
||||
setLineListTypes([
|
||||
[lineNum, listType]
|
||||
]);
|
||||
debugger;
|
||||
if(listType == ''){
|
||||
documentAttributeManager.removeAttributeOnLine(lineNum, listAttributeName);
|
||||
}else{
|
||||
documentAttributeManager.setAttributeOnLine(lineNum, listAttributeName, listType);
|
||||
}
|
||||
|
||||
//if the list has been removed, it is necessary to renumber
|
||||
//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
|
||||
//from the current one.
|
||||
if(renumberList(lineNum+1)==null)
|
||||
{
|
||||
renumberList(lineNum);
|
||||
}
|
||||
}
|
||||
|
||||
function renumberList(lineNum){
|
||||
|
@ -4932,8 +4906,8 @@ function Ace2Inner(){
|
|||
}
|
||||
else if(curLevel == level)
|
||||
{
|
||||
buildKeepRange(builder, loc, (loc = [line, 0]));
|
||||
buildKeepRange(builder, loc, (loc = [line, 1]), [
|
||||
ChangesetUtils.buildKeepRange(rep, builder, loc, (loc = [line, 0]));
|
||||
ChangesetUtils.buildKeepRange(rep, builder, loc, (loc = [line, 1]), [
|
||||
['start', position]
|
||||
], rep.apool);
|
||||
|
||||
|
@ -4964,62 +4938,6 @@ function Ace2Inner(){
|
|||
|
||||
}
|
||||
|
||||
function setLineListTypes(lineNumTypePairsInOrder)
|
||||
{
|
||||
var loc = [0, 0];
|
||||
var builder = Changeset.builder(rep.lines.totalWidth());
|
||||
for (var i = 0; i < lineNumTypePairsInOrder.length; i++)
|
||||
{
|
||||
var pair = lineNumTypePairsInOrder[i];
|
||||
var lineNum = pair[0];
|
||||
var listType = pair[1];
|
||||
buildKeepRange(builder, loc, (loc = [lineNum, 0]));
|
||||
if (getLineListType(lineNum))
|
||||
{
|
||||
// already a line marker
|
||||
if (listType)
|
||||
{
|
||||
// make different list type
|
||||
buildKeepRange(builder, loc, (loc = [lineNum, 1]), [
|
||||
['list', listType]
|
||||
], rep.apool);
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove list marker
|
||||
buildRemoveRange(builder, loc, (loc = [lineNum, 1]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// currently no line marker
|
||||
if (listType)
|
||||
{
|
||||
// add a line marker
|
||||
builder.insert('*', [
|
||||
['author', thisAuthor],
|
||||
['insertorder', 'first'],
|
||||
['list', listType]
|
||||
], rep.apool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var cs = builder.toString();
|
||||
if (!Changeset.isIdentity(cs))
|
||||
{
|
||||
performDocumentApplyChangeset(cs);
|
||||
}
|
||||
|
||||
//if the list has been removed, it is necessary to renumber
|
||||
//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
|
||||
//from the current one.
|
||||
if(renumberList(lineNum+1)==null)
|
||||
{
|
||||
renumberList(lineNum);
|
||||
}
|
||||
}
|
||||
|
||||
function doInsertList(type)
|
||||
{
|
||||
|
@ -5057,7 +4975,10 @@ function Ace2Inner(){
|
|||
var t = getLineListType(n);
|
||||
mods.push([n, allLinesAreList ? 'indent' + level : (t ? type + level : type + '1')]);
|
||||
}
|
||||
setLineListTypes(mods);
|
||||
|
||||
_.each(mods, function(mod){
|
||||
setLineListType.apply(this, mod);
|
||||
});
|
||||
}
|
||||
|
||||
function doInsertUnorderedList(){
|
||||
|
@ -5477,6 +5398,11 @@ function Ace2Inner(){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Init documentAttributeManager
|
||||
|
||||
documentAttributeManager = new AttributeManager(rep, performDocumentApplyChangeset);
|
||||
|
||||
$(document).ready(function(){
|
||||
doc = document; // defined as a var in scope outside
|
||||
|
|
Loading…
Reference in New Issue