Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
044a8a5c
Commit
044a8a5c
authored
Feb 11, 2013
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CodeMirror.
parent
039160f5
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
382 additions
and
20 deletions
+382
-20
cms/static/js/views/settings/advanced_view.js
+12
-16
cms/static/sass/_settings.scss
+10
-4
common/static/js/vendor/CodeMirror/javascript.js
+360
-0
No files found.
cms/static/js/views/settings/advanced_view.js
View file @
044a8a5c
...
...
@@ -55,36 +55,32 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
attachJSONEditor
:
function
(
textarea
)
{
var
self
=
this
;
CodeMirror
.
fromTextArea
(
textarea
,
{
mode
:
"
text/html"
,
lineNumbers
:
tru
e
,
lineWrapping
:
true
,
mode
:
"
application/json"
,
lineNumbers
:
fals
e
,
lineWrapping
:
true
,
onBlur
:
function
(
mirror
)
{
var
key
=
$
(
mirror
.
getWrapperElement
()).
closest
(
'.row'
).
children
(
'.key'
).
attr
(
'id'
);
mirror
.
save
();
var
quotedValue
=
mirror
.
getValue
();
// TODO: error checking
var
JSONValue
=
JSON
.
parse
(
quotedValue
);
self
.
model
.
set
(
key
,
JSONValue
,
{
validate
:
true
});
self
.
showMessage
(
self
.
unsaved_changes
);
// cachethis.clearValidationErrors();
// var newVal = mirror.getValue();
// if (cachethis.model.get(field) != newVal) cachethis.model.save(field, newVal,
// { error: CMS.ServerError});
}
});
},
showMessage
:
function
(
type
)
{
this
.
$el
.
find
(
".message-status"
).
removeClass
(
"is-shown"
);
//
var saveButton = this.$el.find(".save-button").addClass('disabled');
//
var cancelButton = this.$el.find(".cancel-button").addClass('disabled');
var
saveButton
=
this
.
$el
.
find
(
".save-button"
).
addClass
(
'disabled'
);
var
cancelButton
=
this
.
$el
.
find
(
".cancel-button"
).
addClass
(
'disabled'
);
if
(
type
)
{
if
(
type
===
this
.
error_saving
)
{
this
.
$el
.
find
(
".message-status.error"
).
addClass
(
"is-shown"
);
//
saveButton.removeClass("disabled");
//
cancelButton.removeClass("disabled");
saveButton
.
removeClass
(
"disabled"
);
cancelButton
.
removeClass
(
"disabled"
);
}
else
if
(
type
===
this
.
unsaved_changes
)
{
this
.
$el
.
find
(
".message-status.warning"
).
addClass
(
"is-shown"
);
//
saveButton.removeClass("disabled");
//
cancelButton.removeClass("disabled");
saveButton
.
removeClass
(
"disabled"
);
cancelButton
.
removeClass
(
"disabled"
);
}
else
if
(
type
===
this
.
successful_changes
)
this
.
$el
.
find
(
".message-status.confirm"
).
addClass
(
"is-shown"
);
...
...
@@ -136,8 +132,8 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
// disable the value entry until there's an acceptable key
$
(
newEle
).
find
(
'.course-advanced-policy-value'
).
addClass
(
'disabled'
);
this
.
fieldToSelectorMap
[
this
.
new_key
]
=
this
.
new_key
;
// need to refind b/c replaceWith seems to copy rather than use the specific ele instance
var
policyValueDivs
=
this
.
$el
.
find
(
'#'
+
this
.
new_key
).
closest
(
'li'
).
find
(
'.
ace
'
);
// need to re
-
find b/c replaceWith seems to copy rather than use the specific ele instance
var
policyValueDivs
=
this
.
$el
.
find
(
'#'
+
this
.
new_key
).
closest
(
'li'
).
find
(
'.
json
'
);
// only 1 but hey, let's take advantage of the context mechanism
_
.
each
(
policyValueDivs
,
this
.
attachJSONEditor
,
this
);
this
.
showMessage
(
this
.
unsaved_changes
);
...
...
@@ -201,8 +197,8 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
// update gui (sets all the ids etc)
var
newEle
=
this
.
template
({
key
:
newKey
,
value
:
JSON
.
stringify
(
this
.
model
.
get
(
newKey
))
});
$
(
event
.
currentTarget
).
closest
(
'li'
).
replaceWith
(
newEle
);
// need to refind b/c replaceWith seems to copy rather than use the specific ele instance
var
policyValueDivs
=
this
.
$el
.
find
(
'#'
+
newKey
).
closest
(
'li'
).
find
(
'.
ace
'
);
// need to re
-
find b/c replaceWith seems to copy rather than use the specific ele instance
var
policyValueDivs
=
this
.
$el
.
find
(
'#'
+
newKey
).
closest
(
'li'
).
find
(
'.
json
'
);
// only 1 but hey, let's take advantage of the context mechanism
_
.
each
(
policyValueDivs
,
this
.
attachJSONEditor
,
this
);
...
...
cms/static/sass/_settings.scss
View file @
044a8a5c
...
...
@@ -550,10 +550,16 @@
}
.settings-advanced
{
.ace
{
height
:
80px
;
border
:
1px
solid
#DDD
;
}
//.CodeMirror {
// border: 1px solid #eee;
// height: auto;
//}
//.CodeMirror-scroll {
// overflow-y: hidden;
// overflow-x: auto;
//}
// messages - should be synced up with global messages in the future
.message
{
...
...
common/static/js/vendor/CodeMirror/javascript.js
0 → 100644
View file @
044a8a5c
CodeMirror
.
defineMode
(
"javascript"
,
function
(
config
,
parserConfig
)
{
var
indentUnit
=
config
.
indentUnit
;
var
jsonMode
=
parserConfig
.
json
;
// Tokenizer
var
keywords
=
function
(){
function
kw
(
type
)
{
return
{
type
:
type
,
style
:
"keyword"
};}
var
A
=
kw
(
"keyword a"
),
B
=
kw
(
"keyword b"
),
C
=
kw
(
"keyword c"
);
var
operator
=
kw
(
"operator"
),
atom
=
{
type
:
"atom"
,
style
:
"atom"
};
return
{
"if"
:
A
,
"while"
:
A
,
"with"
:
A
,
"else"
:
B
,
"do"
:
B
,
"try"
:
B
,
"finally"
:
B
,
"return"
:
C
,
"break"
:
C
,
"continue"
:
C
,
"new"
:
C
,
"delete"
:
C
,
"throw"
:
C
,
"var"
:
kw
(
"var"
),
"const"
:
kw
(
"var"
),
"let"
:
kw
(
"var"
),
"function"
:
kw
(
"function"
),
"catch"
:
kw
(
"catch"
),
"for"
:
kw
(
"for"
),
"switch"
:
kw
(
"switch"
),
"case"
:
kw
(
"case"
),
"default"
:
kw
(
"default"
),
"in"
:
operator
,
"typeof"
:
operator
,
"instanceof"
:
operator
,
"true"
:
atom
,
"false"
:
atom
,
"null"
:
atom
,
"undefined"
:
atom
,
"NaN"
:
atom
,
"Infinity"
:
atom
};
}();
var
isOperatorChar
=
/
[
+
\-
*&%=<>!?|
]
/
;
function
chain
(
stream
,
state
,
f
)
{
state
.
tokenize
=
f
;
return
f
(
stream
,
state
);
}
function
nextUntilUnescaped
(
stream
,
end
)
{
var
escaped
=
false
,
next
;
while
((
next
=
stream
.
next
())
!=
null
)
{
if
(
next
==
end
&&
!
escaped
)
return
false
;
escaped
=
!
escaped
&&
next
==
"
\
\"
;
}
return escaped;
}
// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;
function ret(tp, style, cont) {
type = tp; content = cont;
return style;
}
function jsTokenBase(stream, state) {
var ch = stream.next();
if (ch == '"
' || ch == "'
")
return chain(stream, state, jsTokenString(ch));
else if (/[
\
[
\
]{}
\
(
\
),;
\
:
\
.]/.test(ch))
return ret(ch);
else if (ch == "
0
" && stream.eat(/x/i)) {
stream.eatWhile(/[
\
da-f]/i);
return ret("
number
", "
number
");
}
else if (/
\
d/.test(ch)) {
stream.match(/^
\
d*(?:
\
.
\
d*)?(?:[eE][+
\
-]?
\
d+)?/);
return ret("
number
", "
number
");
}
else if (ch == "
/
") {
if (stream.eat("
*
")) {
return chain(stream, state, jsTokenComment);
}
else if (stream.eat("
/
")) {
stream.skipToEnd();
return ret("
comment
", "
comment
");
}
else if (state.reAllowed) {
nextUntilUnescaped(stream, "
/
");
stream.eatWhile(/[gimy]/); // 'y' is "
sticky
" option in Mozilla
return ret("
regexp
", "
string
-
2
");
}
else {
stream.eatWhile(isOperatorChar);
return ret("
operator
", null, stream.current());
}
}
else if (ch == "
#
") {
stream.skipToEnd();
return ret("
error
", "
error
");
}
else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("
operator
", null, stream.current());
}
else {
stream.eatWhile(/[
\
w
\
$_]/);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
ret("
variable
", "
variable
", word);
}
}
function jsTokenString(quote) {
return function(stream, state) {
if (!nextUntilUnescaped(stream, quote))
state.tokenize = jsTokenBase;
return ret("
string
", "
string
");
};
}
function jsTokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "
/
" && maybeEnd) {
state.tokenize = jsTokenBase;
break;
}
maybeEnd = (ch == "
*
");
}
return ret("
comment
", "
comment
");
}
// Parser
var atomicTypes = {"
atom
": true, "
number
": true, "
variable
": true, "
string
": true, "
regexp
": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
this.column = column;
this.type = type;
this.prev = prev;
this.info = info;
if (align != null) this.align = align;
}
function inScope(state, varname) {
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
}
function parseJS(state, style, type, content, stream) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
if (!state.lexical.hasOwnProperty("
align
"))
state.lexical.align = true;
while(true) {
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
if (combinator(type, content)) {
while(cc.length && cc[cc.length - 1].lex)
cc.pop()();
if (cx.marked) return cx.marked;
if (type == "
variable
" && inScope(state, content)) return "
variable
-
2
";
return style;
}
}
}
// Combinator utils
var cx = {state: null, column: null, marked: null, cc: null};
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function register(varname) {
var state = cx.state;
if (state.context) {
cx.marked = "
def
";
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return;
state.localVars = {name: varname, next: state.localVars};
}
}
// Combinators
var defaultVars = {name: "
this
", next: {name: "
arguments
"}};
function pushcontext() {
if (!cx.state.context) cx.state.localVars = defaultVars;
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
}
function popcontext() {
cx.state.localVars = cx.state.context.vars;
cx.state.context = cx.state.context.prev;
}
function pushlex(type, info) {
var result = function() {
var state = cx.state;
state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
};
result.lex = true;
return result;
}
function poplex() {
var state = cx.state;
if (state.lexical.prev) {
if (state.lexical.type == "
)
")
state.indented = state.lexical.indented;
state.lexical = state.lexical.prev;
}
}
poplex.lex = true;
function expect(wanted) {
return function expecting(type) {
if (type == wanted) return cont();
else if (wanted == "
;
") return pass();
else return cont(arguments.callee);
};
}
function statement(type) {
if (type == "
var
") return cont(pushlex("
vardef
"), vardef1, expect("
;
"), poplex);
if (type == "
keyword
a
") return cont(pushlex("
form
"), expression, statement, poplex);
if (type == "
keyword
b
") return cont(pushlex("
form
"), statement, poplex);
if (type == "
{
") return cont(pushlex("
}
"), block, poplex);
if (type == "
;
") return cont();
if (type == "
function
") return cont(functiondef);
if (type == "
for
") return cont(pushlex("
form
"), expect("
(
"), pushlex("
)
"), forspec1, expect("
)
"),
poplex, statement, poplex);
if (type == "
variable
") return cont(pushlex("
stat
"), maybelabel);
if (type == "
switch
") return cont(pushlex("
form
"), expression, pushlex("
}
", "
switch
"), expect("
{
"),
block, poplex, poplex);
if (type == "
case
") return cont(expression, expect("
:
"));
if (type == "
default
") return cont(expect("
:
"));
if (type == "
catch
") return cont(pushlex("
form
"), pushcontext, expect("
(
"), funarg, expect("
)
"),
statement, poplex, popcontext);
return pass(pushlex("
stat
"), expression, expect("
;
"), poplex);
}
function expression(type) {
if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
if (type == "
function
") return cont(functiondef);
if (type == "
keyword
c
") return cont(maybeexpression);
if (type == "
(
") return cont(pushlex("
)
"), maybeexpression, expect("
)
"), poplex, maybeoperator);
if (type == "
operator
") return cont(expression);
if (type == "
[
") return cont(pushlex("
]
"), commasep(expression, "
]
"), poplex, maybeoperator);
if (type == "
{
") return cont(pushlex("
}
"), commasep(objprop, "
}
"), poplex, maybeoperator);
return cont();
}
function maybeexpression(type) {
if (type.match(/[;
\
}
\
)
\
],]/)) return pass();
return pass(expression);
}
function maybeoperator(type, value) {
if (type == "
operator
" && /
\
+
\
+|--/.test(value)) return cont(maybeoperator);
if (type == "
operator
") return cont(expression);
if (type == "
;
") return;
if (type == "
(
") return cont(pushlex("
)
"), commasep(expression, "
)
"), poplex, maybeoperator);
if (type == "
.
") return cont(property, maybeoperator);
if (type == "
[
") return cont(pushlex("
]
"), expression, expect("
]
"), poplex, maybeoperator);
}
function maybelabel(type) {
if (type == "
:
") return cont(poplex, statement);
return pass(maybeoperator, expect("
;
"), poplex);
}
function property(type) {
if (type == "
variable
") {cx.marked = "
property
"; return cont();}
}
function objprop(type) {
if (type == "
variable
") cx.marked = "
property
";
if (atomicTypes.hasOwnProperty(type)) return cont(expect("
:
"), expression);
}
function commasep(what, end) {
function proceed(type) {
if (type == "
,
") return cont(what, proceed);
if (type == end) return cont();
return cont(expect(end));
}
return function commaSeparated(type) {
if (type == end) return cont();
else return pass(what, proceed);
};
}
function block(type) {
if (type == "
}
") return cont();
return pass(statement, block);
}
function vardef1(type, value) {
if (type == "
variable
"){register(value); return cont(vardef2);}
return cont();
}
function vardef2(type, value) {
if (value == "
=
") return cont(expression, vardef2);
if (type == "
,
") return cont(vardef1);
}
function forspec1(type) {
if (type == "
var
") return cont(vardef1, forspec2);
if (type == "
;
") return pass(forspec2);
if (type == "
variable
") return cont(formaybein);
return pass(forspec2);
}
function formaybein(type, value) {
if (value == "
in
") return cont(expression);
return cont(maybeoperator, forspec2);
}
function forspec2(type, value) {
if (type == "
;
") return cont(forspec3);
if (value == "
in
") return cont(expression);
return cont(expression, expect("
;
"), forspec3);
}
function forspec3(type) {
if (type != "
)
") cont(expression);
}
function functiondef(type, value) {
if (type == "
variable
") {register(value); return cont(functiondef);}
if (type == "
(
") return cont(pushlex("
)
"), pushcontext, commasep(funarg, "
)
"), poplex, statement, popcontext);
}
function funarg(type, value) {
if (type == "
variable
") {register(value); return cont();}
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: jsTokenBase,
reAllowed: true,
kwAllowed: true,
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "
block
", false),
localVars: parserConfig.localVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: 0
};
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("
align
"))
state.lexical.align = false;
state.indented = stream.indentation();
}
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "
comment
") return style;
state.reAllowed = !!(type == "
operator
" || type == "
keyword
c
" || type.match(/^[
\
[{}
\
(,;:]$/));
state.kwAllowed = type != '.';
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
if (state.tokenize != jsTokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
type = lexical.type, closing = firstChar == type;
if (type == "
vardef
") return lexical.indented + 4;
else if (type == "
form
" && firstChar == "
{
") return lexical.indented;
else if (type == "
stat
" || type == "
form
") return lexical.indented + indentUnit;
else if (lexical.info == "
switch
" && !closing)
return lexical.indented + (/^(?:case|default)
\
b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
},
electricChars: "
:{}
"
};
});
CodeMirror.defineMIME("
text
/
javascript
", "
javascript
");
CodeMirror.defineMIME("
application
/
json
", {name: "
javascript
", json: true});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment