ep_context
Advanced tools
Comparing version
@@ -9,2 +9,3 @@ { | ||
"aceAttribsToClasses": "ep_context/static/js/index", | ||
"aceAttribClasses":"ep_context/static/js/index", | ||
"aceEditEvent": "ep_context/static/js/index", | ||
@@ -18,9 +19,13 @@ "aceDomLineProcessLineAttributes": "ep_context/static/js/index", | ||
"aceEditorCSS": "ep_context/static/js/context", | ||
"acePaste": "ep_context/static/js/index" | ||
"acePaste": "ep_context/static/js/index", | ||
"aceCreateDomLine": "ep_context/static/js/index" | ||
}, | ||
"hooks": { | ||
"eejsBlock_editbarMenuLeft": "ep_context/index", | ||
"eejsBlock_timesliderBody": "ep_context/index", | ||
"collectContentPre": "ep_context/static/js/shared", | ||
"collectContentPost": "ep_context/static/js/shared", | ||
"eejsBlock_dd_format":"ep_context/index", | ||
"eejsBlock_scripts": "ep_context/index", | ||
"eejsBlock_timesliderScripts": "ep_context/index", | ||
"aceAttribClasses":"ep_context/index", | ||
@@ -27,0 +32,0 @@ "stylesForExport" : "ep_context/index", |
62
index.js
var eejs = require('ep_etherpad-lite/node/eejs/'); | ||
var Changeset = require("ep_etherpad-lite/static/js/Changeset"); | ||
var sanitize = require('./sanitizer.js').sanitize; | ||
var contexts = require("./static/js/contexts.js").contexts; | ||
var generateCSSFromContexts = require("./static/js/contexts.js").generateCSSFromContexts; | ||
var Security = require('ep_etherpad-lite/static/js/security'); | ||
var _encodeWhitespace = require('ep_etherpad-lite/node/utils/ExportHelper')._encodeWhitespace; | ||
/* | ||
var stylesCSS = [".contextTitle{text-align:center;display:block;font-size:18px;line-height:20px;}\n", | ||
@@ -11,5 +14,6 @@ ".contexttitle{text-align:center;display:block;font-size:18px;line-height:20px;}\n", | ||
]; | ||
*/ | ||
/******************** | ||
* UI | ||
* UI and CSS | ||
*/ | ||
@@ -26,3 +30,18 @@ exports.eejsBlock_editbarMenuLeft = function (hook_name, args, cb) { | ||
exports.eejsBlock_scripts = function (hook_name, args, cb) { | ||
args.content = args.content + "<script src='../static/plugins/ep_context/static/js/contexts.js'></script>"; | ||
return cb(); | ||
} | ||
exports.eejsBlock_timesliderScripts = function (hook_name, args, cb) { | ||
args.content = args.content + "<script src='../../../static/plugins/ep_context/static/js/contexts.js'></script>"; | ||
return cb(); | ||
} | ||
exports.eejsBlock_timesliderBody = function(hook_name, args, cb){ | ||
args.content = args.content + "<script>var head = $('body').append('<style>'+generateCSSFromContexts()+'</style>')</script>"; | ||
return cb(); | ||
} | ||
// timesliderStyles | ||
/******************** | ||
@@ -45,2 +64,3 @@ * Editor | ||
var css = ""; | ||
var stylesCSS = cssFromContexts(); | ||
stylesCSS.forEach(function(style){ | ||
@@ -58,4 +78,4 @@ css += "\n" + style; | ||
// line, apool,attribLine,text | ||
exports.getLineHTMLForExport = function (hook, line) { | ||
var contextV = _analyzeLine(line.attribLine, line.apool); | ||
exports.getLineHTMLForExport = function (hook, context) { | ||
var contextV = _analyzeLine(context.attribLine, context.apool); | ||
@@ -66,3 +86,4 @@ // If it has a context | ||
}else{ | ||
return line.lineContent + "<br>"; | ||
context.lineContent += "<br>"; | ||
return true; | ||
} | ||
@@ -76,3 +97,3 @@ | ||
if(contextV.indexOf("context") !== 0){ | ||
before += "<p class='context" + contextV + "'>"; | ||
before += "<p class='context context" + contextV + "'><span class='contextbefore'>"; | ||
}else{ | ||
@@ -83,3 +104,3 @@ before += "<p class='" + contextV + "'>"; | ||
// TODO, ensure this is not hard coded.. Impossible to parse CSS prolly so need a decent solution | ||
if(contextV === "Whereas"){ | ||
if(contextV === "whereas"){ | ||
before += "WHEREAS, " | ||
@@ -92,3 +113,3 @@ after += ", and"; | ||
} | ||
if(contextV === "Resolved"){ | ||
if(contextV === "resolved"){ | ||
before += "Be It Further Resolved, " | ||
@@ -105,10 +126,14 @@ after += ", and"; | ||
before += "</span>" | ||
after += "</p>"; | ||
}); | ||
// Remove leading * else don't.. | ||
var newString = before + line.lineContent.substring(1) + after + "<br>"; | ||
return newString; | ||
}else{ // no context, nothing to remove | ||
return line.lineContent; | ||
if (context.lineContent[0] === '*') { | ||
context.lineContent = context.lineContent.substring(1) | ||
} | ||
context.lineContent = before + context.lineContent + "<span class='contextafter'>" + after + "</span>" + "<br>"; | ||
return true; | ||
} | ||
return true; | ||
} | ||
@@ -137,1 +162,16 @@ | ||
} | ||
function cssFromContexts(){ | ||
var formattedCSS = []; | ||
for(var prop in contexts){ | ||
var context = contexts[prop]; | ||
if(context.css){ | ||
var css = ".context"+prop+"{"+context.css+"};"; | ||
console.log("pushed"); | ||
formattedCSS.push(css); | ||
} | ||
} | ||
return formattedCSS; | ||
} | ||
{ | ||
"description": "Context for Etherpad Documents, very WIP.", | ||
"name": "ep_context", | ||
"version": "0.0.10", | ||
"version": "0.0.11", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "John McLear", |
@@ -6,4 +6,37 @@ var _, $, jQuery; | ||
var styles = ["Sponsor", "Title", "Whereas", "Resolved", "Signature", "Date"]; | ||
var styles = []; | ||
var allContextKeys = []; | ||
var lastLineContexts = []; | ||
var contextStrings = []; // Used for Copy/pasting | ||
var contextStartStrings = {}; // Used for locating which string starts with a given value | ||
// Setup the relevant lookup objects, one time operation | ||
$.each(contexts, function(key, context){ | ||
if(context.first && context.first.before) contextStrings.push(context.first.before.content); | ||
if(context.second && context.second.before) contextStrings.push(context.second.before.content); | ||
if(context.before && context.before) contextStrings.push(context.before.content); | ||
if(context.beforelast && context.beforelast.before) contextStrings.push(context.beforelast.before.content); | ||
if(context.last && context.last.before) contextStrings.push(context.last.before.content); | ||
contextStartStrings[key] = []; | ||
if(context.first && context.first.before) contextStartStrings[key].push(context.first.before.content); | ||
if(context.second && context.second.before) contextStartStrings[key].push(context.second.before.content); | ||
if(context.before && context.before) contextStartStrings[key].push(context.before.content); | ||
if(context.beforelast && context.beforelast.before) contextStartStrings[key].push(context.beforelast.before.content); | ||
if(context.last && context.last.before) contextStartStrings[key].push(context.last.before.content); | ||
lastLineContexts.push("contextlast"+key); | ||
allContextKeys.push("context"+key); | ||
allContextKeys.push("contextfirst"+key); | ||
allContextKeys.push("contextsecond"+key); | ||
allContextKeys.push("contextbeforelast"+key); | ||
allContextKeys.push("contextlast"+key); | ||
if(context.displayName){ | ||
styles.push(context.displayName); | ||
}else{ | ||
styles.push(key); | ||
contexts[key].displayName = key; | ||
} | ||
}); | ||
// Handle paste events | ||
@@ -32,3 +65,5 @@ exports.acePaste = function(hook, context){ | ||
var head = inner.contents().find("head"); | ||
$(head).append("<style>"+generateCSSFromContexts()+"</style>"); | ||
var contextControlsContainerHTML = '<div id="contextButtonsContainer" style="display:block;z-index:1;margin-left:50px;"></div>'; | ||
@@ -39,3 +74,3 @@ var floatingIcons = '<div title="Press Shift and Space to bring up Context Options" class="buttonHint"><div id="contextHint" class="contextButton contextHint">⇧ + ␣</div></div>'; | ||
buttonsHTML += '<div id="newLineButton" class="contextButton" unselectable="on">+</div>'; | ||
var bigButtonHTML = '<button id="bigNewLineButton" style="width:650px;position:absolute;top:0;left:auto;margin-left:133px">+</button>'; | ||
//var bigButtonHTML = '<button id="bigNewLineButton" style="width:650px;position:absolute;top:0;left:auto;margin-left:133px">+</button>'; | ||
var contextContainer = '<div id="contextContainer" class="contextContainer"><div style="position:absolute; margin-left:-50px; width:100%; top:10px;"></div></div>'; | ||
@@ -47,3 +82,3 @@ var optionsHTML = $('.context').html(); | ||
// Add control stuff to the UI | ||
padOuter.find("#sidediv").after(bigButtonHTML); | ||
//padOuter.find("#sidediv").after(bigButtonHTML); | ||
padOuter.find("#sidediv").after(contextControlsContainerHTML); | ||
@@ -59,16 +94,2 @@ padOuter.find("#sidediv").after(contextContainer); | ||
// Selection event | ||
/* | ||
$('.context-selection').click(function(contextValue){ | ||
var newValue = $('.context-selection').val(); | ||
context.ace.callWithAce(function(ace){ | ||
ace.ace_doContext(newValue); | ||
},'context' , true); | ||
// Re-focus our powers! | ||
var innerdoc = padInner[0]; | ||
$(innerdoc).contents().find("body").blur().focus(); | ||
}); | ||
*/ | ||
$(select).on("keydown", function(e){ | ||
@@ -98,2 +119,15 @@ // On tab key of select | ||
// Top control from ribbon | ||
$(".context > .context-selection").change(function(contextValue){ | ||
var newValue = $(".context > .context-selection").val(); | ||
context.ace.callWithAce(function(ace){ | ||
ace.ace_doContext(newValue); | ||
},'context' , true); | ||
// Re-focus our powers! | ||
var innerdoc = padInner[0]; | ||
$(innerdoc).contents().find("body").blur().focus(); | ||
}); | ||
// Select on side | ||
$(select).click(function(contextValue){ | ||
@@ -209,3 +243,2 @@ var newValue = $(select).val(); | ||
function reDrawLastLineButton(rep){ | ||
var padLength = rep.lines.length(); | ||
@@ -266,3 +299,3 @@ | ||
if(cs.docTextChanged === true && cs.domClean === true && cs.repChanged === true && (cs.type === "handleKeyEvent" || cs.type === "context") && clientVars.enterKey){ | ||
if(cs.docTextChanged === true && cs.domClean === true && cs.repChanged === true && (cs.type === "handleKeyEvent" || cs.type === "context") && clientVars.enterKey){ | ||
clientVars.enterKey = false; | ||
@@ -294,6 +327,8 @@ // Define variables | ||
// if(!blankLine) return; | ||
if(attributes === "lastwhereas") attributes = "Whereas"; | ||
if(attributes === "lastresolved") attributes = "Resolved"; | ||
if(attributes === "firstresolved") attributes = "Resolved"; | ||
if(attributes.indexOf("last") === 0){ | ||
attributes = attributes.substring(4, attributes.length); | ||
} | ||
if(attributes.indexOf("first") === 0){ | ||
attributes = attributes.substring(5, attributes.length); | ||
} | ||
documentAttributeManager.setAttributeOnLine(thisLine, 'context', attributes); | ||
@@ -312,2 +347,3 @@ } | ||
// If the text has changed in the pad I need to redraw the top of the select and the left arrow | ||
@@ -322,16 +358,35 @@ | ||
setTimeout(function(){ // avoid race condition.. | ||
getLastContext(call, function(lastContext){ | ||
if(!lastContext){ // No context set so set to dummy | ||
$('.context-selection').val("dummy"); // top | ||
select.val("dummy"); // side | ||
}else{ | ||
// Show this context as being enabled. | ||
lastContext = lastContext.replace("context",""); | ||
lastContext = lastContext.charAt(0).toUpperCase() + lastContext.slice(1); | ||
if(lastContext === "Lastwhereas") lastContext = "Whereas"; | ||
if(lastContext === "Lastresolved") lastContext = "Resolved"; | ||
if(lastContext === "Firstresolved") lastContext = "Resolved"; | ||
select.val(lastContext); // side | ||
$('.context-selection').val(lastContext); // top | ||
} | ||
padEditor.callWithAce(function(ace){ | ||
ace.ace_getLastContext(call, function(lastContext){ | ||
if(!lastContext){ // No context set so set to dummy | ||
$('.context-selection').val("dummy"); // top | ||
select.val("dummy"); // side | ||
}else{ | ||
// Show this context as being enabled. | ||
lastContext = lastContext.replace("context",""); | ||
// Process first and last items from metacontexts down to contexts | ||
if(lastContext.indexOf("last") === 0){ | ||
lastContext = lastContext.substring(4, lastContext.length); | ||
} | ||
if(lastContext.indexOf("first") === 0){ | ||
lastContext = lastContext.substring(5, lastContext.length); | ||
} | ||
lastContext = contexts[lastContext].displayName; | ||
// lastContext = lastContext.charAt(0).toUpperCase() + lastContext.slice(1); | ||
// Process first and last items from metacontexts down to contexts | ||
if(lastContext.indexOf("Last") === 0){ | ||
lastContext = lastContext.substring(4, lastContext.length); | ||
} | ||
if(lastContext.indexOf("First") === 0){ | ||
lastContext = lastContext.substring(5, lastContext.length); | ||
} | ||
select.val(lastContext); // side | ||
$('.context-selection').val(lastContext); // top | ||
} | ||
}); | ||
}); | ||
@@ -345,21 +400,57 @@ },500); | ||
// Our sup/subscript attribute will result in a class | ||
// I'm not sure if this is actually required.. | ||
// Our context attribute will result in a class | ||
exports.aceAttribsToClasses = function(hook, context){ | ||
var classes = []; | ||
if(context.key == 'context'){ | ||
if(context.key === 'context'){ | ||
classes.push("context:"+context.value); | ||
} | ||
if(context.key.indexOf('context') !== -1){ | ||
var contextSplit = context.key.split(":")[1]; | ||
if(contextSplit) classes.push("context:"+contextSplit); | ||
} | ||
return classes; | ||
} | ||
// CAN PROBABLY DELETE BELOW FOR NOW WE LEAVE IT IN // CAKE | ||
// Register attributes that are html markup / blocks not just classes | ||
// This should make export export properly IE <sub>helllo</sub>world | ||
// will be the output and not <span class=sub>helllo</span> | ||
exports.aceAttribClasses = function(hook, attr){ | ||
// console.log("DERP"); | ||
// $.each("title", function(k, v){ | ||
// attr[v] = 'tag:'+v; | ||
// }); | ||
// return "context:title"; | ||
// return attr; | ||
} | ||
exports.aceCreateDomLine = function(hook_name, args, cb) { | ||
// console.log(args.cls); | ||
if (args.cls.indexOf('context:') >= 0) { | ||
var clss = []; | ||
var argClss = args.cls.split(" "); | ||
var value; | ||
for (var i = 0; i < argClss.length; i++) { | ||
var cls = argClss[i]; | ||
if (cls.indexOf("context:") != -1) { | ||
value = cls.substr(cls.indexOf(":")+1); | ||
} else { | ||
clss.push(cls); | ||
} | ||
} | ||
return cb([{cls: clss.join(" "), extraOpenTags: "<context"+value+">", extraCloseTags: "</context"+value+">"}]); | ||
} | ||
return cb(); | ||
}; | ||
// Block elements - Prevents character walking | ||
exports.aceRegisterBlockElements = function(){ | ||
var styleArr = []; | ||
styleArr.push("contextlastwhereas"); | ||
styleArr.push("contextlastresolved"); | ||
styleArr.push("contextfirstresolved"); | ||
$.each(styles, function(k,v){ | ||
styleArr.push("context"+v.toLowerCase()); | ||
$.each(contexts, function(context){ | ||
styleArr.push("contextfirst"+context); | ||
styleArr.push("context"+context); | ||
styleArr.push("contextlast"+context); | ||
}); | ||
@@ -374,25 +465,74 @@ return styleArr; | ||
// Find out which lines are selected and assign them the context attribute. | ||
// Passing a level >= 0 will set a context on the selected lines, level < 0 | ||
// Passing a level >= 0 will set a context on the selected lines, level < 0 | ||
// will remove it | ||
function doContext(level){ | ||
var documentAttributeManager = this.documentAttributeManager; | ||
var ace = this.editorInfo; | ||
var rep = this.rep; | ||
var firstLine, lastLine; | ||
firstLine = rep.selStart[0]; | ||
lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0)); | ||
_(_.range(firstLine, lastLine + 1)).each(function(i){ | ||
// Are we apply the context attribute on a full line or a selection? | ||
var isLineContext = (rep.selStart[0] === rep.selEnd[0]) && (rep.selStart[1] === rep.selEnd[1]); | ||
// Apply Context on Selection | ||
if(!isLineContext){ | ||
if(level === "dummy"){ | ||
// console.log("removing attribute on line"); | ||
documentAttributeManager.removeAttributeOnLine(i, 'context'); | ||
}else{ | ||
// console.log("set attr on", firstLine, level); | ||
documentAttributeManager.setAttributeOnLine(i, 'context', level); | ||
$.each(contexts, function(k, v){ | ||
ace.ace_setAttributeOnSelection('context:'+k, false); | ||
}); | ||
return; | ||
} | ||
}); | ||
ace.ace_setAttributeOnSelection('context:'+level.toLowerCase(), true); | ||
return; | ||
} | ||
// Apply Context on entire line | ||
if(isLineContext){ | ||
// console.log("applying context to entire line"); | ||
firstLine = rep.selStart[0]; | ||
lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0)); | ||
_(_.range(firstLine, lastLine + 1)).each(function(i){ | ||
var context = documentAttributeManager.getAttributeOnLine(i, 'context'); | ||
// ADDING A LEVEL | ||
if(context !== "dummy" && context !== "" && level !== "dummy"){ | ||
// console.log("adding a level"); | ||
level = context + "$$" + level; | ||
} | ||
// DROPPING A LEVEL | ||
if(level === "dummy"){ | ||
// Drop a level | ||
var contexts = context.split("$$"); | ||
contexts.pop(); | ||
var joinedLevel = contexts.join("$$"); | ||
// REMOVING CONTEXT ALLTOGETHER | ||
if(level === "dummy" && contexts.length === 0){ | ||
// console.log("removing attribute on line"); | ||
documentAttributeManager.removeAttributeOnLine(i, 'context'); | ||
}else{ | ||
// console.log("not at bottom level so changing context for line"); | ||
documentAttributeManager.setAttributeOnLine(i, 'context', joinedLevel.toLowerCase()); | ||
} | ||
} | ||
// SETTING ATTRIBUTE ON LINE | ||
if(level !== "dummy" && level){ | ||
// console.log("set attr on", firstLine, level.toLowerCase()); | ||
documentAttributeManager.setAttributeOnLine(i, 'context', level.toLowerCase()); | ||
} | ||
}); | ||
} | ||
} | ||
// Get the context of a line | ||
function getLastContext(context, cb){ | ||
var rep = context.rep; | ||
var documentAttributeManager = context.documentAttributeManager; | ||
function getLastContext(editorContext, cb){ | ||
var rep = editorContext.rep; | ||
var ace = this.editorInfo; | ||
var documentAttributeManager = editorContext.documentAttributeManager; | ||
var foundOnLine = false; | ||
var foundOnSelection = false; | ||
// See if the line attributes has an attribute | ||
var firstLine, lastLine; | ||
@@ -404,9 +544,34 @@ firstLine = rep.selStart[0]; | ||
var attributes = documentAttributeManager.getAttributeOnLine(i, 'context'); | ||
// console.log("attributes", attributes); | ||
// take last attribute from attributes, split it | ||
var split = attributes.split("$"); | ||
var split = attributes.split("$$"); | ||
// clean empty values | ||
split = cleanArray(split); | ||
var lastContext = split[split.length-1]; | ||
return cb(lastContext); | ||
// return cb(lastContext); | ||
foundOnLine = lastContext; | ||
}); | ||
// See if the current selection has the attribute | ||
$.each(contexts, function(context){ | ||
// This could probably be optimized with a indexOf | ||
if(documentAttributeManager.getAttributeOnSelection("context:"+context, true)){ | ||
foundOnSelection = context; | ||
return false; | ||
} | ||
}); | ||
if(foundOnSelection){ | ||
// console.log("returned a found on selection value", foundOnSelection); | ||
return cb(foundOnSelection); | ||
} | ||
if(foundOnLine){ | ||
// console.log("returned a found on line value", foundOnLine); | ||
return cb(foundOnLine); | ||
} | ||
if(!foundOnSelection && !foundOnLine){ | ||
// console.log("no attribute found"); | ||
return cb(null); | ||
} | ||
} | ||
@@ -420,3 +585,3 @@ | ||
// take last attribute from attributes, split it | ||
var split = attributes.split("$"); | ||
var split = attributes.split("$$"); | ||
// clean empty values | ||
@@ -431,2 +596,3 @@ split = cleanArray(split); | ||
editorInfo.ace_doContext = _(doContext).bind(context); | ||
editorInfo.ace_getLastContext = _(getLastContext).bind(context); | ||
editorInfo.ace_handlePaste = _(handlePaste).bind(context); | ||
@@ -436,3 +602,3 @@ editorInfo.ace_getLineContext = _(getLineContext).bind(context); | ||
// Here we convert the class context:x into a tag | ||
// Here we convert the class context:x into a tag | ||
exports.aceDomLineProcessLineAttributes = function(name, context){ | ||
@@ -443,19 +609,15 @@ var preHtml = ""; | ||
var contexts = /context:(.*?) /i.exec(context.cls); | ||
if(!contexts && !processed) return []; | ||
if(contexts){ | ||
var tags = contexts[1]; | ||
tags = tags.split("$"); | ||
$.each(tags, function(i, tag){ | ||
if(tag.substring(0,7) === "context"){ | ||
// on paste we have the correct context defined so we need to modify it back to the tag | ||
tag = tag.substring(7,tag.length); | ||
tag = tag.charAt(0).toUpperCase() + tag.slice(1); | ||
} | ||
if(styles.indexOf(tag) !== -1 || tag === "lastwhereas" || tag === "lastresolved" || tag === "firstresolved"){ | ||
preHtml += '<context' + tag + ' class="context">'; | ||
postHtml += '</context' + tag + ' class="context">'; | ||
processed = true; | ||
} | ||
var contextsFound = /context:(.*?) /i.exec(context.cls); | ||
if(!contextsFound && !processed) return []; | ||
if(contextsFound){ | ||
var context = contextsFound[1]; | ||
var splitContexts = context.split("$$"); | ||
$.each(splitContexts, function(k, context){ | ||
$.each(allContextKeys, function(k, contextKey){ | ||
if(contextKey === "context"+context){ | ||
preHtml += '<context' + context + ' class="context">'; | ||
postHtml += '</context' + context + ' class="context">'; | ||
processed = true; | ||
} | ||
}); | ||
}); | ||
@@ -592,18 +754,28 @@ } | ||
var offset = offsetTop + offsetHeight; | ||
var context = documentAttributeManager.getAttributeOnLine(k, 'context'); | ||
var context = documentAttributeManager.getAttributeOnLine(k, 'context'); | ||
if(context){ | ||
// draw the context value on the screen | ||
if(offset){ | ||
if(context === "lastwhereas") context = "Whereas"; | ||
if(context === "lastresolved") context = "Resolved"; | ||
if(context === "firstresolved") context = "Resolved"; | ||
if(context === "contextresolved") context = "Resolved"; | ||
contextContainer.append("<div class='contextLabel' style='top:"+offset+"px'>"+context+"</div>"); | ||
} | ||
}else{ | ||
if(offset){ // Handle bug where it would randomly throw a context label at offset 0 | ||
contextContainer.append("<div class='contextLabel nocontext' style='top:"+offset+"px'>No Context</div>"); | ||
} | ||
// Given hello$$world returns ["hello","world"]; | ||
var splitContexts = context.split("$$"); | ||
context = splitContexts[splitContexts.length-1]; | ||
if(!context){ | ||
// No context available to draw a big No Context thingy | ||
contextContainer.append("<div class='contextLabel nocontext' style='top:"+offset+"px'>No Context</div>"); | ||
return; | ||
} | ||
if(!offset) return; | ||
// Process first and last items from metacontexts down to contexts | ||
if(context.indexOf("last") === 0){ | ||
context = context.substring(4, context.length); | ||
} | ||
if(context.indexOf("first") === 0){ | ||
context = context.substring(5, context.length); | ||
} | ||
context = context.toLowerCase(); // support legacy docs | ||
// draw the context value on the screen | ||
contextContainer.append("<div class='contextLabel' style='top:"+offset+"px'>"+contexts[context].displayName+"</div>"); | ||
}); | ||
@@ -619,8 +791,9 @@ } | ||
var lines = padInner.contents().find("div"); | ||
var contexts = {}; | ||
var thisContexts = {}; | ||
$.each(lines, function(k, line){ | ||
contexts[k] = {}; | ||
thisContexts[k] = {}; | ||
// console.log("line", line); | ||
// Find last contextwhereas | ||
var hasContext = $(line).find("contextwhereas, contextlastwhereas, contextresolved, contextlastresolved , contextfirstresolved"); | ||
var searchString = allContextKeys + ""; | ||
var hasContext = $(line).find(searchString); | ||
if(hasContext[0]) var context = hasContext[0].localName; | ||
@@ -630,14 +803,15 @@ // If the line is whereas or lastwhereas context store this data in an object | ||
if(hasContext.length > 0){ | ||
contexts[k].hasContext = true; | ||
if(context === "contextwhereas" || context === "contextlastwhereas"){ | ||
contexts[k].context = "whereas" | ||
} | ||
if(context === "contextresolved" || context === "contextlastresolved" || context === "contextfirstresolved"){ | ||
contexts[k].context = "resolved" | ||
} | ||
thisContexts[k].hasContext = true; | ||
$.each(contexts, function(context){ | ||
if(context.indexOf("context") !== -1){ | ||
thisContexts[k].context = context; | ||
} | ||
}); | ||
} | ||
var isLastLine = $(line).find("contextlastwhereas, contextlastresolved"); | ||
var lastLineSearchString = lastLineContexts + ""; | ||
var isLastLine = $(line).find(lastLineSearchString); | ||
if(isLastLine.length > 0){ | ||
// If the line is whereas or lastwhereas context store this data in an object | ||
contexts[k].hasLastLine = true; | ||
thisContexts[k].hasLastLine = true; | ||
} | ||
@@ -647,3 +821,3 @@ }); | ||
// Go through our existing object and check to see if it's right.. | ||
$.each(contexts, function(k, line){ | ||
$.each(thisContexts, function(k, line){ | ||
var lineNumber = parseInt(k); | ||
@@ -654,7 +828,7 @@ var context = line.context; | ||
var prevLine = {}; | ||
var sizeOfContexts = Object.size(contexts); | ||
var sizeOfContexts = Object.size(thisContexts); | ||
// If this is not the first line get the values of the previous line | ||
if (k > 0){ | ||
prevLine = contexts[k-1]; | ||
prevLine = thisContexts[k-1]; | ||
} | ||
@@ -664,11 +838,14 @@ // If this is not the last line get the values of the next line | ||
var nextLineKey = parseInt(k)+1; | ||
if(contexts[nextLineKey]) nextLine = contexts[nextLineKey]; | ||
if(thisContexts[nextLineKey]) nextLine = thisContexts[nextLineKey]; | ||
} | ||
var context = documentAttributeManager.getAttributeOnLine(lineNumber, 'context'); | ||
nextLine.context = documentAttributeManager.getAttributeOnLine(lineNumber+1, 'context'); | ||
thisLine.context = context; | ||
// console.log("prevLine", prevLine); | ||
// console.log("thisLine", thisLine); | ||
// console.log("nextLine", nextLine); | ||
/* | ||
console.log("prevLine", prevLine); | ||
console.log("thisLine", thisLine); | ||
console.log("nextLine", nextLine); | ||
*/ | ||
// REMOVE LASTLINE | ||
@@ -680,18 +857,23 @@ // If this line has lastwhereas context AND the next line has whereas then this line should not have lastwhereas | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
if(context === "whereas" || context === "lastwhereas" || context === "firstwhereas") documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'Whereas'); | ||
if(context === "resolved" || context === "lastresolved" || context === "firstresolved") documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'Resolved'); | ||
// console.log("removing lastwhereas from ", lineNumber, thisLine) | ||
$.each(contexts, function(contextKey){ | ||
if(context.indexOf(contextKey) !== -1){ | ||
// console.warn("removed lastline from ", lineNumber); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', contextKey); | ||
} | ||
}); | ||
} | ||
if(context === "contextfirstresolved" || context === "firstresolved"){ | ||
// REMOVE FIRSTLINE | ||
// If this line has lastwhereas context AND the next line has whereas then this line should not have lastwhereas | ||
// So remove it.. | ||
if(thisLine.hasContext && (prevLine.context === "resolved" || prevLine.content === "firstresolved") && context){ | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'Resolved'); | ||
// console.log("removing firstwhereas from ", lineNumber, thisLine, prevLine, context) | ||
// REMOVE FIRSTLINE | ||
// If this line has lastwhereas context AND the next line has whereas then this line should not have lastwhereas | ||
// So remove it.. | ||
$.each(contexts, function(contextKey){ | ||
if(context.indexOf("first"+contextKey) !== -1){ | ||
if(thisLine.hasContext && (prevLine.context === contextKey || prevLine.context === "first"+contextKey) && context){ | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
// console.warn("set NORMAL on ", lineNumber); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', contextKey); | ||
// console.log("removing firstwhereas from ", lineNumber, thisLine, prevLine, context) | ||
} | ||
} | ||
} | ||
}); | ||
@@ -701,3 +883,3 @@ // ADD LASTLINE | ||
// If this line has different context to the next line | ||
if(thisLine.hasContext && prevLine.hasContext && (nextLine.context !== thisLine.context)){ | ||
if(thisLine.hasContext && prevLine.hasContext && (nextLine.context !== thisLine.context && nextLine.context !== "last"+thisLine.context)){ | ||
// console.log("setting last line on ", lineNumber, thisLine); | ||
@@ -707,11 +889,9 @@ // Check to see if this line number already has lastwhere context value | ||
// console.log("Current context of line", lineNumber, context); | ||
if(context !== "lastWhereas" && context === "Whereas"){ | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'lastwhereas'); | ||
} | ||
if(context !== "lastResolved" && context === "Resolved" || context === "contextresolved"){ | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'lastresolved'); | ||
} | ||
$.each(contexts, function(contextKey){ | ||
if(context !== "last"+contextKey && context === contextKey){ | ||
// console.warn("set LASTLINE on ", lineNumber); | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'last'+contextKey); | ||
} | ||
}); | ||
} | ||
@@ -721,13 +901,14 @@ | ||
// If this is the first line with this context | ||
if(thisLine.hasContext && (prevLine.context !== "resolved")){ | ||
// console.log("setting first line on ", lineNumber, thisLine); | ||
// Check to see if this line number already has lastwhere context value | ||
var context = documentAttributeManager.getAttributeOnLine(lineNumber, 'context'); | ||
// console.log("Current context of line", lineNumber, context); | ||
if(context === "Resolved" || context === "lastresolved"){ | ||
// console.log("setting first", lineNumber); | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'firstresolved'); | ||
$.each(contexts, function(contextKey){ | ||
if(thisLine.hasContext && (prevLine.context !== contextKey)){ | ||
var context = documentAttributeManager.getAttributeOnLine(lineNumber, 'context'); | ||
// console.log("Current context of line", lineNumber, context); | ||
if(context === contextKey && prevLine.context !== "first"+contextKey){ | ||
// console.log("setting first", lineNumber, "first"+context); | ||
// console.warn("set FIRSTLINE on ", lineNumber); | ||
documentAttributeManager.removeAttributeOnLine(lineNumber, 'context'); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', "first"+contextKey); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
@@ -743,8 +924,6 @@ } | ||
var contextStrings = ["whereas", "be it resolved", "be it further resolved"]; | ||
var contexts = ["Whereas", "Resolved", "Resolved"]; | ||
// Go through each line of the document | ||
$.each(lines, function(index, line){ | ||
var lineText = $(line).text(); | ||
var lineContext = false; | ||
// console.log("lineText", lineText, "lineText.length", lineText.length); | ||
@@ -760,3 +939,2 @@ | ||
// See if the line has the whereas content | ||
@@ -768,9 +946,27 @@ var cleanLineText = lineText.toLowerCase(); | ||
$.each(contextStrings, function(k, contextString){ | ||
strPos = cleanLineText.indexOf(contextString); // Where is the string in the line | ||
strPos = cleanLineText.indexOf(contextString.toLowerCase()); // Where is the string in the line | ||
if(strPos !== -1){ | ||
hasContext = k; // Sets which context we have | ||
strPosition = strPos; | ||
// How do we know which context ID this contextString is from? | ||
$.each(contextStartStrings, function(key, strings){ | ||
$.each(strings, function(k, startString){ | ||
if( cleanLineText.indexOf(startString.toLowerCase()) !== -1){ | ||
lineContext = key; | ||
} | ||
}); | ||
}); | ||
// I'm not sure why we can't use this simple value above.. | ||
// TODO: investigate this bit further | ||
hasContext = k; // Sets which context we have | ||
strPosition = strPos; | ||
} | ||
}); | ||
// Remove any lines that just container dashed lines | ||
// TODO, use regular expression | ||
if(cleanLineText.indexOf("______") === 0 || cleanLineText.indexOf("---") === 0){ | ||
toDestroy.push(index); | ||
} | ||
cleanLineText = cleanLineText.trim(); | ||
@@ -781,3 +977,2 @@ if(hasContext !== false){ // Note that the index may be 0 because so we need this statement | ||
// move caret to this location | ||
var lineNumber = index; | ||
@@ -797,3 +992,3 @@ | ||
if(attributeLength > 8){ | ||
startLocation = 1; | ||
// startLocation = 1; | ||
endLocation = endLocation +1; | ||
@@ -804,3 +999,2 @@ } | ||
var stringWithoutContext = cleanLineText.substring(contextStrings[hasContext].length,cleanLineText.length); | ||
// Strip leading ,'s a common cause of gum disease | ||
@@ -812,15 +1006,35 @@ if(stringWithoutContext[0] === ","){ | ||
// Stripp leading white space | ||
var regex = /^\s*/; | ||
var numberOfPrefixSpaces = stringWithoutContext.match(regex)[0].length; | ||
if(numberOfPrefixSpaces){ | ||
endLocation = endLocation + numberOfPrefixSpaces; | ||
} | ||
// Strip leading white space | ||
// Causesa problem w/ Hoops in the Hood document | ||
// var regex = /^\s*/; | ||
// var numberOfPrefixSpaces = stringWithoutContext.match(regex)[0].length; | ||
// if(numberOfPrefixSpaces){ | ||
// endLocation = endLocation + numberOfPrefixSpaces; | ||
// } | ||
// Removes everything noisy to keep things clean, fresh and minty | ||
ace.ace_replaceRange([lineNumber,startLocation], [lineNumber,strPosition+endLocation], ""); | ||
$.each(contexts, function(contextKey){ | ||
if(contextKey === lineContext){ | ||
// Removes everything noisy to keep things clean, fresh and minty - PREFIX | ||
ace.ace_replaceRange([lineNumber,startLocation], [lineNumber,strPosition+endLocation], ""); | ||
} | ||
}); | ||
// Removes everything noisy to keep things clean, fresh and minty - SUFFIX | ||
// This is temporary logic, we can do this better. | ||
$.each(contexts, function(contextKey, context){ | ||
if(context.after && context.after.content){ | ||
var removeThis = contexts[contextKey].after.content; | ||
if(stringWithoutContext.substring(stringWithoutContext.length - removeThis.length, stringWithoutContext.length) === removeThis){ | ||
// console.log("string has ; and ,", lineNumber, stringWithoutContext); | ||
ace.ace_replaceRange([lineNumber,stringWithoutContext.length - removeThis.length -1], [lineNumber,stringWithoutContext.length-1], ""); | ||
} | ||
} | ||
}); | ||
// Set the Attribute to Whereas for the line | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', contexts[hasContext]); | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', lineContext); | ||
}); | ||
@@ -856,2 +1070,32 @@ }else{ | ||
// TODO: do this another time.. Not important for initial roll out.. | ||
// Need a split value IE "Presented by" and " on ", so basically two values.. | ||
// So if it starts with "presented by" and has "on" then split the line.. | ||
// Something to add to contexts.js | ||
// Now go through every line looking for lines we have to split | ||
// Sponsors get magically broken into two parts! | ||
// This doesn't work because of issue #47 where trying to add an additional line with replaceRange will | ||
// NOTE: Iterating twice is horribly inefficient but we have to because if we don't we get errors | ||
// This could be rewritten to perform better though | ||
$.each(lines, function(lineNumber, line){ | ||
var lineText = $(line).text(); | ||
// Disabled for now... | ||
/* | ||
if(lineText.indexOf("Presented by") === 0){ | ||
context.editorInfo.ace_callWithAce(function(ace){ | ||
if(lineText.indexOf(" on ") !== -1) splitLocation = lineText.indexOf(" on "); | ||
if(!splitLocation) return; | ||
// Break the lines up | ||
ace.ace_replaceRange([lineNumber-1,splitLocation+2], [lineNumber-1,splitLocation+2], "\n"); | ||
// Set first line as Sponsor | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'Sponsor'); | ||
// Sec second line as date | ||
documentAttributeManager.setAttributeOnLine(lineNumber, 'context', 'Date'); | ||
}); | ||
} | ||
*/ | ||
}); | ||
// Redraw last line as we modified layout.. | ||
@@ -858,0 +1102,0 @@ reDrawLastLineButton(context.rep); |
@@ -1,4 +0,10 @@ | ||
// var supportedContexts = ["contextsection", "contextparagraph", "contextsubsection", "contextform", "contextdistribution-code", "contextcongress", "contextsession", "contextheader", "contextenum"]; | ||
var supportedContexts = ["contextsponsor", "contexttitle", "contextwhereas", "contextresolved", "contextsignature", "contextdate", "contextlastwhereas", "contextlastresolved", "contextfirstresolved"]; | ||
var supportedContexts = []; | ||
var contexts = require('./contexts').contexts; | ||
for (var context in contexts){ | ||
supportedContexts.push("context" + context); | ||
supportedContexts.push("contextfirst" + context); | ||
supportedContexts.push("contextlast" + context); | ||
} | ||
exports.collectContentPre = function(hook, context){ | ||
@@ -12,6 +18,12 @@ var tname = context.tname; | ||
if(supportedContexts.indexOf(tname) !== -1){ | ||
console.log(tname); | ||
lineAttributes['context'] = tname; | ||
} | ||
// Added to support Spans -- May be some drama related nonsense here | ||
var level = /(?:^| )(context:[A-Za-z0-9]*)/.exec(context.cls); | ||
if(level){ | ||
level = level[0].split(":")[1]; | ||
context.cc.doAttrib(context.state, "context:" + level); | ||
} | ||
// Probably not needed | ||
@@ -18,0 +30,0 @@ // lineAttributes['lastlinebutton'] = true; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
65513
36.09%16
23.08%1592
34.01%