Codemirror IMPROVEMENT

- Codemirror tenia varias opciones que eran incompatibles con la version de procesmaker y ie.

- Se pudo el codmirror antiguo para las secciones del Designer en el xml y javascript para evitar esos errores.
- se pudo el mismo codigo para las 3 navegadores chrome, firefox, ie.
This commit is contained in:
Marco Antonio Nina
2013-11-29 14:50:01 -04:00
parent 1950e5b8f5
commit 08c8ee9f95
81 changed files with 16230 additions and 89 deletions

View File

@@ -0,0 +1,32 @@
Copyright (c) 2009, Timothy Farrell
All rights reserved.
This software is provided for use in connection with the
CodeMirror suite of modules and utilities, hosted and maintained
at http://codemirror.net/.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,58 @@
html {
cursor: text;
}
.editbox {
padding: .4em;
margin: 0;
font-family: monospace;
font-size: 10pt;
line-height: 1.1em;
color: black;
}
pre.code, .editbox {
color: #666666;
}
.editbox p {
margin: 0;
}
span.py-delimiter, span.py-special {
color: #666666;
}
span.py-operator {
color: #666666;
}
span.py-error {
background-color: #660000;
color: #FFFFFF;
}
span.py-keyword {
color: #770088;
font-weight: bold;
}
span.py-literal {
color: #228811;
}
span.py-identifier, span.py-func {
color: black;
}
span.py-type, span.py-decorator {
color: #0000FF;
}
span.py-comment {
color: #AA7700;
}
span.py-string, span.py-bytes, span.py-raw, span.py-unicode {
color: #AA2222;
}

View File

@@ -0,0 +1,141 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="../../js/codemirror.js" type="text/javascript"></script>
<title>CodeMirror: Python demonstration</title>
<style type="text/css">
.CodeMirror-line-numbers {
width: 2.2em;
color: #aaa;
background-color: #eee;
text-align: right;
padding: .4em;
margin: 0;
font-family: monospace;
font-size: 10pt;
line-height: 1.1em;
}
</style>
</head>
<body style="padding: 20px;">
<p>
This is a simple demonstration of the Python syntax highlighting module
for <a href="index.html">CodeMirror</a>.
</p>
<p>
Features of this parser include:
</p>
<ul>
<li>Token-based syntax highlighting - currently very little lexical analysis happens. Few lexical errors will be detected.</li>
<li>Use the normal indentation mode to enforce regular indentation, otherwise the "shift" indentation mode will give you more flexibility.</li>
<li>Parser Options:
<ul>
<li>pythonVersion (Integer) - 2 or 3 to indicate which version of Python to parse. Default = 2</li>
<li>strictErrors (Bool) - true to highlight errors that may not be Python errors but cause confusion for this parser. Default = true</li>
</ul>
</li>
</ul>
<p>Written by Timothy Farrell (<a href="LICENSE">license</a>). Special
thanks to Adam Brand and Marijn Haverbeke for their help in debugging
and providing for this parser.</p>
<div style="border: 1px solid black; padding: 0px;">
<textarea id="code" cols="100" rows="20" style="width:100%">
# Literals
1234
0.0e101
.123
0b01010011100
0o01234567
0x0987654321abcdef
# Error Literals
.0b000
0.0e
0e
# String Literals
'For\''
"God\""
"""so loved
the world"""
'''that he gave
his only begotten\' '''
'that whosoever believeth \
in him'
''
# Identifiers
__a__
a.b
a.b.c
# Error Identifiers
a.
# Operators
+ - * / % & | ^ ~ < >
== != <= >= <> << >> // **
and or not in is
# Delimiters
() [] {} , : ` = ; @ . # At-signs and periods require context
+= -= *= /= %= &= |= ^=
//= >>= <<= **=
# Keywords
as assert break class continue def del elif else except
finally for from global if import lambda pass raise
return try while with yield
# Python 2 Keywords (otherwise Identifiers)
exec print
# Python 3 Keywords (otherwise Identifiers)
nonlocal
# Types
bool classmethod complex dict enumerate float frozenset int list object
property reversed set slice staticmethod str super tuple type
# Python 2 Types (otherwise Identifiers)
basestring buffer file long unicode xrange
# Python 3 Types (otherwise Identifiers)
bytearray bytes filter map memoryview open range zip
# Example Strict Errors
def doesNothing():
pass # indentUnit is set to 4 but this line is indented 3
# Some Example code
import os
from package import ParentClass
@nonsenseDecorator
def doesNothing():
pass
class ExampleClass(ParentClass):
@staticmethod
def example(inputStr):
a = list(inputStr)
a.reverse()
return ''.join(a)
def __init__(self, mixin = 'Hello'):
self.mixin = mixin
</textarea>
</div>
<script type="text/javascript">
var editor = CodeMirror.fromTextArea('code', {
parserfile: ["../contrib/python/js/parsepython.js"],
stylesheet: "style/pythoncolors.css",
path: "../../js/",
lineNumbers: true,
textWrapping: false,
indentUnit: 4,
parserConfig: {'pythonVersion': 2, 'strictErrors': true}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,541 @@
var PythonParser = Editor.Parser = (function() {
function wordRegexp(words) {
return new RegExp("^(?:" + words.join("|") + ")$");
}
var DELIMITERCLASS = 'py-delimiter';
var LITERALCLASS = 'py-literal';
var ERRORCLASS = 'py-error';
var OPERATORCLASS = 'py-operator';
var IDENTIFIERCLASS = 'py-identifier';
var STRINGCLASS = 'py-string';
var BYTESCLASS = 'py-bytes';
var UNICODECLASS = 'py-unicode';
var RAWCLASS = 'py-raw';
var NORMALCONTEXT = 'normal';
var STRINGCONTEXT = 'string';
var singleOperators = '+-*/%&|^~<>';
var doubleOperators = wordRegexp(['==', '!=', '\\<=', '\\>=', '\\<\\>',
'\\<\\<', '\\>\\>', '\\/\\/', '\\*\\*']);
var singleDelimiters = '()[]{}@,:`=;';
var doubleDelimiters = ['\\+=', '\\-=', '\\*=', '/=', '%=', '&=', '\\|=',
'\\^='];
var tripleDelimiters = wordRegexp(['//=','\\>\\>=','\\<\\<=','\\*\\*=']);
var singleStarters = singleOperators + singleDelimiters + '=!';
var doubleStarters = '=<>*/';
var identifierStarters = /[_A-Za-z]/;
var wordOperators = wordRegexp(['and', 'or', 'not', 'is', 'in']);
var commonkeywords = ['as', 'assert', 'break', 'class', 'continue',
'def', 'del', 'elif', 'else', 'except', 'finally',
'for', 'from', 'global', 'if', 'import',
'lambda', 'pass', 'raise', 'return',
'try', 'while', 'with', 'yield'];
var commontypes = ['bool', 'classmethod', 'complex', 'dict', 'enumerate',
'float', 'frozenset', 'int', 'list', 'object',
'property', 'reversed', 'set', 'slice', 'staticmethod',
'str', 'super', 'tuple', 'type'];
var py2 = {'types': ['basestring', 'buffer', 'file', 'long', 'unicode',
'xrange'],
'keywords': ['exec', 'print'],
'version': 2 };
var py3 = {'types': ['bytearray', 'bytes', 'filter', 'map', 'memoryview',
'open', 'range', 'zip'],
'keywords': ['nonlocal'],
'version': 3};
var py, keywords, types, stringStarters, stringTypes, config;
function configure(conf) {
if (!conf.hasOwnProperty('pythonVersion')) {
conf.pythonVersion = 2;
}
if (!conf.hasOwnProperty('strictErrors')) {
conf.strictErrors = true;
}
if (conf.pythonVersion != 2 && conf.pythonVersion != 3) {
alert('CodeMirror: Unknown Python Version "' +
conf.pythonVersion +
'", defaulting to Python 2.x.');
conf.pythonVersion = 2;
}
if (conf.pythonVersion == 3) {
py = py3;
stringStarters = /[\'\"rbRB]/;
stringTypes = /[rb]/;
doubleDelimiters.push('\\-\\>');
} else {
py = py2;
stringStarters = /[\'\"RUru]/;
stringTypes = /[ru]/;
}
config = conf;
keywords = wordRegexp(commonkeywords.concat(py.keywords));
types = wordRegexp(commontypes.concat(py.types));
doubleDelimiters = wordRegexp(doubleDelimiters);
}
var tokenizePython = (function() {
function normal(source, setState) {
var stringDelim, threeStr, temp, type, word, possible = {};
var ch = source.next();
function filterPossible(token, styleIfPossible) {
if (!possible.style && !possible.content) {
return token;
} else if (typeof(token) == STRINGCONTEXT) {
token = {content: source.get(), style: token};
}
if (possible.style || styleIfPossible) {
token.style = styleIfPossible ? styleIfPossible : possible.style;
}
if (possible.content) {
token.content = possible.content + token.content;
}
possible = {};
return token;
}
// Handle comments
if (ch == '#') {
while (!source.endOfLine()) {
source.next();
}
return 'py-comment';
}
// Handle special chars
if (ch == '\\') {
if (!source.endOfLine()) {
var whitespace = true;
while (!source.endOfLine()) {
if(!(/[\s\u00a0]/.test(source.next()))) {
whitespace = false;
}
}
if (!whitespace) {
return ERRORCLASS;
}
}
return 'py-special';
}
// Handle operators and delimiters
if (singleStarters.indexOf(ch) != -1 || (ch == "." && !source.matches(/\d/))) {
if (doubleStarters.indexOf(source.peek()) != -1) {
temp = ch + source.peek();
// It must be a double delimiter or operator or triple delimiter
if (doubleOperators.test(temp)) {
source.next();
var nextChar = source.peek();
if (nextChar && tripleDelimiters.test(temp + nextChar)) {
source.next();
return DELIMITERCLASS;
} else {
return OPERATORCLASS;
}
} else if (doubleDelimiters.test(temp)) {
source.next();
return DELIMITERCLASS;
}
}
// It must be a single delimiter or operator
if (singleOperators.indexOf(ch) != -1 || ch == ".") {
return OPERATORCLASS;
} else if (singleDelimiters.indexOf(ch) != -1) {
if (ch == '@' && source.matches(/\w/)) {
source.nextWhileMatches(/[\w\d_]/);
return {style:'py-decorator',
content: source.get()};
} else {
return DELIMITERCLASS;
}
} else {
return ERRORCLASS;
}
}
// Handle number literals
if (/\d/.test(ch) || (ch == "." && source.matches(/\d/))) {
if (ch === '0' && !source.endOfLine()) {
switch (source.peek()) {
case 'o':
case 'O':
source.next();
source.nextWhileMatches(/[0-7]/);
return filterPossible(LITERALCLASS, ERRORCLASS);
case 'x':
case 'X':
source.next();
source.nextWhileMatches(/[0-9A-Fa-f]/);
return filterPossible(LITERALCLASS, ERRORCLASS);
case 'b':
case 'B':
source.next();
source.nextWhileMatches(/[01]/);
return filterPossible(LITERALCLASS, ERRORCLASS);
}
}
source.nextWhileMatches(/\d/);
if (ch != '.' && source.peek() == '.') {
source.next();
source.nextWhileMatches(/\d/);
}
// Grab an exponent
if (source.matches(/e/i)) {
source.next();
if (source.peek() == '+' || source.peek() == '-') {
source.next();
}
if (source.matches(/\d/)) {
source.nextWhileMatches(/\d/);
} else {
return filterPossible(ERRORCLASS);
}
}
// Grab a complex number
if (source.matches(/j/i)) {
source.next();
}
return filterPossible(LITERALCLASS);
}
// Handle strings
if (stringStarters.test(ch)) {
var peek = source.peek();
var stringType = STRINGCLASS;
if ((stringTypes.test(ch)) && (peek == '"' || peek == "'")) {
switch (ch.toLowerCase()) {
case 'b':
stringType = BYTESCLASS;
break;
case 'r':
stringType = RAWCLASS;
break;
case 'u':
stringType = UNICODECLASS;
break;
}
ch = source.next();
stringDelim = ch;
if (source.peek() != stringDelim) {
setState(inString(stringType, stringDelim));
return null;
} else {
source.next();
if (source.peek() == stringDelim) {
source.next();
threeStr = stringDelim + stringDelim + stringDelim;
setState(inString(stringType, threeStr));
return null;
} else {
return stringType;
}
}
} else if (ch == "'" || ch == '"') {
stringDelim = ch;
if (source.peek() != stringDelim) {
setState(inString(stringType, stringDelim));
return null;
} else {
source.next();
if (source.peek() == stringDelim) {
source.next();
threeStr = stringDelim + stringDelim + stringDelim;
setState(inString(stringType, threeStr));
return null;
} else {
return stringType;
}
}
}
}
// Handle Identifier
if (identifierStarters.test(ch)) {
source.nextWhileMatches(/[\w\d_]/);
word = source.get();
if (wordOperators.test(word)) {
type = OPERATORCLASS;
} else if (keywords.test(word)) {
type = 'py-keyword';
} else if (types.test(word)) {
type = 'py-type';
} else {
type = IDENTIFIERCLASS;
while (source.peek() == '.') {
source.next();
if (source.matches(identifierStarters)) {
source.nextWhileMatches(/[\w\d]/);
} else {
type = ERRORCLASS;
break;
}
}
word = word + source.get();
}
return filterPossible({style: type, content: word});
}
// Register Dollar sign and Question mark as errors. Always!
if (/\$\?/.test(ch)) {
return filterPossible(ERRORCLASS);
}
return filterPossible(ERRORCLASS);
}
function inString(style, terminator) {
return function(source, setState) {
var matches = [];
var found = false;
while (!found && !source.endOfLine()) {
var ch = source.next(), newMatches = [];
// Skip escaped characters
if (ch == '\\') {
if (source.peek() == '\n') {
break;
}
ch = source.next();
}
if (ch == terminator.charAt(0)) {
matches.push(terminator);
}
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
if (match.charAt(0) == ch) {
if (match.length == 1) {
setState(normal);
found = true;
break;
} else {
newMatches.push(match.slice(1));
}
}
}
matches = newMatches;
}
return style;
};
}
return function(source, startState) {
return tokenizer(source, startState || normal);
};
})();
function parsePython(source, basecolumn) {
if (!keywords) {
configure({});
}
basecolumn = basecolumn || 0;
var tokens = tokenizePython(source);
var lastToken = null;
var column = basecolumn;
var context = {prev: null,
endOfScope: false,
startNewScope: false,
level: basecolumn,
next: null,
type: NORMALCONTEXT
};
function pushContext(level, type) {
type = type ? type : NORMALCONTEXT;
context = {prev: context,
endOfScope: false,
startNewScope: false,
level: level,
next: null,
type: type
};
}
function popContext(remove) {
remove = remove ? remove : false;
if (context.prev) {
if (remove) {
context = context.prev;
context.next = null;
} else {
context.prev.next = context;
context = context.prev;
}
}
}
function indentPython(context) {
var temp;
return function(nextChars, currentLevel, direction) {
if (direction === null || direction === undefined) {
if (nextChars) {
while (context.next) {
context = context.next;
}
}
return context.level;
}
else if (direction === true) {
if (currentLevel == context.level) {
if (context.next) {
return context.next.level;
} else {
return context.level;
}
} else {
temp = context;
while (temp.prev && temp.prev.level > currentLevel) {
temp = temp.prev;
}
return temp.level;
}
} else if (direction === false) {
if (currentLevel > context.level) {
return context.level;
} else if (context.prev) {
temp = context;
while (temp.prev && temp.prev.level >= currentLevel) {
temp = temp.prev;
}
if (temp.prev) {
return temp.prev.level;
} else {
return temp.level;
}
}
}
return context.level;
};
}
var iter = {
next: function() {
var token = tokens.next();
var type = token.style;
var content = token.content;
if (lastToken) {
if (lastToken.content == 'def' && type == IDENTIFIERCLASS) {
token.style = 'py-func';
}
if (lastToken.content == '\n') {
var tempCtx = context;
// Check for a different scope
if (type == 'whitespace' && context.type == NORMALCONTEXT) {
if (token.value.length < context.level) {
while (token.value.length < context.level) {
popContext();
}
if (token.value.length != context.level) {
context = tempCtx;
if (config.strictErrors) {
token.style = ERRORCLASS;
}
} else {
context.next = null;
}
}
} else if (context.level !== basecolumn &&
context.type == NORMALCONTEXT) {
while (basecolumn !== context.level) {
popContext();
}
if (context.level !== basecolumn) {
context = tempCtx;
if (config.strictErrors) {
token.style = ERRORCLASS;
}
}
}
}
}
// Handle Scope Changes
switch(type) {
case STRINGCLASS:
case BYTESCLASS:
case RAWCLASS:
case UNICODECLASS:
if (context.type !== STRINGCONTEXT) {
pushContext(context.level + 1, STRINGCONTEXT);
}
break;
default:
if (context.type === STRINGCONTEXT) {
popContext(true);
}
break;
}
switch(content) {
case '.':
case '@':
// These delimiters don't appear by themselves
if (content !== token.value) {
token.style = ERRORCLASS;
}
break;
case ':':
// Colons only delimit scope inside a normal scope
if (context.type === NORMALCONTEXT) {
context.startNewScope = context.level+indentUnit;
}
break;
case '(':
case '[':
case '{':
// These start a sequence scope
pushContext(column + content.length, 'sequence');
break;
case ')':
case ']':
case '}':
// These end a sequence scope
popContext(true);
break;
case 'pass':
case 'return':
// These end a normal scope
if (context.type === NORMALCONTEXT) {
context.endOfScope = true;
}
break;
case '\n':
// Reset our column
column = basecolumn;
// Make any scope changes
if (context.endOfScope) {
context.endOfScope = false;
popContext();
} else if (context.startNewScope !== false) {
var temp = context.startNewScope;
context.startNewScope = false;
pushContext(temp, NORMALCONTEXT);
}
// Newlines require an indentation function wrapped in a closure for proper context.
token.indentation = indentPython(context);
break;
}
// Keep track of current column for certain scopes.
if (content != '\n') {
column += token.value.length;
}
lastToken = token;
return token;
},
copy: function() {
var _context = context, _tokenState = tokens.state;
return function(source) {
tokens = tokenizePython(source, _tokenState);
context = _context;
return iter;
};
}
};
return iter;
}
return {make: parsePython,
electricChars: "",
configure: configure};
})();