first commit

This commit is contained in:
alazhar
2020-01-02 22:20:31 +07:00
commit 10eb3340ad
5753 changed files with 631345 additions and 0 deletions

View File

@ -0,0 +1,24 @@
.CodeMirror-wrapping {
/* Give some indication of the edge of the editor */
border: 1px solid #ddd;
/* Ensure that the width is correct whether padding for line numbers or not */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.CodeMirror-wrapping iframe {
/* Give the text area a slightly inset appearance */
box-shadow: inset 0 0 8px #ddd;
}
.CodeMirror-line-numbers {
width: 2.2em;
color: #aaa;
background-color: #eee;
text-align: right;
padding-right: .3em;
font-size: 10pt;
font-family: monospace;
padding-top: .4em;
}

View File

@ -0,0 +1,55 @@
html {
cursor: text;
}
.editbox {
margin: .4em;
padding: 0;
font-family: monospace;
font-size: 10pt;
color: black;
}
pre.code, .editbox {
color: #666;
}
.editbox p {
margin: 0;
}
span.css-at {
color: #708;
}
span.css-unit {
color: #281;
}
span.css-value {
color: #708;
}
span.css-identifier {
color: black;
}
span.css-selector {
color: #11B;
}
span.css-important {
color: #00F;
}
span.css-colorcode {
color: #299;
}
span.css-comment {
color: #A70;
}
span.css-string {
color: #A22;
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,59 @@
html {
cursor: text;
}
.editbox {
margin: .4em;
padding: 0;
font-family: monospace;
font-size: 10pt;
color: black;
}
pre.code, .editbox {
color: #666666;
}
.editbox p {
margin: 0;
}
span.js-punctuation {
color: #666666;
}
span.js-operator {
color: #666666;
}
span.js-keyword {
color: #770088;
}
span.js-atom {
color: #228811;
}
span.js-variable {
color: black;
}
span.js-variabledef {
color: #0000FF;
}
span.js-localvariable {
color: #004499;
}
span.js-property {
color: black;
}
span.js-comment {
color: #AA7700;
}
span.js-string {
color: #AA2222;
}

View File

@ -0,0 +1,110 @@
/*
Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
The copyrights embodied in the content of this file are licensed by
Yahoo! Inc. under the BSD (revised) open source license
@author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
*/
html {
cursor: text;
}
.editbox {
margin: .4em;
padding: 0;
font-family: monospace;
font-size: 10pt;
}
/*We should define specific styles for every element of the syntax.
the setting below will cause some annoying color to show through if we missed
defining a style for a token. This is also the "color" of the whitespace and
of the cursor.
*/
pre.code, .editbox {
color: red;
}
.editbox p {
margin: 0;
}
span.php-punctuation {
color: blue;
}
span.php-keyword {
color: #770088;
font-weight: bold;
}
span.php-operator {
color: blue;
}
/* __FILE__ etc.; http://php.net/manual/en/reserved.php */
span.php-compile-time-constant {
color: #776088;
font-weight: bold;
}
/* output of get_defined_constants(). Differs from http://php.net/manual/en/reserved.constants.php */
span.php-predefined-constant {
color: darkgreen;
font-weight: bold;
}
/* PHP reserved "language constructs"... echo() etc.; http://php.net/manual/en/reserved.php */
span.php-reserved-language-construct {
color: green;
font-weight: bold;
}
/* PHP built-in functions: glob(), chr() etc.; output of get_defined_functions()["internal"] */
span.php-predefined-function {
color: green;
}
/* PHP predefined classes: PDO, Exception etc.; output of get_declared_classes() and different from http://php.net/manual/en/reserved.classes.php */
span.php-predefined-class {
color: green;
}
span.php-atom {
color: #228811;
}
/* class, interface, namespace or function names, but not $variables */
span.php-t_string {
color: black;
}
span.php-variable {
color: black;
font-weight: bold;
}
span.js-localvariable {
color: #004499;
}
span.php-comment {
color: #AA7700;
font-stretch: condensed;
/* font-style: italic; This causes line height to slightly change, getting line numbers out of sync */
}
span.php-string-single-quoted {
color: #AA2222;
}
/* double quoted strings allow interpolation */
span.php-string-double-quoted {
color: #AA2222;
font-weight: bold;
}
span.deprecated {
font-size: smaller;
}

View File

@ -0,0 +1,43 @@
html {
cursor: text;
}
.editbox {
margin: .4em;
padding: 0;
font-family: monospace;
font-size: 10pt;
color: black;
}
.editbox p {
margin: 0;
}
span.sp-keyword {
color: #708;
}
span.sp-prefixed {
color: #5d1;
}
span.sp-var {
color: #00c;
}
span.sp-comment {
color: #a70;
}
span.sp-literal {
color: #a22;
}
span.sp-uri {
color: #292;
}
span.sp-operator {
color: #088;
}

View File

@ -0,0 +1,55 @@
html {
cursor: text;
}
.editbox {
margin: .4em;
padding: 0;
font-family: monospace;
font-size: 10pt;
color: black;
}
.editbox p {
margin: 0;
}
span.xml-tagname {
color: #A0B;
}
span.xml-attribute {
color: #281;
}
span.xml-punctuation {
color: black;
}
span.xml-attname {
color: #00F;
}
span.xml-comment {
color: #A70;
}
span.xml-cdata {
color: #48A;
}
span.xml-processing {
color: #999;
}
span.xml-entity {
color: #A22;
}
span.xml-error {
color: #F00 !important;
}
span.xml-text {
color: black;
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
var internetExplorer=document.selection&&window.ActiveXObject&&/MSIE/.test(navigator.userAgent),webkit=/AppleWebKit/.test(navigator.userAgent),safari=/Apple Computer, Inc/.test(navigator.vendor),gecko=navigator.userAgent.match(/gecko\/(\d{8})/i);if(gecko)gecko=Number(gecko[1]);var mac=/Mac/.test(navigator.platform),brokenOpera=window.opera&&/Version\/10.[56]/.test(navigator.userAgent),slowWebkit=/AppleWebKit\/533/.test(navigator.userAgent);
function makeWhiteSpace(f){for(var l=[],k=true;f>0;f--){l.push(k||f==1?nbsp:" ");k^=true}return l.join("")}function fixSpaces(f){if(f.charAt(0)==" ")f=nbsp+f.slice(1);return f.replace(/\t/g,function(){return makeWhiteSpace(indentUnit)}).replace(/[ \u00a0]{2,}/g,function(l){return makeWhiteSpace(l.length)})}function cleanText(f){return f.replace(/\u00a0/g," ").replace(/\u200b/g,"")}
function makePartSpan(f){var l=f;if(f.nodeType==3)l=f.nodeValue;else f=document.createTextNode(l);var k=document.createElement("span");k.isPart=true;k.appendChild(f);k.currentText=l;return k}function alwaysZero(){return 0}var webkitLastLineHack=webkit?function(f){var l=f.lastChild;if(!l||!l.hackBR){l=document.createElement("br");l.hackBR=true;f.appendChild(l)}}:function(){};
function asEditorLines(f){var l=makeWhiteSpace(indentUnit);return map(f.replace(/\t/g,l).replace(/\u00a0/g," ").replace(/\r\n?/g,"\n").split("\n"),fixSpaces)}
var Editor=function(){function f(a,d){function g(e,h){if(e.nodeType==3){if((e.nodeValue=fixSpaces(e.nodeValue.replace(/[\r\u200b]/g,"").replace(/\n/g," "))).length)c=false;b.push(e)}else if(isBR(e)&&e.childNodes.length==0){c=true;b.push(e)}else{for(var j=e.firstChild;j;j=j.nextSibling)g(j);if(!c&&w.hasOwnProperty(e.nodeName.toUpperCase())){c=true;if(!d||!h)b.push(document.createElement("br"))}}}var b=[],c=true;g(a,true);return b}function l(a){function d(e){var h=e.parentNode,j=e.nextSibling;return function(i){h.insertBefore(i,
j)}}var g=[],b=null,c=true;return{next:function(){if(!a)throw StopIteration;var e=a;a=e.nextSibling;var h;if(e.isPart&&e.childNodes.length==1&&e.firstChild.nodeType==3){h=e.firstChild.nodeValue;e.dirty=e.dirty||h!=e.currentText;e.currentText=h;h=!/[\n\t\r]/.test(e.currentText)}else h=false;if(h){g.push(e);c=false;return e.currentText}else if(isBR(e)){c&&window.opera&&e.parentNode.insertBefore(makePartSpan(""),e);g.push(e);c=true;return"\n"}else{h=!e.nextSibling;b=d(e);removeElement(e);e=f(e,h);for(h=
0;h<e.length;h++){var j=e,i=h,n=e[h],r="\n";if(n.nodeType==3){select.snapshotChanged();n=makePartSpan(n);r=n.currentText;c=false}else{c&&window.opera&&b(makePartSpan(""));c=true}n.dirty=true;g.push(n);b(n);j[i]=r}return e.join("")}},nodes:g}}function k(a){for(;a&&!isBR(a);)a=a.previousSibling;return a}function m(a,d){if(a){if(isBR(a))a=a.nextSibling}else a=d.firstChild;for(;a&&!isBR(a);)a=a.nextSibling;return a}function q(a,d,g,b){function c(i){i=cleanText(a.history.textAfter(i));return b?i.toLowerCase():
i}this.editor=a;this.history=a.history;this.history.commit();this.valid=!!d;this.atOccurrence=false;if(b==undefined)b=typeof d=="string"&&d==d.toLowerCase();var e={node:null,offset:0},h=this;if(g&&typeof g=="object"&&typeof g.character=="number"){a.checkLine(g.line);g={node:g.line,offset:g.character};this.pos={from:g,to:g}}else this.pos=g?{from:select.cursorPos(a.container,true)||e,to:select.cursorPos(a.container,false)||e}:{from:e,to:e};if(typeof d!="string")this.matches=function(i,n,r){if(i){i=
c(n).slice(0,r);var t=i.match(d);for(r=0;t;){var o=i.indexOf(t[0]);r+=o;i=i.slice(o+1);if(o=i.match(d))t=o;else break}}else{i=c(n).slice(r);r=(t=i.match(d))&&r+i.indexOf(t[0])}if(t){h.currentMatch=t;return{from:{node:n,offset:r},to:{node:n,offset:r+t[0].length}}}};else{if(b)d=d.toLowerCase();var j=d.split("\n");this.matches=j.length==1?function(i,n,r){var t=c(n),o=d.length,u;if(i?r>=o&&(u=t.lastIndexOf(d,r-o))!=-1:(u=t.indexOf(d,r))!=-1)return{from:{node:n,offset:u},to:{node:n,offset:u+o}}}:function(i,
n,r){var t=i?j.length-1:0,o=j[t],u=c(n),x=i?u.indexOf(o)+o.length:u.lastIndexOf(o);if(!(i?x>=r||x!=o.length:x<=r||x!=u.length-o.length))for(r=n;;){if(i&&!r)break;r=i?this.history.nodeBefore(r):this.history.nodeAfter(r);if(!i&&!r)break;u=c(r);o=j[i?--t:++t];if(t>0&&t<j.length-1)if(u!=o)break;else continue;t=i?u.lastIndexOf(o):u.indexOf(o)+o.length;if(i?t!=u.length-o.length:t!=o.length)break;return{from:{node:i?r:n,offset:i?t:x},to:{node:i?n:r,offset:i?x:t}}}}}}function p(a){this.options=a;window.indentUnit=
a.indentUnit;var d=this.container=document.body;this.history=new UndoHistory(d,a.undoDepth,a.undoDelay,this);var g=this;if(!p.Parser)throw"No parser loaded.";a.parserConfig&&p.Parser.configure&&p.Parser.configure(a.parserConfig);!a.readOnly&&!internetExplorer&&select.setCursorPos(d,{node:null,offset:0});this.dirty=[];this.importCode(a.content||"");this.history.onChange=a.onChange;if(a.readOnly){if(!a.textWrapping)d.style.whiteSpace="nowrap"}else{if(a.continuousScanning!==false){this.scanner=this.documentScanner(a.passTime);
this.delayScanning()}var b=function(){if(document.body.contentEditable!=undefined&&internetExplorer)document.body.contentEditable="true";else document.designMode="on";if(internetExplorer&&a.height!="dynamic")document.body.style.minHeight=window.frameElement.clientHeight-2*document.body.offsetTop-5+"px";document.documentElement.style.borderWidth="0";if(!a.textWrapping)d.style.whiteSpace="nowrap"};try{b()}catch(c){var e=addEventHandler(document,"focus",function(){e();b()},true)}addEventHandler(document,
"keydown",method(this,"keyDown"));addEventHandler(document,"keypress",method(this,"keyPress"));addEventHandler(document,"keyup",method(this,"keyUp"));var h=function(){g.cursorActivity(false)};addEventHandler(internetExplorer?document.body:window,"mouseup",h);addEventHandler(document.body,"cut",h);gecko&&addEventHandler(window,"pagehide",function(){g.unloaded=true});addEventHandler(document.body,"paste",function(j){h();var i=null;try{var n=j.clipboardData||window.clipboardData;if(n)i=n.getData("Text")}catch(r){}if(i!==
null){j.stop();g.replaceSelection(i);select.scrollToCursor(g.container)}});this.options.autoMatchParens&&addEventHandler(document.body,"click",method(this,"scheduleParenHighlight"))}}var w={P:true,DIV:true,LI:true};q.prototype={findNext:function(){return this.find(false)},findPrevious:function(){return this.find(true)},find:function(a){function d(){var h={node:c,offset:e};g.pos={from:h,to:h};return g.atOccurrence=false}if(!this.valid)return false;var g=this,b=a?this.pos.from:this.pos.to,c=b.node,
e=b.offset;if(c&&!c.parentNode){c=null;e=0}for(;;){if(this.pos=this.matches(a,c,e))return this.atOccurrence=true;if(a){if(!c)return d();c=this.history.nodeBefore(c);e=this.history.textAfter(c).length}else{b=this.history.nodeAfter(c);if(!b){e=this.history.textAfter(c).length;return d()}c=b;e=0}}},select:function(){if(this.atOccurrence){select.setCursorPos(this.editor.container,this.pos.from,this.pos.to);select.scrollToCursor(this.editor.container)}},replace:function(a){if(this.atOccurrence){var d=
this.currentMatch;if(d)a=a.replace(/\\(\d)/,function(g,b){return d[b]});this.pos.to=this.editor.replaceRange(this.pos.from,this.pos.to,a);this.atOccurrence=false}},position:function(){if(this.atOccurrence)return{line:this.pos.from.node,character:this.pos.from.offset}}};p.prototype={importCode:function(a){var d=asEditorLines(a);if(!this.options.incrementalLoading||d.length<1E3){this.history.push(null,null,d);this.history.reset()}else{var g=0,b=this,c=function(){var e=d.slice(g,g+1E3);e.push("");b.history.push(b.history.nodeBefore(null),
null,e);b.history.reset();g+=1E3;g<d.length&&parent.setTimeout(c,1E3)};c()}},getCode:function(){if(!this.container.firstChild)return"";var a=[];select.markSelection();forEach(l(this.container.firstChild),method(a,"push"));select.selectMarked();webkit&&this.container.lastChild.hackBR&&a.pop();webkitLastLineHack(this.container);return cleanText(a.join(""))},checkLine:function(a){if(a===false||!(a==null||a.parentNode==this.container||a.hackBR))throw parent.CodeMirror.InvalidLineHandle;},cursorPosition:function(a){if(a==
null)a=true;return(a=select.cursorPos(this.container,a))?{line:a.node,character:a.offset}:{line:null,character:0}},firstLine:function(){return null},lastLine:function(){var a=this.container.lastChild;if(a)a=k(a);if(a&&a.hackBR)a=k(a.previousSibling);return a},nextLine:function(a){this.checkLine(a);a=m(a,this.container);return!a||a.hackBR?false:a},prevLine:function(a){this.checkLine(a);if(a==null)return false;return k(a.previousSibling)},visibleLineCount:function(){for(var a=this.container.firstChild;a&&
isBR(a);)a=a.nextSibling;if(!a)return false;return Math.floor((window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)/a.offsetHeight)},selectLines:function(a,d,g,b){this.checkLine(a);a={node:a,offset:d};d=null;if(b!==undefined){this.checkLine(g);d={node:g,offset:b}}select.setCursorPos(this.container,a,d);select.scrollToCursor(this.container)},lineContent:function(a){var d=[];for(a=a?a.nextSibling:this.container.firstChild;a&&!isBR(a);a=a.nextSibling)d.push(nodeText(a));
return cleanText(d.join(""))},setLineContent:function(a,d){this.history.commit();this.replaceRange({node:a,offset:0},{node:a,offset:this.history.textAfter(a).length},d);this.addDirtyNode(a);this.scheduleHighlight()},removeLine:function(a){for(var d=a?a.nextSibling:this.container.firstChild;d;){var g=d.nextSibling;removeElement(d);if(isBR(d))break;d=g}this.addDirtyNode(a);this.scheduleHighlight()},insertIntoLine:function(a,d,g){var b=null;if(d=="end")b=m(a,this.container);else for(var c=a?a.nextSibling:
this.container.firstChild;c;c=c.nextSibling){if(d==0){b=c;break}var e=nodeText(c);if(e.length>d){b=c.nextSibling;g=e.slice(0,d)+g+e.slice(d);removeElement(c);break}d-=e.length}d=asEditorLines(g);for(g=0;g<d.length;g++){g>0&&this.container.insertBefore(document.createElement("BR"),b);this.container.insertBefore(makePartSpan(d[g]),b)}this.addDirtyNode(a);this.scheduleHighlight()},selectedText:function(){var a=this.history;a.commit();var d=select.cursorPos(this.container,true),g=select.cursorPos(this.container,
false);if(!d||!g)return"";if(d.node==g.node)return a.textAfter(d.node).slice(d.offset,g.offset);var b=[a.textAfter(d.node).slice(d.offset)];for(d=a.nodeAfter(d.node);d!=g.node;d=a.nodeAfter(d))b.push(a.textAfter(d));b.push(a.textAfter(g.node).slice(0,g.offset));return cleanText(b.join("\n"))},replaceSelection:function(a){this.history.commit();var d=select.cursorPos(this.container,true),g=select.cursorPos(this.container,false);if(d&&g){g=this.replaceRange(d,g,a);select.setCursorPos(this.container,
g);webkitLastLineHack(this.container)}},cursorCoords:function(a,d){function g(i,n){var r=-(document.body.scrollTop||document.documentElement.scrollTop||0),t=-(document.body.scrollLeft||document.documentElement.scrollLeft||0)+n;forEach([i,d?null:window.frameElement],function(o){for(;o;){t+=o.offsetLeft;r+=o.offsetTop;o=o.offsetParent}});return{x:t,y:r,yBot:r+i.offsetHeight}}function b(i,n){var r=document.createElement("SPAN");r.appendChild(document.createTextNode(i));try{return n(r)}finally{r.parentNode&&
r.parentNode.removeChild(r)}}var c=select.cursorPos(this.container,a);if(!c)return null;for(var e=c.offset,h=c.node,j=this;e;){h=h?h.nextSibling:this.container.firstChild;c=nodeText(h);if(e<c.length)return b(c.substr(0,e),function(i){i.style.position="absolute";i.style.visibility="hidden";i.className=h.className;j.container.appendChild(i);return g(h,i.offsetWidth)});e-=c.length}return h&&isSpan(h)?g(h,h.offsetWidth):h&&h.nextSibling&&isSpan(h.nextSibling)?g(h.nextSibling,0):b("\u200b",function(i){h?
h.parentNode.insertBefore(i,h.nextSibling):j.container.insertBefore(i,j.container.firstChild);return g(i,0)})},reroutePasteEvent:function(){if(!(this.capturingPaste||window.opera||gecko&&gecko>=20101026)){this.capturingPaste=true;var a=window.frameElement.CodeMirror.textareaHack,d=this.cursorCoords(true,true);a.style.top=d.y+"px";if(internetExplorer)if(d=select.getBookmark(this.container))this.selectionSnapshot=d;parent.focus();a.value="";a.focus();var g=this;parent.setTimeout(function(){g.capturingPaste=
false;window.focus();g.selectionSnapshot&&window.select.setBookmark(g.container,g.selectionSnapshot);var b=a.value;if(b){g.replaceSelection(b);select.scrollToCursor(g.container)}},10)}},replaceRange:function(a,d,g){g=asEditorLines(g);g[0]=this.history.textAfter(a.node).slice(0,a.offset)+g[0];var b=g[g.length-1];g[g.length-1]=b+this.history.textAfter(d.node).slice(d.offset);d=this.history.nodeAfter(d.node);this.history.push(a.node,d,g);return{node:this.history.nodeBefore(d),offset:b.length}},getSearchCursor:function(a,
d,g){return new q(this,a,d,g)},reindent:function(){this.container.firstChild&&this.indentRegion(null,this.container.lastChild)},reindentSelection:function(a){if(select.somethingSelected()){var d=select.selectionTopNode(this.container,true),g=select.selectionTopNode(this.container,false);d===false||g===false||this.indentRegion(d,g,a,true)}else this.indentAtCursor(a)},grabKeys:function(a,d){this.frozen=a;this.keyFilter=d},ungrabKeys:function(){this.frozen="leave"},setParser:function(a,d){p.Parser=window[a];
(d=d||this.options.parserConfig)&&p.Parser.configure&&p.Parser.configure(d);if(this.container.firstChild){forEach(this.container.childNodes,function(g){if(g.nodeType!=3)g.dirty=true});this.addDirtyNode(this.firstChild);this.scheduleHighlight()}},keyDown:function(a){if(this.frozen=="leave")this.keyFilter=this.frozen=null;if(this.frozen&&(!this.keyFilter||this.keyFilter(a.keyCode,a))){a.stop();this.frozen(a)}else{var d=a.keyCode;this.delayScanning();this.options.autoMatchParens&&this.scheduleParenHighlight();
if(d==13){if(a.ctrlKey&&!a.altKey)this.reparseBuffer();else{select.insertNewlineAtCursor();d=this.options.enterMode;if(d!="flat")this.indentAtCursor(d=="keep"?"keep":undefined);select.scrollToCursor(this.container)}a.stop()}else if(d==9&&this.options.tabMode!="default"&&!a.ctrlKey){this.handleTab(!a.shiftKey);a.stop()}else if(d==32&&a.shiftKey&&this.options.tabMode=="default"){this.handleTab(true);a.stop()}else if(d==36&&!a.shiftKey&&!a.ctrlKey)this.home()&&a.stop();else if(d==35&&!a.shiftKey&&!a.ctrlKey)this.end()&&
a.stop();else if(d==33&&!a.shiftKey&&!a.ctrlKey&&!gecko)this.pageUp()&&a.stop();else if(d==34&&!a.shiftKey&&!a.ctrlKey&&!gecko)this.pageDown()&&a.stop();else if((d==219||d==221)&&a.ctrlKey&&!a.altKey){this.highlightParens(a.shiftKey,true);a.stop()}else if(a.metaKey&&!a.shiftKey&&(d==37||d==39)){var g=select.selectionTopNode(this.container);if(!(g===false||!this.container.firstChild)){if(d==37)select.focusAfterNode(k(g),this.container);else{d=m(g,this.container);select.focusAfterNode(d?d.previousSibling:
this.container.lastChild,this.container)}a.stop()}}else if((a.ctrlKey||a.metaKey)&&!a.altKey)if(a.shiftKey&&d==90||d==89){select.scrollToNode(this.history.redo());a.stop()}else if(d==90||safari&&d==8){select.scrollToNode(this.history.undo());a.stop()}else if(d==83&&this.options.saveFunction){this.options.saveFunction();a.stop()}else d==86&&!mac&&this.reroutePasteEvent()}},keyPress:function(a){var d=this.options.electricChars&&p.Parser.electricChars,g=this;if(this.frozen&&(!this.keyFilter||this.keyFilter(a.keyCode||
a.code,a))||a.code==13||a.code==9&&this.options.tabMode!="default"||a.code==32&&a.shiftKey&&this.options.tabMode=="default")a.stop();else if(mac&&(a.ctrlKey||a.metaKey)&&a.character=="v")this.reroutePasteEvent();else if(d&&d.indexOf(a.character)!=-1)parent.setTimeout(function(){g.indentAtCursor(null)},0);else if(brokenOpera)if(a.code==8){var b=select.selectionTopNode(this.container);g=this;var c=b?b.nextSibling:this.container.firstChild;b!==false&&c&&isBR(c)&&parent.setTimeout(function(){select.selectionTopNode(g.container)==
c&&select.focusAfterNode(c.previousSibling,g.container)},20)}else{if(a.code==46){b=select.selectionTopNode(this.container);g=this;b&&isBR(b)&&parent.setTimeout(function(){select.selectionTopNode(g.container)!=b&&select.focusAfterNode(b,g.container)},20)}}else if(slowWebkit){c=(b=select.selectionTopNode(this.container))?b.nextSibling:this.container.firstChild;if(b&&c&&isBR(c)&&!isBR(b)){var e=document.createTextNode("\u200b");this.container.insertBefore(e,c);parent.setTimeout(function(){if(e.nodeValue==
"\u200b")removeElement(e);else e.nodeValue=e.nodeValue.replace("\u200b","")},20)}}webkit&&!this.options.textWrapping&&setTimeout(function(){var h=select.selectionTopNode(g.container,true);h&&h.nodeType==3&&h.previousSibling&&isBR(h.previousSibling)&&h.nextSibling&&isBR(h.nextSibling)&&h.parentNode.replaceChild(document.createElement("BR"),h.previousSibling)},50)},keyUp:function(a){this.cursorActivity(a.keyCode>=16&&a.keyCode<=18||a.keyCode>=33&&a.keyCode<=40)},indentLineAfter:function(a,d){function g(n){n=
n?n.nextSibling:b.container.firstChild;if(!n||!hasClass(n,"whitespace"))return null;return n}var b=this,c=g(a),e=0,h=c?c.currentText.length:0,j=c?c.nextSibling:a?a.nextSibling:this.container.firstChild;if(d=="keep"){if(a){var i=g(k(a.previousSibling));if(i)e=i.currentText.length}}else{i=a&&j&&j.currentText?j.currentText:"";if(d!=null&&this.options.tabMode!="indent")e=d?h+indentUnit:Math.max(0,h-indentUnit);else if(a)e=a.indentation(i,h,d,j);else if(p.Parser.firstIndentation)e=p.Parser.firstIndentation(i,
h,d,j)}h=e-h;if(h<0)if(e==0){if(j)select.snapshotMove(c.firstChild,j.firstChild||j,0);removeElement(c);c=null}else{select.snapshotMove(c.firstChild,c.firstChild,h,true);c.currentText=makeWhiteSpace(e);c.firstChild.nodeValue=c.currentText}else if(h>0)if(c){c.currentText=makeWhiteSpace(e);c.firstChild.nodeValue=c.currentText;select.snapshotMove(c.firstChild,c.firstChild,h,true)}else{c=makePartSpan(makeWhiteSpace(e));c.className="whitespace";a?insertAfter(c,a):this.container.insertBefore(c,this.container.firstChild);
select.snapshotMove(j&&(j.firstChild||j),c.firstChild,e,false,true)}else c&&select.snapshotMove(c.firstChild,c.firstChild,e,false);h!=0&&this.addDirtyNode(a)},highlightAtCursor:function(){var a=select.selectionTopNode(this.container,true),d=select.selectionTopNode(this.container,false);if(a===false||d===false)return false;select.markSelection();if(this.highlight(a,m(d,this.container),true,20)===false)return false;select.selectMarked();return true},handleTab:function(a){this.options.tabMode=="spaces"&&
!select.somethingSelected()?select.insertTabAtCursor():this.reindentSelection(a)},home:function(){var a=select.selectionTopNode(this.container,true),d=a;if(a===false||!(!a||a.isPart||isBR(a))||!this.container.firstChild)return false;for(;a&&!isBR(a);)a=a.previousSibling;var g=a?a.nextSibling:this.container.firstChild;g&&g!=d&&g.isPart&&hasClass(g,"whitespace")?select.focusAfterNode(g,this.container):select.focusAfterNode(a,this.container);select.scrollToCursor(this.container);return true},end:function(){var a=
select.selectionTopNode(this.container,true);if(a===false)return false;a=m(a,this.container);if(!a)return false;select.focusAfterNode(a.previousSibling,this.container);select.scrollToCursor(this.container);return true},pageUp:function(){var a=this.cursorPosition().line,d=this.visibleLineCount();if(a===false||d===false)return false;d-=2;for(var g=0;g<d;g++){a=this.prevLine(a);if(a===false)break}if(g==0)return false;select.setCursorPos(this.container,{node:a,offset:0});select.scrollToCursor(this.container);
return true},pageDown:function(){var a=this.cursorPosition().line,d=this.visibleLineCount();if(a===false||d===false)return false;d-=2;for(var g=0;g<d;g++){var b=this.nextLine(a);if(b===false)break;a=b}if(g==0)return false;select.setCursorPos(this.container,{node:a,offset:0});select.scrollToCursor(this.container);return true},scheduleParenHighlight:function(){this.parenEvent&&parent.clearTimeout(this.parenEvent);var a=this;this.parenEvent=parent.setTimeout(function(){a.highlightParens()},300)},highlightParens:function(a,
d){function g(u,x){if(u)if(j)if(j.call)j(u,x);else u.className+=" "+j[x?0:1];else{u.style.fontWeight="bold";u.style.color=x?"#8F8":"#F88"}}function b(u){if(u)if(j&&!j.call)removeClass(removeClass(u,j[0]),j[1]);else if(h.options.unmarkParen)h.options.unmarkParen(u);else{u.style.fontWeight="";u.style.color=""}}function c(u){if(u.currentText)return(u=u.currentText.match(/^[\s\u00a0]*([\(\)\[\]{}])[\s\u00a0]*$/))&&u[1]}function e(){for(var u=[],x,s=true,v=n;v;v=t?v.nextSibling:v.previousSibling)if(v.className==
r&&isSpan(v)&&(x=c(v))){if(/[\(\[\{]/.test(x)==t)u.push(x);else if(u.length){if(u.pop()!=matching[x])s=false}else s=false;if(!u.length)break}else if(v.dirty||!isSpan(v)&&!isBR(v))return{node:v,status:"dirty"};return{node:v,status:v&&s}}var h=this,j=this.options.markParen;if(typeof j=="string")j=[j,j];if(!d&&h.highlighted){b(h.highlighted[0]);b(h.highlighted[1])}if(!(!window||!window.parent||!window.select)){this.parenEvent&&parent.clearTimeout(this.parenEvent);this.parenEvent=null;var i,n=select.selectionTopNode(this.container,
true);if(n&&this.highlightAtCursor())if((n=select.selectionTopNode(this.container,true))&&((i=c(n))||(n=n.nextSibling)&&(i=c(n))))for(var r=n.className,t=/[\(\[\{]/.test(i);;){var o=e();if(o.status=="dirty"){this.highlight(o.node,m(o.node));o.node.dirty=false}else{g(n,o.status);g(o.node,o.status);if(d)parent.setTimeout(function(){b(n);b(o.node)},500);else h.highlighted=[n,o.node];a&&o.node&&select.focusAfterNode(o.node.previousSibling,this.container);break}}}},indentAtCursor:function(a){if(this.container.firstChild)if(this.highlightAtCursor()){var d=
select.selectionTopNode(this.container,false);if(d!==false){select.markSelection();this.indentLineAfter(k(d),a);select.selectMarked()}}},indentRegion:function(a,d,g,b){var c=a=k(a),e=a&&k(a.previousSibling);isBR(d)||(d=m(d,this.container));this.addDirtyNode(a);do{var h=m(c,this.container);c&&this.highlight(e,h,true);this.indentLineAfter(c,g);e=c;c=h}while(c!=d);b&&select.setCursorPos(this.container,{node:a,offset:0},{node:d,offset:0})},cursorActivity:function(a){if(this.unloaded){window.document.designMode=
"off";window.document.designMode="on";this.unloaded=false}if(internetExplorer){this.container.createTextRange().execCommand("unlink");clearTimeout(this.saveSelectionSnapshot);var d=this;this.saveSelectionSnapshot=setTimeout(function(){var c=select.getBookmark(d.container);if(c)d.selectionSnapshot=c},200)}var g=this.options.onCursorActivity;if(!a||g){var b=select.selectionTopNode(this.container,false);if(!(b===false||!this.container.firstChild)){b=b||this.container.firstChild;g&&g(b);if(!a){this.scheduleHighlight();
this.addDirtyNode(b)}}}},reparseBuffer:function(){forEach(this.container.childNodes,function(a){a.dirty=true});this.container.firstChild&&this.addDirtyNode(this.container.firstChild)},addDirtyNode:function(a){if(a=a||this.container.firstChild){for(var d=0;d<this.dirty.length;d++)if(this.dirty[d]==a)return;if(a.nodeType!=3)a.dirty=true;this.dirty.push(a)}},allClean:function(){return!this.dirty.length},scheduleHighlight:function(){var a=this;parent.clearTimeout(this.highlightTimeout);this.highlightTimeout=
parent.setTimeout(function(){a.highlightDirty()},this.options.passDelay)},getDirtyNode:function(){for(;this.dirty.length>0;){var a=this.dirty.pop();try{for(;a&&a.parentNode!=this.container;)a=a.parentNode;if(a&&(a.dirty||a.nodeType==3))return a}catch(d){}}return null},highlightDirty:function(a){if(!window||!window.parent||!window.select)return false;this.options.readOnly||select.markSelection();for(var d,g=a?null:(new Date).getTime()+this.options.passTime;((new Date).getTime()<g||a)&&(d=this.getDirtyNode());){var b=
this.highlight(d,g);b&&b.node&&b.dirty&&this.addDirtyNode(b.node.nextSibling)}this.options.readOnly||select.selectMarked();d&&this.scheduleHighlight();return this.dirty.length==0},documentScanner:function(a){var d=this,g=null;return function(){if(!(!window||!window.parent||!window.select)){if(g&&g.parentNode!=d.container)g=null;select.markSelection();var b=d.highlight(g,(new Date).getTime()+a,true);select.selectMarked();b=b?b.node&&b.node.nextSibling:null;g=g==b?null:b;d.delayScanning()}}},delayScanning:function(){if(this.scanner){parent.clearTimeout(this.documentScan);
this.documentScan=parent.setTimeout(this.scanner,this.options.continuousScanning)}},highlight:function(a,d,g,b){function c(s){if(s){var v=s.oldNextSibling;if(o||v===undefined||s.nextSibling!=v)h.history.touch(s);s.oldNextSibling=s.nextSibling}else{v=h.container.oldFirstChild;if(o||v===undefined||h.container.firstChild!=v)h.history.touch(null);h.container.oldFirstChild=h.container.firstChild}}var e=this.container,h=this,j=this.options.activeTokens,i=typeof d=="number"?d:null;if(!e.firstChild)return false;
for(;a&&(!a.parserFromHere||a.dirty);){if(b!=null&&isBR(a)&&--b<0)return false;a=a.previousSibling}if(a&&!a.nextSibling)return false;var n=l(a?a.nextSibling:e.firstChild);b=stringStream(n);var r=a?a.parserFromHere(b):p.Parser.make(b),t={current:null,get:function(){if(!this.current)this.current=n.nodes.shift();return this.current},next:function(){this.current=null},remove:function(){e.removeChild(this.get());this.current=null},getNonEmpty:function(){for(var s=this.get();s&&isSpan(s)&&s.currentText==
"";)if(window.opera&&(s.previousSibling==null||isBR(s.previousSibling))&&(s.nextSibling==null||isBR(s.nextSibling))){this.next();s=this.get()}else{var v=s;this.remove();s=this.get();select.snapshotMove(v.firstChild,s&&(s.firstChild||s),0)}return s}},o=false,u=true,x=0;forEach(r,function(s){var v=t.getNonEmpty();if(s.value=="\n"){if(!isBR(v))throw"Parser out of sync. Expected BR.";if(v.dirty||!v.indentation)o=true;c(a);a=v;v.parserFromHere=r.copy();v.indentation=s.indentation||alwaysZero;v.dirty=false;
if(i==null&&v==d)throw StopIteration;if(i!=null&&(new Date).getTime()>=i||!o&&!u&&x>1&&!g)throw StopIteration;u=o;o=false;x=0;t.next()}else{if(!isSpan(v))throw"Parser out of sync. Expected SPAN.";if(v.dirty)o=true;x++;if(!v.reduced&&v.currentText==s.value&&v.className==s.style){j&&v.dirty&&j(v,s,h);v.dirty=false;t.next()}else{o=true;var y=makePartSpan(s.value);y.className=s.style;e.insertBefore(y,v);j&&j(y,s,h);s=s.value.length;for(var A=0;s>0;){v=t.get();var z=v.currentText.length;select.snapshotReplaceNode(v.firstChild,
y.firstChild,s,A);if(z>s){v.currentText=v.currentText.substring(s);v.reduced=true;s=0}else{s-=z;A+=z;t.remove()}}}}});c(a);webkitLastLineHack(this.container);return{node:t.getNonEmpty(),dirty:o}}};return p}();addEventHandler(window,"load",function(){var f=window.frameElement.CodeMirror;f.editor=new Editor(f.options);parent.setTimeout(method(f,"init"),0)});var select={};
(function(){function f(b,c){for(;b&&b.parentNode!=c;)b=b.parentNode;return b}function l(b,c){for(;!b.previousSibling&&b.parentNode!=c;)b=b.parentNode;return f(b.previousSibling,c)}function k(b){var c=b.nextSibling;if(c){for(;c.firstChild;)c=c.firstChild;return c.nodeType==3||isBR(c)?c:k(c)}else{for(b=b.parentNode;b&&!b.nextSibling;)b=b.parentNode;return b&&k(b)}}select.ie_selection=document.selection&&document.selection.createRangeCollection;select.scrollToNode=function(b,c){if(b){for(var e=b,h=document.body,
j=document.documentElement,i=!e.nextSibling||!e.nextSibling.nextSibling||!e.nextSibling.nextSibling.nextSibling,n=0;e&&!e.offsetTop;){n++;e=e.previousSibling}if(n==0)i=false;if(!(webkit&&e&&e.offsetTop==5&&e.offsetLeft==5)){n*=e?e.offsetHeight:0;for(var r=0,t=b?b.offsetWidth:0;e&&e.offsetParent;){n+=e.offsetTop;isBR(e)||(r+=e.offsetLeft);e=e.offsetParent}e=h.scrollLeft||j.scrollLeft||0;h=h.scrollTop||j.scrollTop||0;var o=false,u=window.innerWidth||j.clientWidth||0;if(c||t<u){if(c){var x=select.offsetInNode(b),
s=nodeText(b).length;if(s)r+=t*(x/s)}t=r-e;if(t<0||t>u){e=r;o=true}}r=n-h;if(r<0||i||r>(window.innerHeight||j.clientHeight||0)-50){h=i?1E6:n;o=true}o&&window.scrollTo(e,h)}}};select.scrollToCursor=function(b){select.scrollToNode(select.selectionTopNode(b,true)||b.firstChild,true)};var m=null;select.snapshotChanged=function(){if(m)m.changed=true};select.snapshotReplaceNode=function(b,c,e,h){function j(i){if(b==i.node){m.changed=true;if(e&&i.offset>e)i.offset-=e;else{i.node=c;i.offset+=h||0}}else if(select.ie_selection&&
i.offset==0&&i.node==k(b))m.changed=true}if(m){j(m.start);j(m.end)}};select.snapshotMove=function(b,c,e,h,j){function i(n){if(b==n.node&&(!j||n.offset==0)){m.changed=true;n.node=c;n.offset=h?Math.max(0,n.offset+e):e}}if(m){i(m.start);i(m.end)}};if(select.ie_selection){var q=function(){var b=document.selection;if(!b)return null;return b.createRange?b.createRange():b.createTextRange()},p=function(b){function c(t){for(var o=null;!o&&t;){o=t.nextSibling;t=t.parentNode}return e(o)}function e(t){for(;t&&
t.firstChild;)t=t.firstChild;return{node:t,offset:0}}var h=q();h.collapse(b);b=h.parentElement();if(!isAncestor(document.body,b))return null;if(!b.firstChild)return e(b);var j=h.duplicate();j.moveToElementText(b);j.collapse(true);for(var i=b.firstChild;i;i=i.nextSibling){if(i.nodeType==3){var n=i.nodeValue.length;j.move("character",n)}else{j.moveToElementText(i);j.collapse(false)}var r=h.compareEndPoints("StartToStart",j);if(r==0)return c(i);if(r!=1){if(i.nodeType!=3)return e(i);j.setEndPoint("StartToEnd",
h);return{node:i,offset:n-j.text.length}}}return c(b)};select.markSelection=function(){m=null;if(document.selection){var b=p(true),c=p(false);if(b&&c)m={start:b,end:c,changed:false}}};select.selectMarked=function(){function b(h){var j=document.body.createTextRange(),i=h.node;if(i)if(i.nodeType==3){j.moveToElementText(i.parentNode);for(h=h.offset;i.previousSibling;){i=i.previousSibling;h+=(i.innerText||"").length}j.move("character",h)}else{j.moveToElementText(i);j.collapse(true)}else{j.moveToElementText(document.body);
j.collapse(false)}return j}if(m&&m.changed){var c=b(m.start),e=b(m.end);c.setEndPoint("StartToEnd",e);c.select()}};select.offsetInNode=function(b){var c=q();if(!c)return 0;var e=c.duplicate();try{e.moveToElementText(b)}catch(h){return 0}c.setEndPoint("StartToStart",e);return c.text.length};select.selectionTopNode=function(b,c){function e(o,u){if(u.nodeType==3){for(var x=0,s=u.previousSibling;s&&s.nodeType==3;){x+=s.nodeValue.length;s=s.previousSibling}if(s){try{o.moveToElementText(s)}catch(v){return false}o.collapse(false)}else o.moveToElementText(u.parentNode);
x&&o.move("character",x)}else try{o.moveToElementText(u)}catch(y){return false}return true}var h=q();if(!h)return false;var j=h.duplicate();h.collapse(c);var i=h.parentElement();if(i&&isAncestor(b,i)){j.moveToElementText(i);if(h.compareEndPoints("StartToStart",j)==1)return f(i,b)}c=0;for(i=b.childNodes.length-1;c<i;){var n=Math.ceil((i+c)/2),r=b.childNodes[n];if(!r)return false;if(!e(j,r))return false;if(h.compareEndPoints("StartToStart",j)==1)c=n;else i=n-1}if(c==0){h=q();j=h.duplicate();try{j.moveToElementText(b)}catch(t){return null}if(h.compareEndPoints("StartToStart",
j)==0)return null}return b.childNodes[c]||null};select.focusAfterNode=function(b,c){var e=document.body.createTextRange();e.moveToElementText(b||c);e.collapse(!b);e.select()};select.somethingSelected=function(){var b=q();return b&&b.text!=""};var w=function(b){var c=q();if(c){c.pasteHTML(b);c.collapse(false);c.select()}};select.insertNewlineAtCursor=function(){w("<br>")};select.insertTabAtCursor=function(){w("\u00a0\u00a0\u00a0\u00a0")};select.cursorPos=function(b,c){var e=q();if(!e)return null;for(var h=
select.selectionTopNode(b,c);h&&!isBR(h);)h=h.previousSibling;var j=e.duplicate();e.collapse(c);if(h){j.moveToElementText(h);j.collapse(false)}else{try{j.moveToElementText(b)}catch(i){return null}j.collapse(true)}e.setEndPoint("StartToStart",j);return{node:h,offset:e.text.length}};select.setCursorPos=function(b,c,e){function h(i){var n=document.body.createTextRange();if(i.node){n.moveToElementText(i.node);n.collapse(false)}else{n.moveToElementText(b);n.collapse(true)}n.move("character",i.offset);
return n}var j=h(c);e&&e!=c&&j.setEndPoint("EndToEnd",h(e));j.select()};select.getBookmark=function(b){var c=select.cursorPos(b,true);b=select.cursorPos(b,false);if(c&&b)return{from:c,to:b}};select.setBookmark=function(b,c){c&&select.setCursorPos(b,c.from,c.to)}}else{var a=function(b,c){for(;b.nodeType!=3&&!isBR(b);){var e=b.childNodes[c]||b.nextSibling;for(c=0;!e&&b.parentNode;){b=b.parentNode;e=b.nextSibling}b=e;if(!e)break}return{node:b,offset:c}};select.markSelection=function(){var b=window.getSelection();
if(!b||b.rangeCount==0)return m=null;b=b.getRangeAt(0);m={start:a(b.startContainer,b.startOffset),end:a(b.endContainer,b.endOffset),changed:false}};select.selectMarked=function(){function b(){if(e.start.node==e.end.node&&e.start.offset==e.end.offset){var j=window.getSelection();if(!j||j.rangeCount==0)return true;j=j.getRangeAt(0);j=a(j.startContainer,j.startOffset);return e.start.node!=j.node||e.start.offset!=j.offset}}function c(j,i){if(j.node)if(j.offset==0)h["set"+i+"Before"](j.node);else h["set"+
i](j.node,j.offset);else h.setStartAfter(document.body.lastChild||document.body)}var e=m;if(e&&(e.changed||webkit&&b())){var h=document.createRange();c(e.end,"End");c(e.start,"Start");d(h)}};var d=function(b){var c=window.getSelection();if(c){c.removeAllRanges();c.addRange(b)}},g=function(){var b=window.getSelection();return!b||b.rangeCount==0?false:b.getRangeAt(0)};select.selectionTopNode=function(b,c){var e=g();if(!e)return false;var h=c?e.startContainer:e.endContainer,j=c?e.startOffset:e.endOffset;
window.opera&&!c&&e.endContainer==b&&e.endOffset==e.startOffset+1&&b.childNodes[e.startOffset]&&isBR(b.childNodes[e.startOffset])&&j--;return h.nodeType==3?j>0?f(h,b):l(h,b):h.nodeName.toUpperCase()=="HTML"?j==1?null:b.lastChild:h==b?j==0?null:h.childNodes[j-1]:j==h.childNodes.length?f(h,b):j==0?l(h,b):f(h.childNodes[j-1],b)};select.focusAfterNode=function(b,c){var e=document.createRange();e.setStartBefore(c.firstChild||c);if(b&&!b.firstChild)e.setEndAfter(b);else b?e.setEnd(b,b.childNodes.length):
e.setEndBefore(c.firstChild||c);e.collapse(false);d(e)};select.somethingSelected=function(){var b=g();return b&&!b.collapsed};select.offsetInNode=function(b){var c=g();if(!c)return 0;c=c.cloneRange();c.setStartBefore(b);return c.toString().length};select.insertNodeAtCursor=function(b){var c=g();if(c){c.deleteContents();c.insertNode(b);webkitLastLineHack(document.body);if(window.opera&&isBR(b)&&isSpan(b.parentNode)){c=b.nextSibling;var e=b.parentNode,h=e.parentNode;h.insertBefore(b,e.nextSibling);
for(e="";c&&c.nodeType==3;c=c.nextSibling){e+=c.nodeValue;removeElement(c)}h.insertBefore(makePartSpan(e,document),b.nextSibling)}c=document.createRange();c.selectNode(b);c.collapse(false);d(c)}};select.insertNewlineAtCursor=function(){select.insertNodeAtCursor(document.createElement("BR"))};select.insertTabAtCursor=function(){select.insertNodeAtCursor(document.createTextNode("\u00a0\u00a0\u00a0\u00a0"))};select.cursorPos=function(b,c){var e=g();if(e){for(var h=select.selectionTopNode(b,c);h&&!isBR(h);)h=
h.previousSibling;e=e.cloneRange();e.collapse(c);h?e.setStartAfter(h):e.setStartBefore(b);return{node:h,offset:e.toString().length}}};select.setCursorPos=function(b,c,e){function h(i,n,r){function t(s){s.nodeType==3?o.push(s):forEach(s.childNodes,t)}if(n==0&&i&&!i.nextSibling){j["set"+r+"After"](i);return true}if(i=i?i.nextSibling:b.firstChild){if(n==0){j["set"+r+"Before"](i);return true}for(var o=[];;){for(;i&&!o.length;){t(i);i=i.nextSibling}var u=o.shift();if(!u)return false;var x=u.nodeValue.length;
if(x>=n){j["set"+r](u,n);return true}n-=x}}}var j=document.createRange();e=e||c;h(e.node,e.offset,"End")&&h(c.node,c.offset,"Start")&&d(j)}}})();
var stringStream=function(f){function l(){for(;m==k.length;){q+=k;k="";m=0;try{k=f.next()}catch(p){if(p!=StopIteration)throw p;else return false}}return true}var k="",m=0,q="";return{peek:function(){if(!l())return null;return k.charAt(m)},next:function(){if(!l())if(q.length>0)throw"End of stringstream reached without emptying buffer ('"+q+"').";else throw StopIteration;return k.charAt(m++)},get:function(){var p=q;q="";if(m>0){p+=k.slice(0,m);k=k.slice(m);m=0}return p},push:function(p){k=k.slice(0,
m)+p+k.slice(m)},lookAhead:function(p,w,a,d){function g(i){return d?i.toLowerCase():i}p=g(p);var b=false,c=q,e=m;for(a&&this.nextWhileMatches(/[\s\u00a0]/);;){a=m+p.length;var h=k.length-m;if(a<=k.length){b=p==g(k.slice(m,a));m=a;break}else if(p.slice(0,h)==g(k.slice(m))){q+=k;k="";try{k=f.next()}catch(j){if(j!=StopIteration)throw j;break}m=0;p=p.slice(h)}else break}if(!(b&&w)){k=q.slice(c.length)+k;m=e;q=c}return b},lookAheadRegex:function(p,w){if(p.source.charAt(0)!="^")throw Error("Regexps passed to lookAheadRegex must start with ^");
for(;k.indexOf("\n",m)==-1;)try{k+=f.next()}catch(a){if(a!=StopIteration)throw a;break}var d=k.slice(m).match(p);if(d&&w)m+=d[0].length;return d},more:function(){return this.peek()!==null},applies:function(p){var w=this.peek();return w!==null&&p(w)},nextWhile:function(p){for(var w;(w=this.peek())!==null&&p(w);)this.next()},matches:function(p){var w=this.peek();return w!==null&&p.test(w)},nextWhileMatches:function(p){for(var w;(w=this.peek())!==null&&p.test(w);)this.next()},equals:function(p){return p===
this.peek()},endOfLine:function(){var p=this.peek();return p==null||p=="\n"}}};
function tokenizer(f,l){function k(q){return q!="\n"&&/^[\s\u00a0]*$/.test(q)}var m={state:l,take:function(q){if(typeof q=="string")q={style:q,type:q};q.content=(q.content||"")+f.get();/\n$/.test(q.content)||f.nextWhile(k);q.value=q.content+f.get();return q},next:function(){if(!f.more())throw StopIteration;var q;if(f.equals("\n")){f.next();return this.take("whitespace")}if(f.applies(k))q="whitespace";else for(;!q;)q=this.state(f,function(p){m.state=p});return this.take(q)}};return m}
function UndoHistory(f,l,k,m){this.container=f;this.maxDepth=l;this.commitDelay=k;this.editor=m;this.last=this.first=f={text:"",from:null,to:null};this.firstTouched=false;this.history=[];this.redoHistory=[];this.touched=[];this.lostundo=0}
UndoHistory.prototype={scheduleCommit:function(){var f=this;parent.clearTimeout(this.commitTimeout);this.commitTimeout=parent.setTimeout(function(){f.tryCommit()},this.commitDelay)},touch:function(f){this.setTouched(f);this.scheduleCommit()},undo:function(){this.commit();if(this.history.length){var f=this.history.pop();this.redoHistory.push(this.updateTo(f,"applyChain"));this.notifyEnvironment();return this.chainNode(f)}},redo:function(){this.commit();if(this.redoHistory.length){var f=this.redoHistory.pop();
this.addUndoLevel(this.updateTo(f,"applyChain"));this.notifyEnvironment();return this.chainNode(f)}},clear:function(){this.history=[];this.redoHistory=[];this.lostundo=0},historySize:function(){return{undo:this.history.length,redo:this.redoHistory.length,lostundo:this.lostundo}},push:function(f,l,k){for(var m=[],q=0;q<k.length;q++){var p=q==k.length-1?l:document.createElement("br");m.push({from:f,to:p,text:cleanText(k[q])});f=p}this.pushChains([m],f==null&&l==null);this.notifyEnvironment()},pushChains:function(f,
l){this.commit(l);this.addUndoLevel(this.updateTo(f,"applyChain"));this.redoHistory=[]},chainNode:function(f){for(var l=0;l<f.length;l++){var k=f[l][0];if(k=k&&(k.from||k.to))return k}},reset:function(){this.history=[];this.redoHistory=[];this.lostundo=0},textAfter:function(f){return this.after(f).text},nodeAfter:function(f){return this.after(f).to},nodeBefore:function(f){return this.before(f).from},tryCommit:function(){!window||!window.parent||!window.UndoHistory||(this.editor.highlightDirty()?this.commit(true):
this.scheduleCommit())},commit:function(f){parent.clearTimeout(this.commitTimeout);f||this.editor.highlightDirty(true);f=this.touchedChains();if(f.length){this.addUndoLevel(this.updateTo(f,"linkChain"));this.redoHistory=[];this.notifyEnvironment()}},updateTo:function(f,l){for(var k=[],m=[],q=0;q<f.length;q++){k.push(this.shadowChain(f[q]));m.push(this[l](f[q]))}l=="applyChain"&&this.notifyDirty(m);return k},notifyDirty:function(f){forEach(f,method(this.editor,"addDirtyNode"));this.editor.scheduleHighlight()},
notifyEnvironment:function(){if(this.onChange)this.onChange(this.editor);window.frameElement&&window.frameElement.CodeMirror.updateNumbers&&window.frameElement.CodeMirror.updateNumbers()},linkChain:function(f){for(var l=0;l<f.length;l++){var k=f[l];if(k.from)k.from.historyAfter=k;else this.first=k;if(k.to)k.to.historyBefore=k;else this.last=k}},after:function(f){return f?f.historyAfter:this.first},before:function(f){return f?f.historyBefore:this.last},setTouched:function(f){if(f){if(!f.historyTouched){this.touched.push(f);
f.historyTouched=true}}else this.firstTouched=true},addUndoLevel:function(f){this.history.push(f);if(this.history.length>this.maxDepth){this.history.shift();this.lostundo+=1}},touchedChains:function(){function f(a,d){if(a)a.historyTemp=d;else q=d}function l(a){for(var d=[],g=a?a.nextSibling:m.container.firstChild;g&&(!isBR(g)||g.hackBR);g=g.nextSibling)!g.hackBR&&g.currentText&&d.push(g.currentText);return{from:a,to:g,text:cleanText(d.join(""))}}function k(a,d){for(var g=d+"Sibling",b=a[g];b&&!isBR(b);)b=
b[g];return b}var m=this,q=null,p=[];m.firstTouched&&m.touched.push(null);forEach(m.touched,function(a){if(!(a&&(a.parentNode!=m.container||a.hackBR))){if(a)a.historyTouched=false;else m.firstTouched=false;var d=l(a),g=m.after(a);if(!g||g.text!=d.text||g.to!=d.to){p.push(d);f(a,d)}}});var w=[];m.touched=[];forEach(p,function(a){if(a.from?a.from.historyTemp:q){for(var d=[],g=a.from,b=true;;){var c=g?g.historyTemp:q;if(!c)if(b)break;else c=l(g);d.unshift(c);f(g,null);if(!g)break;b=m.after(g);g=k(g,
"previous")}g=a.to;for(b=m.before(a.from);;){if(!g)break;c=g?g.historyTemp:q;if(!c)if(b)break;else c=l(g);d.push(c);f(g,null);b=m.before(g);g=k(g,"next")}w.push(d)}});return w},shadowChain:function(f){var l=[],k=this.after(f[0].from);for(f=f[f.length-1].to;;){l.push(k);k=k.to;if(!k||k==f)break;else k=k.historyAfter||this.before(f)}return l},applyChain:function(f){var l=select.cursorPos(this.container,false),k=this,m=f[0].from,q=f[f.length-1].to;(function(b,c){for(var e=b?b.nextSibling:k.container.firstChild;e!=
c;){var h=e.nextSibling;removeElement(e);e=h}})(m,q);for(var p=0;p<f.length;p++){var w=f[p];p>0&&k.container.insertBefore(w.from,q);var a=makePartSpan(fixSpaces(w.text));k.container.insertBefore(a,q);if(l&&l.node==w.from){a=0;var d=this.after(w.from);if(d&&p==f.length-1){for(var g=0;g<l.offset&&w.text.charAt(g)==d.text.charAt(g);g++);if(l.offset>g)a=w.text.length-d.text.length}select.setCursorPos(this.container,{node:w.from,offset:Math.max(0,l.offset+a)})}else l&&p==f.length-1&&l.node&&l.node.parentNode!=
this.container&&select.setCursorPos(this.container,{node:w.from,offset:w.text.length})}this.linkChain(f);return m}};function method(f,l){return function(){f[l].apply(f,arguments)}}var StopIteration={toString:function(){return"StopIteration"}};function forEach(f,l){if(f.next)try{for(;;)l(f.next())}catch(k){if(k!=StopIteration)throw k;}else for(var m=0;m<f.length;m++)l(f[m])}function map(f,l){var k=[];forEach(f,function(m){k.push(l(m))});return k}
function matcher(f){return function(l){return f.test(l)}}function hasClass(f,l){var k=f.className;return k&&RegExp("(^| )"+l+"($| )").test(k)}function removeClass(f,l){f.className=f.className.replace(RegExp(" "+l+"\\b","g"),"");return f}function insertAfter(f,l){l.parentNode.insertBefore(f,l.nextSibling);return f}function removeElement(f){f.parentNode&&f.parentNode.removeChild(f)}function clearElement(f){for(;f.firstChild;)f.removeChild(f.firstChild)}
function isAncestor(f,l){for(;l=l.parentNode;)if(f==l)return true;return false}var nbsp="\u00a0",matching={"{":"}","[":"]","(":")","}":"{","]":"[",")":"("};
function normalizeEvent(f){if(!f.stopPropagation){f.stopPropagation=function(){this.cancelBubble=true};f.preventDefault=function(){this.returnValue=false}}if(!f.stop)f.stop=function(){this.stopPropagation();this.preventDefault()};if(f.type=="keypress"){f.code=f.charCode==null?f.keyCode:f.charCode;f.character=String.fromCharCode(f.code)}return f}
function addEventHandler(f,l,k,m){function q(p){k(normalizeEvent(p||window.event))}if(typeof f.addEventListener=="function"){f.addEventListener(l,q,false);if(m)return function(){f.removeEventListener(l,q,false)}}else{f.attachEvent("on"+l,q);if(m)return function(){f.detachEvent("on"+l,q)}}}function nodeText(f){return f.textContent||f.innerText||f.nodeValue||""}function nodeTop(f){for(var l=0;f.offsetParent;){l+=f.offsetTop;f=f.offsetParent}return l}
function isBR(f){f=f.nodeName;return f=="BR"||f=="br"}function isSpan(f){f=f.nodeName;return f=="SPAN"||f=="span"};

View File

@ -0,0 +1,590 @@
/* CodeMirror main module (http://codemirror.net/)
*
* Implements the CodeMirror constructor and prototype, which take care
* of initializing the editor frame, and providing the outside interface.
*/
// The CodeMirrorConfig object is used to specify a default
// configuration. If you specify such an object before loading this
// file, the values you put into it will override the defaults given
// below. You can also assign to it after loading.
var CodeMirrorConfig = window.CodeMirrorConfig || {};
var CodeMirror = (function(){
function setDefaults(object, defaults) {
for (var option in defaults) {
if (!object.hasOwnProperty(option))
object[option] = defaults[option];
}
}
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
function createHTMLElement(el) {
if (document.createElementNS && document.documentElement.namespaceURI !== null)
return document.createElementNS("http://www.w3.org/1999/xhtml", el)
else
return document.createElement(el)
}
// These default options can be overridden by passing a set of
// options to a specific CodeMirror constructor. See manual.html for
// their meaning.
setDefaults(CodeMirrorConfig, {
stylesheet: [],
path: "",
parserfile: [],
basefiles: ["util.js", "stringstream.js", "select.js", "undo.js", "editor.js", "tokenize.js"],
iframeClass: null,
passDelay: 200,
passTime: 50,
lineNumberDelay: 200,
lineNumberTime: 50,
continuousScanning: false,
saveFunction: null,
onLoad: null,
onChange: null,
undoDepth: 50,
undoDelay: 800,
disableSpellcheck: true,
textWrapping: true,
readOnly: false,
width: "",
height: "300px",
minHeight: 100,
onDynamicHeightChange: null,
autoMatchParens: false,
markParen: null,
unmarkParen: null,
parserConfig: null,
tabMode: "indent", // or "spaces", "default", "shift"
enterMode: "indent", // or "keep", "flat"
electricChars: true,
reindentOnLoad: false,
activeTokens: null,
onCursorActivity: null,
lineNumbers: false,
firstLineNumber: 1,
onLineNumberClick: null,
indentUnit: 2,
domain: null,
noScriptCaching: false,
incrementalLoading: false
});
function addLineNumberDiv(container, firstNum) {
var nums = createHTMLElement("div"),
scroller = createHTMLElement("div");
nums.style.position = "absolute";
nums.style.height = "100%";
if (nums.style.setExpression) {
try {nums.style.setExpression("height", "this.previousSibling.offsetHeight + 'px'");}
catch(e) {} // Seems to throw 'Not Implemented' on some IE8 versions
}
nums.style.top = "0px";
nums.style.left = "0px";
nums.style.overflow = "hidden";
container.appendChild(nums);
scroller.className = "CodeMirror-line-numbers";
nums.appendChild(scroller);
scroller.innerHTML = "<div>" + firstNum + "</div>";
return nums;
}
function frameHTML(options) {
if (typeof options.parserfile == "string")
options.parserfile = [options.parserfile];
if (typeof options.basefiles == "string")
options.basefiles = [options.basefiles];
if (typeof options.stylesheet == "string")
options.stylesheet = [options.stylesheet];
var sp = " spellcheck=\"" + (options.disableSpellcheck ? "false" : "true") + "\"";
var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html" + sp + "><head>"];
// Hack to work around a bunch of IE8-specific problems.
html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>");
var queryStr = options.noScriptCaching ? "?nocache=" + new Date().getTime().toString(16) : "";
forEach(options.stylesheet, function(file) {
html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + queryStr + "\"/>");
});
forEach(options.basefiles.concat(options.parserfile), function(file) {
if (!/^https?:/.test(file)) file = options.path + file;
html.push("<script type=\"text/javascript\" src=\"" + file + queryStr + "\"><" + "/script>");
});
html.push("</head><body style=\"border-width: 0;\" class=\"editbox\"" + sp + "></body></html>");
return html.join("");
}
var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
function CodeMirror(place, options) {
// Use passed options, if any, to override defaults.
this.options = options = options || {};
setDefaults(options, CodeMirrorConfig);
// Backward compatibility for deprecated options.
if (options.dumbTabs) options.tabMode = "spaces";
else if (options.normalTab) options.tabMode = "default";
if (options.cursorActivity) options.onCursorActivity = options.cursorActivity;
var frame = this.frame = createHTMLElement("iframe");
if (options.iframeClass) frame.className = options.iframeClass;
frame.frameBorder = 0;
frame.style.border = "0";
frame.style.width = '100%';
frame.style.height = '100%';
// display: block occasionally suppresses some Firefox bugs, so we
// always add it, redundant as it sounds.
frame.style.display = "block";
var div = this.wrapping = createHTMLElement("div");
div.style.position = "relative";
div.className = "CodeMirror-wrapping";
div.style.width = options.width;
div.style.height = (options.height == "dynamic") ? options.minHeight + "px" : options.height;
// This is used by Editor.reroutePasteEvent
var teHack = this.textareaHack = createHTMLElement("textarea");
div.appendChild(teHack);
teHack.style.position = "absolute";
teHack.style.left = "-10000px";
teHack.style.width = "10px";
teHack.tabIndex = 100000;
// Link back to this object, so that the editor can fetch options
// and add a reference to itself.
frame.CodeMirror = this;
if (options.domain && internetExplorer) {
this.html = frameHTML(options);
frame.src = "javascript:(function(){document.open();" +
(options.domain ? "document.domain=\"" + options.domain + "\";" : "") +
"document.write(window.frameElement.CodeMirror.html);document.close();})()";
}
else {
frame.src = "javascript:;";
}
if (place.appendChild) place.appendChild(div);
else place(div);
div.appendChild(frame);
if (options.lineNumbers) this.lineNumbers = addLineNumberDiv(div, options.firstLineNumber);
this.win = frame.contentWindow;
if (!options.domain || !internetExplorer) {
this.win.document.open();
this.win.document.write(frameHTML(options));
this.win.document.close();
}
}
CodeMirror.prototype = {
init: function() {
// Deprecated, but still supported.
if (this.options.initCallback) this.options.initCallback(this);
if (this.options.onLoad) this.options.onLoad(this);
if (this.options.lineNumbers) this.activateLineNumbers();
if (this.options.reindentOnLoad) this.reindent();
if (this.options.height == "dynamic") this.setDynamicHeight();
},
getCode: function() {return this.editor.getCode();},
setCode: function(code) {this.editor.importCode(code);},
selection: function() {this.focusIfIE(); return this.editor.selectedText();},
reindent: function() {this.editor.reindent();},
reindentSelection: function() {this.focusIfIE(); this.editor.reindentSelection(null);},
focusIfIE: function() {
// in IE, a lot of selection-related functionality only works when the frame is focused
if (this.win.select.ie_selection && document.activeElement != this.frame)
this.focus();
},
focus: function() {
this.win.focus();
if (this.editor.selectionSnapshot) // IE hack
this.win.select.setBookmark(this.win.document.body, this.editor.selectionSnapshot);
},
replaceSelection: function(text) {
this.focus();
this.editor.replaceSelection(text);
return true;
},
replaceChars: function(text, start, end) {
this.editor.replaceChars(text, start, end);
},
getSearchCursor: function(string, fromCursor, caseFold) {
return this.editor.getSearchCursor(string, fromCursor, caseFold);
},
undo: function() {this.editor.history.undo();},
redo: function() {this.editor.history.redo();},
historySize: function() {return this.editor.history.historySize();},
clearHistory: function() {this.editor.history.clear();},
grabKeys: function(callback, filter) {this.editor.grabKeys(callback, filter);},
ungrabKeys: function() {this.editor.ungrabKeys();},
setParser: function(name, parserConfig) {this.editor.setParser(name, parserConfig);},
setSpellcheck: function(on) {this.win.document.body.spellcheck = on;},
setStylesheet: function(names) {
if (typeof names === "string") names = [names];
var activeStylesheets = {};
var matchedNames = {};
var links = this.win.document.getElementsByTagName("link");
// Create hashes of active stylesheets and matched names.
// This is O(n^2) but n is expected to be very small.
for (var x = 0, link; link = links[x]; x++) {
if (link.rel.indexOf("stylesheet") !== -1) {
for (var y = 0; y < names.length; y++) {
var name = names[y];
if (link.href.substring(link.href.length - name.length) === name) {
activeStylesheets[link.href] = true;
matchedNames[name] = true;
}
}
}
}
// Activate the selected stylesheets and disable the rest.
for (var x = 0, link; link = links[x]; x++) {
if (link.rel.indexOf("stylesheet") !== -1) {
link.disabled = !(link.href in activeStylesheets);
}
}
// Create any new stylesheets.
for (var y = 0; y < names.length; y++) {
var name = names[y];
if (!(name in matchedNames)) {
var link = this.win.document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = name;
this.win.document.getElementsByTagName('head')[0].appendChild(link);
}
}
},
setTextWrapping: function(on) {
if (on == this.options.textWrapping) return;
this.win.document.body.style.whiteSpace = on ? "" : "nowrap";
this.options.textWrapping = on;
if (this.lineNumbers) {
this.setLineNumbers(false);
this.setLineNumbers(true);
}
},
setIndentUnit: function(unit) {this.win.indentUnit = unit;},
setUndoDepth: function(depth) {this.editor.history.maxDepth = depth;},
setTabMode: function(mode) {this.options.tabMode = mode;},
setEnterMode: function(mode) {this.options.enterMode = mode;},
setLineNumbers: function(on) {
if (on && !this.lineNumbers) {
this.lineNumbers = addLineNumberDiv(this.wrapping,this.options.firstLineNumber);
this.activateLineNumbers();
}
else if (!on && this.lineNumbers) {
this.wrapping.removeChild(this.lineNumbers);
this.wrapping.style.paddingLeft = "";
this.lineNumbers = null;
}
},
cursorPosition: function(start) {this.focusIfIE(); return this.editor.cursorPosition(start);},
firstLine: function() {return this.editor.firstLine();},
lastLine: function() {return this.editor.lastLine();},
nextLine: function(line) {return this.editor.nextLine(line);},
prevLine: function(line) {return this.editor.prevLine(line);},
lineContent: function(line) {return this.editor.lineContent(line);},
setLineContent: function(line, content) {this.editor.setLineContent(line, content);},
removeLine: function(line){this.editor.removeLine(line);},
insertIntoLine: function(line, position, content) {this.editor.insertIntoLine(line, position, content);},
selectLines: function(startLine, startOffset, endLine, endOffset) {
this.win.focus();
this.editor.selectLines(startLine, startOffset, endLine, endOffset);
},
nthLine: function(n) {
var line = this.firstLine();
for (; n > 1 && line !== false; n--)
line = this.nextLine(line);
return line;
},
lineNumber: function(line) {
var num = 0;
while (line !== false) {
num++;
line = this.prevLine(line);
}
return num;
},
jumpToLine: function(line) {
if (typeof line == "number") line = this.nthLine(line);
this.selectLines(line, 0);
this.win.focus();
},
currentLine: function() { // Deprecated, but still there for backward compatibility
return this.lineNumber(this.cursorLine());
},
cursorLine: function() {
return this.cursorPosition().line;
},
cursorCoords: function(start) {return this.editor.cursorCoords(start);},
activateLineNumbers: function() {
var frame = this.frame, win = frame.contentWindow, doc = win.document, body = doc.body,
nums = this.lineNumbers, scroller = nums.firstChild, self = this;
var barWidth = null;
nums.onclick = function(e) {
var handler = self.options.onLineNumberClick;
if (handler) {
var div = (e || window.event).target || (e || window.event).srcElement;
var num = div == nums ? NaN : Number(div.innerHTML);
if (!isNaN(num)) handler(num, div);
}
};
function sizeBar() {
if (frame.offsetWidth == 0) return;
for (var root = frame; root.parentNode; root = root.parentNode){}
if (!nums.parentNode || root != document || !win.Editor) {
// Clear event handlers (their nodes might already be collected, so try/catch)
try{clear();}catch(e){}
clearInterval(sizeInterval);
return;
}
if (nums.offsetWidth != barWidth) {
barWidth = nums.offsetWidth;
frame.parentNode.style.paddingLeft = barWidth + "px";
}
}
function doScroll() {
nums.scrollTop = body.scrollTop || doc.documentElement.scrollTop || 0;
}
// Cleanup function, registered by nonWrapping and wrapping.
var clear = function(){};
sizeBar();
var sizeInterval = setInterval(sizeBar, 500);
function ensureEnoughLineNumbers(fill) {
var lineHeight = scroller.firstChild.offsetHeight;
if (lineHeight == 0) return;
var targetHeight = 50 + Math.max(body.offsetHeight, Math.max(frame.offsetHeight, body.scrollHeight || 0)),
lastNumber = Math.ceil(targetHeight / lineHeight);
for (var i = scroller.childNodes.length; i <= lastNumber; i++) {
var div = createHTMLElement("div");
div.appendChild(document.createTextNode(fill ? String(i + self.options.firstLineNumber) : "\u00a0"));
scroller.appendChild(div);
}
}
function nonWrapping() {
function update() {
ensureEnoughLineNumbers(true);
doScroll();
}
self.updateNumbers = update;
var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
onResize = win.addEventHandler(win, "resize", update, true);
clear = function(){
onScroll(); onResize();
if (self.updateNumbers == update) self.updateNumbers = null;
};
update();
}
function wrapping() {
var node, lineNum, next, pos, changes = [], styleNums = self.options.styleNumbers;
function setNum(n, node) {
// Does not typically happen (but can, if you mess with the
// document during the numbering)
if (!lineNum) lineNum = scroller.appendChild(createHTMLElement("div"));
if (styleNums) styleNums(lineNum, node, n);
// Changes are accumulated, so that the document layout
// doesn't have to be recomputed during the pass
changes.push(lineNum); changes.push(n);
pos = lineNum.offsetHeight + lineNum.offsetTop;
lineNum = lineNum.nextSibling;
}
function commitChanges() {
for (var i = 0; i < changes.length; i += 2)
changes[i].innerHTML = changes[i + 1];
changes = [];
}
function work() {
if (!scroller.parentNode || scroller.parentNode != self.lineNumbers) return;
var endTime = new Date().getTime() + self.options.lineNumberTime;
while (node) {
setNum(next++, node.previousSibling);
for (; node && !win.isBR(node); node = node.nextSibling) {
var bott = node.offsetTop + node.offsetHeight;
while (scroller.offsetHeight && bott - 3 > pos) {
var oldPos = pos;
setNum("&nbsp;");
if (pos <= oldPos) break;
}
}
if (node) node = node.nextSibling;
if (new Date().getTime() > endTime) {
commitChanges();
pending = setTimeout(work, self.options.lineNumberDelay);
return;
}
}
while (lineNum) setNum(next++);
commitChanges();
doScroll();
}
function start(firstTime) {
doScroll();
ensureEnoughLineNumbers(firstTime);
node = body.firstChild;
lineNum = scroller.firstChild;
pos = 0;
next = self.options.firstLineNumber;
work();
}
start(true);
var pending = null;
function update() {
if (pending) clearTimeout(pending);
if (self.editor.allClean()) start();
else pending = setTimeout(update, 200);
}
self.updateNumbers = update;
var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
onResize = win.addEventHandler(win, "resize", update, true);
clear = function(){
if (pending) clearTimeout(pending);
if (self.updateNumbers == update) self.updateNumbers = null;
onScroll();
onResize();
};
}
(this.options.textWrapping || this.options.styleNumbers ? wrapping : nonWrapping)();
},
setDynamicHeight: function() {
var self = this, activity = self.options.onCursorActivity, win = self.win, body = win.document.body,
lineHeight = null, timeout = null, vmargin = 2 * self.frame.offsetTop;
body.style.overflowY = "hidden";
win.document.documentElement.style.overflowY = "hidden";
this.frame.scrolling = "no";
function updateHeight() {
var trailingLines = 0, node = body.lastChild, computedHeight;
while (node && win.isBR(node)) {
if (!node.hackBR) trailingLines++;
node = node.previousSibling;
}
if (node) {
lineHeight = node.offsetHeight;
computedHeight = node.offsetTop + (1 + trailingLines) * lineHeight;
}
else if (lineHeight) {
computedHeight = trailingLines * lineHeight;
}
if (computedHeight) {
if (self.options.onDynamicHeightChange)
computedHeight = self.options.onDynamicHeightChange(computedHeight);
if (computedHeight)
self.wrapping.style.height = Math.max(vmargin + computedHeight, self.options.minHeight) + "px";
}
}
setTimeout(updateHeight, 300);
self.options.onCursorActivity = function(x) {
if (activity) activity(x);
clearTimeout(timeout);
timeout = setTimeout(updateHeight, 100);
};
}
};
CodeMirror.InvalidLineHandle = {toString: function(){return "CodeMirror.InvalidLineHandle";}};
CodeMirror.replace = function(element) {
if (typeof element == "string")
element = document.getElementById(element);
return function(newElement) {
element.parentNode.replaceChild(newElement, element);
};
};
CodeMirror.fromTextArea = function(area, options) {
if (typeof area == "string")
area = document.getElementById(area);
options = options || {};
if (area.style.width && options.width == null)
options.width = area.style.width;
if (area.style.height && options.height == null)
options.height = area.style.height;
if (options.content == null) options.content = area.value;
function updateField() {
area.value = mirror.getCode();
}
if (area.form) {
if (typeof area.form.addEventListener == "function")
area.form.addEventListener("submit", updateField, false);
else
area.form.attachEvent("onsubmit", updateField);
if (typeof area.form.submit == "function") {
var realSubmit = area.form.submit;
function wrapSubmit() {
updateField();
// Can't use realSubmit.apply because IE6 is too stupid
area.form.submit = realSubmit;
area.form.submit();
area.form.submit = wrapSubmit;
}
area.form.submit = wrapSubmit;
}
}
function insert(frame) {
if (area.nextSibling)
area.parentNode.insertBefore(frame, area.nextSibling);
else
area.parentNode.appendChild(frame);
}
area.style.display = "none";
var mirror = new CodeMirror(insert, options);
mirror.save = updateField;
mirror.toTextArea = function() {
updateField();
area.parentNode.removeChild(mirror.wrapping);
area.style.display = "";
if (area.form) {
if (typeof area.form.submit == "function")
area.form.submit = realSubmit;
if (typeof area.form.removeEventListener == "function")
area.form.removeEventListener("submit", updateField, false);
else
area.form.detachEvent("onsubmit", updateField);
}
};
return mirror;
};
CodeMirror.isProbablySupported = function() {
// This is rather awful, but can be useful.
var match;
if (window.opera)
return Number(window.opera.version()) >= 9.52;
else if (/Apple Computer, Inc/.test(navigator.vendor) && (match = navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./)))
return Number(match[1]) >= 3;
else if (document.selection && window.ActiveXObject && (match = navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/)))
return Number(match[1]) >= 6;
else if (match = navigator.userAgent.match(/gecko\/(\d{8})/i))
return Number(match[1]) >= 20050901;
else if (match = navigator.userAgent.match(/AppleWebKit\/(\d+)/))
return Number(match[1]) >= 525;
else
return null;
};
return CodeMirror;
})();

View File

@ -0,0 +1,24 @@
var CodeMirrorConfig=window.CodeMirrorConfig||{},CodeMirror=function(){function D(a,b){for(var c in b)a.hasOwnProperty(c)||(a[c]=b[c])}function E(a,b){for(var c=0;c<a.length;c++)b(a[c])}function s(a){return document.createElementNS&&document.documentElement.namespaceURI!==null?document.createElementNS("http://www.w3.org/1999/xhtml",a):document.createElement(a)}function F(a,b){var c=s("div"),e=s("div");c.style.position="absolute";c.style.height="100%";if(c.style.setExpression)try{c.style.setExpression("height",
"this.previousSibling.offsetHeight + 'px'")}catch(f){}c.style.top="0px";c.style.left="0px";c.style.overflow="hidden";a.appendChild(c);e.className="CodeMirror-line-numbers";c.appendChild(e);e.innerHTML="<div>"+b+"</div>";return c}function G(a){if(typeof a.parserfile=="string")a.parserfile=[a.parserfile];if(typeof a.basefiles=="string")a.basefiles=[a.basefiles];if(typeof a.stylesheet=="string")a.stylesheet=[a.stylesheet];var b=' spellcheck="'+(a.disableSpellcheck?"false":"true")+'"',c=['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html'+
b+"><head>"];c.push('<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>');var e=a.noScriptCaching?"?nocache="+(new Date).getTime().toString(16):"";E(a.stylesheet,function(f){c.push('<link rel="stylesheet" type="text/css" href="'+f+e+'"/>')});E(a.basefiles.concat(a.parserfile),function(f){/^https?:/.test(f)||(f=a.path+f);c.push('<script type="text/javascript" src="'+f+e+'"><\/script>')});c.push('</head><body style="border-width: 0;" class="editbox"'+b+"></body></html>");return c.join("")}
function t(a,b){this.options=b=b||{};D(b,CodeMirrorConfig);if(b.dumbTabs)b.tabMode="spaces";else if(b.normalTab)b.tabMode="default";if(b.cursorActivity)b.onCursorActivity=b.cursorActivity;var c=this.frame=s("iframe");if(b.iframeClass)c.className=b.iframeClass;c.frameBorder=0;c.style.border="0";c.style.width="100%";c.style.height="100%";c.style.display="block";var e=this.wrapping=s("div");e.style.position="relative";e.className="CodeMirror-wrapping";e.style.width=b.width;e.style.height=b.height=="dynamic"?
b.minHeight+"px":b.height;var f=this.textareaHack=s("textarea");e.appendChild(f);f.style.position="absolute";f.style.left="-10000px";f.style.width="10px";f.tabIndex=1E5;c.CodeMirror=this;if(b.domain&&H){this.html=G(b);c.src="javascript:(function(){document.open();"+(b.domain?'document.domain="'+b.domain+'";':"")+"document.write(window.frameElement.CodeMirror.html);document.close();})()"}else c.src="javascript:;";a.appendChild?a.appendChild(e):a(e);e.appendChild(c);if(b.lineNumbers)this.lineNumbers=
F(e,b.firstLineNumber);this.win=c.contentWindow;if(!b.domain||!H){this.win.document.open();this.win.document.write(G(b));this.win.document.close()}}D(CodeMirrorConfig,{stylesheet:[],path:"",parserfile:[],basefiles:["util.js","stringstream.js","select.js","undo.js","editor.js","tokenize.js"],iframeClass:null,passDelay:200,passTime:50,lineNumberDelay:200,lineNumberTime:50,continuousScanning:false,saveFunction:null,onLoad:null,onChange:null,undoDepth:50,undoDelay:800,disableSpellcheck:true,textWrapping:true,
readOnly:false,width:"",height:"300px",minHeight:100,onDynamicHeightChange:null,autoMatchParens:false,markParen:null,unmarkParen:null,parserConfig:null,tabMode:"indent",enterMode:"indent",electricChars:true,reindentOnLoad:false,activeTokens:null,onCursorActivity:null,lineNumbers:false,firstLineNumber:1,onLineNumberClick:null,indentUnit:2,domain:null,noScriptCaching:false,incrementalLoading:false});var H=document.selection&&window.ActiveXObject&&/MSIE/.test(navigator.userAgent);t.prototype={init:function(){this.options.initCallback&&
this.options.initCallback(this);if(this.options.onLoad)this.options.onLoad(this);this.options.lineNumbers&&this.activateLineNumbers();this.options.reindentOnLoad&&this.reindent();this.options.height=="dynamic"&&this.setDynamicHeight()},getCode:function(){return this.editor.getCode()},setCode:function(a){this.editor.importCode(a)},selection:function(){this.focusIfIE();return this.editor.selectedText()},reindent:function(){this.editor.reindent()},reindentSelection:function(){this.focusIfIE();this.editor.reindentSelection(null)},
focusIfIE:function(){this.win.select.ie_selection&&document.activeElement!=this.frame&&this.focus()},focus:function(){this.win.focus();this.editor.selectionSnapshot&&this.win.select.setBookmark(this.win.document.body,this.editor.selectionSnapshot)},replaceSelection:function(a){this.focus();this.editor.replaceSelection(a);return true},replaceChars:function(a,b,c){this.editor.replaceChars(a,b,c)},getSearchCursor:function(a,b,c){return this.editor.getSearchCursor(a,b,c)},undo:function(){this.editor.history.undo()},
redo:function(){this.editor.history.redo()},historySize:function(){return this.editor.history.historySize()},clearHistory:function(){this.editor.history.clear()},grabKeys:function(a,b){this.editor.grabKeys(a,b)},ungrabKeys:function(){this.editor.ungrabKeys()},setParser:function(a,b){this.editor.setParser(a,b)},setSpellcheck:function(a){this.win.document.body.spellcheck=a},setStylesheet:function(a){if(typeof a==="string")a=[a];for(var b={},c={},e=this.win.document.getElementsByTagName("link"),f=0,
d;d=e[f];f++)if(d.rel.indexOf("stylesheet")!==-1)for(var g=0;g<a.length;g++){var n=a[g];if(d.href.substring(d.href.length-n.length)===n){b[d.href]=true;c[n]=true}}for(f=0;d=e[f];f++)if(d.rel.indexOf("stylesheet")!==-1)d.disabled=!(d.href in b);for(g=0;g<a.length;g++){n=a[g];if(!(n in c)){d=this.win.document.createElement("link");d.rel="stylesheet";d.type="text/css";d.href=n;this.win.document.getElementsByTagName("head")[0].appendChild(d)}}},setTextWrapping:function(a){if(a!=this.options.textWrapping){this.win.document.body.style.whiteSpace=
a?"":"nowrap";this.options.textWrapping=a;if(this.lineNumbers){this.setLineNumbers(false);this.setLineNumbers(true)}}},setIndentUnit:function(a){this.win.indentUnit=a},setUndoDepth:function(a){this.editor.history.maxDepth=a},setTabMode:function(a){this.options.tabMode=a},setEnterMode:function(a){this.options.enterMode=a},setLineNumbers:function(a){if(a&&!this.lineNumbers){this.lineNumbers=F(this.wrapping,this.options.firstLineNumber);this.activateLineNumbers()}else if(!a&&this.lineNumbers){this.wrapping.removeChild(this.lineNumbers);
this.wrapping.style.paddingLeft="";this.lineNumbers=null}},cursorPosition:function(a){this.focusIfIE();return this.editor.cursorPosition(a)},firstLine:function(){return this.editor.firstLine()},lastLine:function(){return this.editor.lastLine()},nextLine:function(a){return this.editor.nextLine(a)},prevLine:function(a){return this.editor.prevLine(a)},lineContent:function(a){return this.editor.lineContent(a)},setLineContent:function(a,b){this.editor.setLineContent(a,b)},removeLine:function(a){this.editor.removeLine(a)},
insertIntoLine:function(a,b,c){this.editor.insertIntoLine(a,b,c)},selectLines:function(a,b,c,e){this.win.focus();this.editor.selectLines(a,b,c,e)},nthLine:function(a){for(var b=this.firstLine();a>1&&b!==false;a--)b=this.nextLine(b);return b},lineNumber:function(a){for(var b=0;a!==false;){b++;a=this.prevLine(a)}return b},jumpToLine:function(a){if(typeof a=="number")a=this.nthLine(a);this.selectLines(a,0);this.win.focus()},currentLine:function(){return this.lineNumber(this.cursorLine())},cursorLine:function(){return this.cursorPosition().line},
cursorCoords:function(a){return this.editor.cursorCoords(a)},activateLineNumbers:function(){function a(){if(d.offsetWidth!=0){for(var h=d;h.parentNode;h=h.parentNode);if(!i.parentNode||h!=document||!g.Editor){try{z()}catch(l){}clearInterval(J)}else if(i.offsetWidth!=A){A=i.offsetWidth;d.parentNode.style.paddingLeft=A+"px"}}}function b(){i.scrollTop=q.scrollTop||n.documentElement.scrollTop||0}function c(h){var l=j.firstChild.offsetHeight;if(l!=0){l=Math.ceil((50+Math.max(q.offsetHeight,Math.max(d.offsetHeight,
q.scrollHeight||0)))/l);for(var o=j.childNodes.length;o<=l;o++){var w=s("div");w.appendChild(document.createTextNode(h?String(o+k.options.firstLineNumber):"\u00a0"));j.appendChild(w)}}}function e(){function h(){c(true);b()}k.updateNumbers=h;var l=g.addEventHandler(g,"scroll",b,true),o=g.addEventHandler(g,"resize",h,true);z=function(){l();o();if(k.updateNumbers==h)k.updateNumbers=null};h()}function f(){function h(p,B){r||(r=j.appendChild(s("div")));I&&I(r,B,p);u.push(r);u.push(p);x=r.offsetHeight+
r.offsetTop;r=r.nextSibling}function l(){for(var p=0;p<u.length;p+=2)u[p].innerHTML=u[p+1];u=[]}function o(){if(!(!j.parentNode||j.parentNode!=k.lineNumbers)){for(var p=(new Date).getTime()+k.options.lineNumberTime;m;){for(h(C++,m.previousSibling);m&&!g.isBR(m);m=m.nextSibling)for(var B=m.offsetTop+m.offsetHeight;j.offsetHeight&&B-3>x;){var K=x;h("&nbsp;");if(x<=K)break}if(m)m=m.nextSibling;if((new Date).getTime()>p){l();v=setTimeout(o,k.options.lineNumberDelay);return}}for(;r;)h(C++);l();b()}}function w(p){b();
c(p);m=q.firstChild;r=j.firstChild;x=0;C=k.options.firstLineNumber;o()}function y(){v&&clearTimeout(v);if(k.editor.allClean())w();else v=setTimeout(y,200)}var m,r,C,x,u=[],I=k.options.styleNumbers;w(true);var v=null;k.updateNumbers=y;var L=g.addEventHandler(g,"scroll",b,true),M=g.addEventHandler(g,"resize",y,true);z=function(){v&&clearTimeout(v);if(k.updateNumbers==y)k.updateNumbers=null;L();M()}}var d=this.frame,g=d.contentWindow,n=g.document,q=n.body,i=this.lineNumbers,j=i.firstChild,k=this,A=null;
i.onclick=function(h){var l=k.options.onLineNumberClick;if(l){h=(h||window.event).target||(h||window.event).srcElement;var o=h==i?NaN:Number(h.innerHTML);isNaN(o)||l(o,h)}};var z=function(){};a();var J=setInterval(a,500);(this.options.textWrapping||this.options.styleNumbers?f:e)()},setDynamicHeight:function(){function a(){for(var q=0,i=f.lastChild,j;i&&e.isBR(i);){i.hackBR||q++;i=i.previousSibling}if(i){d=i.offsetHeight;j=i.offsetTop+(1+q)*d}else if(d)j=q*d;if(j){if(b.options.onDynamicHeightChange)j=
b.options.onDynamicHeightChange(j);if(j)b.wrapping.style.height=Math.max(n+j,b.options.minHeight)+"px"}}var b=this,c=b.options.onCursorActivity,e=b.win,f=e.document.body,d=null,g=null,n=2*b.frame.offsetTop;f.style.overflowY="hidden";e.document.documentElement.style.overflowY="hidden";this.frame.scrolling="no";setTimeout(a,300);b.options.onCursorActivity=function(q){c&&c(q);clearTimeout(g);g=setTimeout(a,100)}}};t.InvalidLineHandle={toString:function(){return"CodeMirror.InvalidLineHandle"}};t.replace=
function(a){if(typeof a=="string")a=document.getElementById(a);return function(b){a.parentNode.replaceChild(b,a)}};t.fromTextArea=function(a,b){function c(){a.value=d.getCode()}if(typeof a=="string")a=document.getElementById(a);b=b||{};if(a.style.width&&b.width==null)b.width=a.style.width;if(a.style.height&&b.height==null)b.height=a.style.height;if(b.content==null)b.content=a.value;if(a.form){typeof a.form.addEventListener=="function"?a.form.addEventListener("submit",c,false):a.form.attachEvent("onsubmit",
c);if(typeof a.form.submit=="function"){var e=a.form.submit,f=function(){c();a.form.submit=e;a.form.submit();a.form.submit=f};a.form.submit=f}}a.style.display="none";var d=new t(function(g){a.nextSibling?a.parentNode.insertBefore(g,a.nextSibling):a.parentNode.appendChild(g)},b);d.save=c;d.toTextArea=function(){c();a.parentNode.removeChild(d.wrapping);a.style.display="";if(a.form){if(typeof a.form.submit=="function")a.form.submit=e;typeof a.form.removeEventListener=="function"?a.form.removeEventListener("submit",
c,false):a.form.detachEvent("onsubmit",c)}};return d};t.isProbablySupported=function(){var a;return window.opera?Number(window.opera.version())>=9.52:/Apple Computer, Inc/.test(navigator.vendor)&&(a=navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./))?Number(a[1])>=3:document.selection&&window.ActiveXObject&&(a=navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/))?Number(a[1])>=6:(a=navigator.userAgent.match(/gecko\/(\d{8})/i))?Number(a[1])>=20050901:(a=navigator.userAgent.match(/AppleWebKit\/(\d+)/))?
Number(a[1])>=525:null};return t}();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
// Minimal framing needed to use CodeMirror-style parsers to highlight
// code. Load this along with tokenize.js, stringstream.js, and your
// parser. Then call highlightText, passing a string as the first
// argument, and as the second argument either a callback function
// that will be called with an array of SPAN nodes for every line in
// the code, or a DOM node to which to append these spans, and
// optionally (not needed if you only loaded one parser) a parser
// object.
// Stuff from util.js that the parsers are using.
var StopIteration = {toString: function() {return "StopIteration"}};
var Editor = {};
var indentUnit = 2;
(function(){
function normaliseString(string) {
var tab = "";
for (var i = 0; i < indentUnit; i++) tab += " ";
string = string.replace(/\t/g, tab).replace(/\u00a0/g, " ").replace(/\r\n?/g, "\n");
var pos = 0, parts = [], lines = string.split("\n");
for (var line = 0; line < lines.length; line++) {
if (line != 0) parts.push("\n");
parts.push(lines[line]);
}
return {
next: function() {
if (pos < parts.length) return parts[pos++];
else throw StopIteration;
}
};
}
window.highlightText = function(string, callback, parser) {
parser = (parser || Editor.Parser).make(stringStream(normaliseString(string)));
var line = [];
if (callback.nodeType == 1) {
var node = callback;
callback = function(line) {
for (var i = 0; i < line.length; i++)
node.appendChild(line[i]);
node.appendChild(document.createElement("br"));
};
}
try {
while (true) {
var token = parser.next();
if (token.value == "\n") {
callback(line);
line = [];
}
else {
var span = document.createElement("span");
span.className = token.style;
span.appendChild(document.createTextNode(token.value));
line.push(span);
}
}
}
catch (e) {
if (e != StopIteration) throw e;
}
if (line.length) callback(line);
}
})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,81 @@
/* Demonstration of embedding CodeMirror in a bigger application. The
* interface defined here is a mess of prompts and confirms, and
* should probably not be used in a real project.
*/
function MirrorFrame(place, options) {
this.home = document.createElement("div");
if (place.appendChild)
place.appendChild(this.home);
else
place(this.home);
var self = this;
function makeButton(name, action) {
var button = document.createElement("input");
button.type = "button";
button.value = name;
self.home.appendChild(button);
button.onclick = function(){self[action].call(self);};
}
makeButton("Search", "search");
makeButton("Replace", "replace");
makeButton("Current line", "line");
makeButton("Jump to line", "jump");
makeButton("Insert constructor", "macro");
makeButton("Indent all", "reindent");
this.mirror = new CodeMirror(this.home, options);
}
MirrorFrame.prototype = {
search: function() {
var text = prompt("Enter search term:", "");
if (!text) return;
var first = true;
do {
var cursor = this.mirror.getSearchCursor(text, first);
first = false;
while (cursor.findNext()) {
cursor.select();
if (!confirm("Search again?"))
return;
}
} while (confirm("End of document reached. Start over?"));
},
replace: function() {
// This is a replace-all, but it is possible to implement a
// prompting replace.
var from = prompt("Enter search string:", ""), to;
if (from) to = prompt("What should it be replaced with?", "");
if (to == null) return;
var cursor = this.mirror.getSearchCursor(from, false);
while (cursor.findNext())
cursor.replace(to);
},
jump: function() {
var line = prompt("Jump to line:", "");
if (line && !isNaN(Number(line)))
this.mirror.jumpToLine(Number(line));
},
line: function() {
alert("The cursor is currently at line " + this.mirror.currentLine());
this.mirror.focus();
},
macro: function() {
var name = prompt("Name your constructor:", "");
if (name)
this.mirror.replaceSelection("function " + name + "() {\n \n}\n\n" + name + ".prototype = {\n \n};\n");
},
reindent: function() {
this.mirror.reindent();
}
};

View File

@ -0,0 +1,161 @@
/* Simple parser for CSS */
var CSSParser = Editor.Parser = (function() {
var tokenizeCSS = (function() {
function normal(source, setState) {
var ch = source.next();
if (ch == "@") {
source.nextWhileMatches(/\w/);
return "css-at";
}
else if (ch == "/" && source.equals("*")) {
setState(inCComment);
return null;
}
else if (ch == "<" && source.equals("!")) {
setState(inSGMLComment);
return null;
}
else if (ch == "=") {
return "css-compare";
}
else if (source.equals("=") && (ch == "~" || ch == "|")) {
source.next();
return "css-compare";
}
else if (ch == "\"" || ch == "'") {
setState(inString(ch));
return null;
}
else if (ch == "#") {
source.nextWhileMatches(/\w/);
return "css-hash";
}
else if (ch == "!") {
source.nextWhileMatches(/[ \t]/);
source.nextWhileMatches(/\w/);
return "css-important";
}
else if (/\d/.test(ch)) {
source.nextWhileMatches(/[\w.%]/);
return "css-unit";
}
else if (/[,.+>*\/]/.test(ch)) {
return "css-select-op";
}
else if (/[;{}:\[\]]/.test(ch)) {
return "css-punctuation";
}
else {
source.nextWhileMatches(/[\w\\\-_]/);
return "css-identifier";
}
}
function inCComment(source, setState) {
var maybeEnd = false;
while (!source.endOfLine()) {
var ch = source.next();
if (maybeEnd && ch == "/") {
setState(normal);
break;
}
maybeEnd = (ch == "*");
}
return "css-comment";
}
function inSGMLComment(source, setState) {
var dashes = 0;
while (!source.endOfLine()) {
var ch = source.next();
if (dashes >= 2 && ch == ">") {
setState(normal);
break;
}
dashes = (ch == "-") ? dashes + 1 : 0;
}
return "css-comment";
}
function inString(quote) {
return function(source, setState) {
var escaped = false;
while (!source.endOfLine()) {
var ch = source.next();
if (ch == quote && !escaped)
break;
escaped = !escaped && ch == "\\";
}
if (!escaped)
setState(normal);
return "css-string";
};
}
return function(source, startState) {
return tokenizer(source, startState || normal);
};
})();
function indentCSS(inBraces, inRule, base) {
return function(nextChars) {
if (!inBraces || /^\}/.test(nextChars)) return base;
else if (inRule) return base + indentUnit * 2;
else return base + indentUnit;
};
}
// This is a very simplistic parser -- since CSS does not really
// nest, it works acceptably well, but some nicer colouroing could
// be provided with a more complicated parser.
function parseCSS(source, basecolumn) {
basecolumn = basecolumn || 0;
var tokens = tokenizeCSS(source);
var inBraces = false, inRule = false, inDecl = false;;
var iter = {
next: function() {
var token = tokens.next(), style = token.style, content = token.content;
if (style == "css-hash")
style = token.style = inRule ? "css-colorcode" : "css-identifier";
if (style == "css-identifier") {
if (inRule) token.style = "css-value";
else if (!inBraces && !inDecl) token.style = "css-selector";
}
if (content == "\n")
token.indentation = indentCSS(inBraces, inRule, basecolumn);
if (content == "{" && inDecl == "@media")
inDecl = false;
else if (content == "{")
inBraces = true;
else if (content == "}")
inBraces = inRule = inDecl = false;
else if (content == ";")
inRule = inDecl = false;
else if (inBraces && style != "css-comment" && style != "whitespace")
inRule = true;
else if (!inBraces && style == "css-at")
inDecl = content;
return token;
},
copy: function() {
var _inBraces = inBraces, _inRule = inRule, _tokenState = tokens.state;
return function(source) {
tokens = tokenizeCSS(source, _tokenState);
inBraces = _inBraces;
inRule = _inRule;
return iter;
};
}
};
return iter;
}
return {make: parseCSS, electricChars: "}"};
})();

View File

@ -0,0 +1,32 @@
var DummyParser = Editor.Parser = (function() {
function tokenizeDummy(source) {
while (!source.endOfLine()) source.next();
return "text";
}
function parseDummy(source) {
function indentTo(n) {return function() {return n;}}
source = tokenizer(source, tokenizeDummy);
var space = 0;
var iter = {
next: function() {
var tok = source.next();
if (tok.type == "whitespace") {
if (tok.value == "\n") tok.indentation = indentTo(space);
else space = tok.value.length;
}
return tok;
},
copy: function() {
var _space = space;
return function(_source) {
space = _space;
source = tokenizer(_source, tokenizeDummy);
return iter;
};
}
};
return iter;
}
return {make: parseDummy};
})();

View File

@ -0,0 +1,93 @@
var HTMLMixedParser = Editor.Parser = (function() {
// tags that trigger seperate parsers
var triggers = {
"script": "JSParser",
"style": "CSSParser"
};
function checkDependencies() {
var parsers = ['XMLParser'];
for (var p in triggers) parsers.push(triggers[p]);
for (var i in parsers) {
if (!window[parsers[i]]) throw new Error(parsers[i] + " parser must be loaded for HTML mixed mode to work.");
}
XMLParser.configure({useHTMLKludges: true});
}
function parseMixed(stream) {
checkDependencies();
var htmlParser = XMLParser.make(stream), localParser = null, inTag = false;
var iter = {next: top, copy: copy};
function top() {
var token = htmlParser.next();
if (token.content == "<")
inTag = true;
else if (token.style == "xml-tagname" && inTag === true)
inTag = token.content.toLowerCase();
else if (token.content == ">") {
if (triggers[inTag]) {
var parser = window[triggers[inTag]];
iter.next = local(parser, "</" + inTag);
}
inTag = false;
}
return token;
}
function local(parser, tag) {
var baseIndent = htmlParser.indentation();
localParser = parser.make(stream, baseIndent + indentUnit);
return function() {
if (stream.lookAhead(tag, false, false, true)) {
localParser = null;
iter.next = top;
return top();
}
var token = localParser.next();
var lt = token.value.lastIndexOf("<"), sz = Math.min(token.value.length - lt, tag.length);
if (lt != -1 && token.value.slice(lt, lt + sz).toLowerCase() == tag.slice(0, sz) &&
stream.lookAhead(tag.slice(sz), false, false, true)) {
stream.push(token.value.slice(lt));
token.value = token.value.slice(0, lt);
}
if (token.indentation) {
var oldIndent = token.indentation;
token.indentation = function(chars) {
if (chars == "</")
return baseIndent;
else
return oldIndent(chars);
};
}
return token;
};
}
function copy() {
var _html = htmlParser.copy(), _local = localParser && localParser.copy(),
_next = iter.next, _inTag = inTag;
return function(_stream) {
stream = _stream;
htmlParser = _html(_stream);
localParser = _local && _local(_stream);
iter.next = _next;
inTag = _inTag;
return iter;
};
}
return iter;
}
return {
make: parseMixed,
electricChars: "{}/:",
configure: function(obj) {
if (obj.triggers) triggers = obj.triggers;
}
};
})();

View File

@ -0,0 +1,359 @@
/* Parse function for JavaScript. Makes use of the tokenizer from
* tokenizejavascript.js. Note that your parsers do not have to be
* this complicated -- if you don't want to recognize local variables,
* in many languages it is enough to just look for braces, semicolons,
* parentheses, etc, and know when you are inside a string or comment.
*
* See manual.html for more info about the parser interface.
*/
var JSParser = Editor.Parser = (function() {
// Token types that can be considered to be atoms.
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
// Setting that can be used to have JSON data indent properly.
var json = false;
// Constructor for the lexical context objects.
function JSLexical(indented, column, type, align, prev, info) {
// indentation at start of this line
this.indented = indented;
// column at which this scope was opened
this.column = column;
// type of scope ('vardef', 'stat' (statement), 'form' (special form), '[', '{', or '(')
this.type = type;
// '[', '{', or '(' blocks that have any text after their opening
// character are said to be 'aligned' -- any lines below are
// indented all the way to the opening character.
if (align != null)
this.align = align;
// Parent scope, if any.
this.prev = prev;
this.info = info;
}
// My favourite JavaScript indentation rules.
function indentJS(lexical) {
return function(firstChars) {
var firstChar = firstChars && firstChars.charAt(0), type = lexical.type;
var 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(firstChars) ? indentUnit : 2 * indentUnit);
else if (lexical.align)
return lexical.column - (closing ? 1 : 0);
else
return lexical.indented + (closing ? 0 : indentUnit);
};
}
// The parser-iterator-producing function itself.
function parseJS(input, basecolumn) {
// Wrap the input in a token stream
var tokens = tokenizeJavaScript(input);
// The parser state. cc is a stack of actions that have to be
// performed to finish the current statement. For example we might
// know that we still need to find a closing parenthesis and a
// semicolon. Actions at the end of the stack go first. It is
// initialized with an infinitely looping action that consumes
// whole statements.
var cc = [json ? expressions : statements];
// Context contains information about the current local scope, the
// variables defined in that, and the scopes above it.
var context = null;
// The lexical scope, used mostly for indentation.
var lexical = new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false);
// Current column, and the indentation at the start of the current
// line. Used to create lexical scope objects.
var column = 0;
var indented = 0;
// Variables which are used by the mark, cont, and pass functions
// below to communicate with the driver loop in the 'next'
// function.
var consume, marked;
// The iterator object.
var parser = {next: next, copy: copy};
function next(){
// Start by performing any 'lexical' actions (adjusting the
// lexical variable), or the operations below will be working
// with the wrong lexical state.
while(cc[cc.length - 1].lex)
cc.pop()();
// Fetch a token.
var token = tokens.next();
// Adjust column and indented.
if (token.type == "whitespace" && column == 0)
indented = token.value.length;
column += token.value.length;
if (token.content == "\n"){
indented = column = 0;
// If the lexical scope's align property is still undefined at
// the end of the line, it is an un-aligned scope.
if (!("align" in lexical))
lexical.align = false;
// Newline tokens get an indentation function associated with
// them.
token.indentation = indentJS(lexical);
}
// No more processing for meaningless tokens.
if (token.type == "whitespace" || token.type == "comment")
return token;
// When a meaningful token is found and the lexical scope's
// align is undefined, it is an aligned scope.
if (!("align" in lexical))
lexical.align = true;
// Execute actions until one 'consumes' the token and we can
// return it.
while(true) {
consume = marked = false;
// Take and execute the topmost action.
cc.pop()(token.type, token.content);
if (consume){
// Marked is used to change the style of the current token.
if (marked)
token.style = marked;
// Here we differentiate between local and global variables.
else if (token.type == "variable" && inScope(token.content))
token.style = "js-localvariable";
return token;
}
}
}
// This makes a copy of the parser state. It stores all the
// stateful variables in a closure, and returns a function that
// will restore them when called with a new input stream. Note
// that the cc array has to be copied, because it is contantly
// being modified. Lexical objects are not mutated, and context
// objects are not mutated in a harmful way, so they can be shared
// between runs of the parser.
function copy(){
var _context = context, _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
return function copyParser(input){
context = _context;
lexical = _lexical;
cc = _cc.concat([]); // copies the array
column = indented = 0;
tokens = tokenizeJavaScript(input, _tokenState);
return parser;
};
}
// Helper function for pushing a number of actions onto the cc
// stack in reverse order.
function push(fs){
for (var i = fs.length - 1; i >= 0; i--)
cc.push(fs[i]);
}
// cont and pass are used by the action functions to add other
// actions to the stack. cont will cause the current token to be
// consumed, pass will leave it for the next action.
function cont(){
push(arguments);
consume = true;
}
function pass(){
push(arguments);
consume = false;
}
// Used to change the style of the current token.
function mark(style){
marked = style;
}
// Push a new scope. Will automatically link the current scope.
function pushcontext(){
context = {prev: context, vars: {"this": true, "arguments": true}};
}
// Pop off the current scope.
function popcontext(){
context = context.prev;
}
// Register a variable in the current scope.
function register(varname){
if (context){
mark("js-variabledef");
context.vars[varname] = true;
}
}
// Check whether a variable is defined in the current scope.
function inScope(varname){
var cursor = context;
while (cursor) {
if (cursor.vars[varname])
return true;
cursor = cursor.prev;
}
return false;
}
// Push a new lexical context of the given type.
function pushlex(type, info) {
var result = function(){
lexical = new JSLexical(indented, column, type, null, lexical, info)
};
result.lex = true;
return result;
}
// Pop off the current lexical context.
function poplex(){
if (lexical.type == ")")
indented = lexical.indented;
lexical = lexical.prev;
}
poplex.lex = true;
// The 'lex' flag on these actions is used by the 'next' function
// to know they can (and have to) be ran before moving on to the
// next token.
// Creates an action that discards tokens until it finds one of
// the given type.
function expect(wanted){
return function expecting(type){
if (type == wanted) cont();
else if (wanted == ";") pass();
else cont(arguments.callee);
};
}
// Looks for a statement, and then calls itself.
function statements(type){
return pass(statement, statements);
}
function expressions(type){
return pass(expression, expressions);
}
// Dispatches various types of statements based on the type of the
// current token.
function statement(type){
if (type == "var") cont(pushlex("vardef"), vardef1, expect(";"), poplex);
else if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
else if (type == "{") cont(pushlex("}"), block, poplex);
else if (type == ";") cont();
else if (type == "function") cont(functiondef);
else if (type == "for") cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), poplex, statement, poplex);
else if (type == "variable") cont(pushlex("stat"), maybelabel);
else if (type == "switch") cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), block, poplex, poplex);
else if (type == "case") cont(expression, expect(":"));
else if (type == "default") cont(expect(":"));
else if (type == "catch") cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), statement, poplex, popcontext);
else pass(pushlex("stat"), expression, expect(";"), poplex);
}
// Dispatch expression types.
function expression(type){
if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
else if (type == "function") cont(functiondef);
else if (type == "keyword c") cont(expression);
else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
else if (type == "operator") cont(expression);
else if (type == "[") cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
else if (type == "{") cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
else cont();
}
// Called for places where operators, function calls, or
// subscripts are valid. Will skip on to the next action if none
// is found.
function maybeoperator(type, value){
if (type == "operator" && /\+\+|--/.test(value)) cont(maybeoperator);
else if (type == "operator") cont(expression);
else if (type == ";") pass();
else if (type == "(") cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
else if (type == ".") cont(property, maybeoperator);
else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
}
// When a statement starts with a variable name, it might be a
// label. If no colon follows, it's a regular statement.
function maybelabel(type){
if (type == ":") cont(poplex, statement);
else pass(maybeoperator, expect(";"), poplex);
}
// Property names need to have their style adjusted -- the
// tokenizer thinks they are variables.
function property(type){
if (type == "variable") {mark("js-property"); cont();}
}
// This parses a property and its value in an object literal.
function objprop(type){
if (type == "variable") mark("js-property");
if (atomicTypes.hasOwnProperty(type)) cont(expect(":"), expression);
}
// Parses a comma-separated list of the things that are recognized
// by the 'what' argument.
function commasep(what, end){
function proceed(type) {
if (type == ",") cont(what, proceed);
else if (type == end) cont();
else cont(expect(end));
}
return function commaSeparated(type) {
if (type == end) cont();
else pass(what, proceed);
};
}
// Look for statements until a closing brace is found.
function block(type){
if (type == "}") cont();
else pass(statement, block);
}
// Variable definitions are split into two actions -- 1 looks for
// a name or the end of the definition, 2 looks for an '=' sign or
// a comma.
function vardef1(type, value){
if (type == "variable"){register(value); cont(vardef2);}
else cont();
}
function vardef2(type, value){
if (value == "=") cont(expression, vardef2);
else if (type == ",") cont(vardef1);
}
// For loops.
function forspec1(type){
if (type == "var") cont(vardef1, forspec2);
else if (type == ";") pass(forspec2);
else if (type == "variable") cont(formaybein);
else pass(forspec2);
}
function formaybein(type, value){
if (value == "in") cont(expression);
else cont(maybeoperator, forspec2);
}
function forspec2(type, value){
if (type == ";") cont(forspec3);
else if (value == "in") cont(expression);
else cont(expression, expect(";"), forspec3);
}
function forspec3(type) {
if (type == ")") pass();
else cont(expression);
}
// A function definition creates a new context, and the variables
// in its argument list have to be added to this context.
function functiondef(type, value){
if (type == "variable"){register(value); cont(functiondef);}
else if (type == "(") cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
}
function funarg(type, value){
if (type == "variable"){register(value); cont();}
}
return parser;
}
return {
make: parseJS,
electricChars: "{}:",
configure: function(obj) {
if (obj.json != null) json = obj.json;
}
};
})();

View File

@ -0,0 +1,419 @@
/*
Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
The copyrights embodied in the content of this file are licensed by
Yahoo! Inc. under the BSD (revised) open source license
@author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
Parse function for PHP. Makes use of the tokenizer from tokenizephp.js.
Based on parsejavascript.js by Marijn Haverbeke.
Features:
+ special "deprecated" style for PHP4 keywords like 'var'
+ support for PHP 5.3 keywords: 'namespace', 'use'
+ 911 predefined constants, 1301 predefined functions, 105 predeclared classes
from a typical PHP installation in a LAMP environment
+ new feature: syntax error flagging, thus enabling strict parsing of:
+ function definitions with explicitly or implicitly typed arguments and default values
+ modifiers (public, static etc.) applied to method and member definitions
+ foreach(array_expression as $key [=> $value]) loops
+ differentiation between single-quoted strings and double-quoted interpolating strings
*/
// add the Array.indexOf method for JS engines that don't support it (e.g. IE)
// code from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Array/IndexOf
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
var PHPParser = Editor.Parser = (function() {
// Token types that can be considered to be atoms, part of operator expressions
var atomicTypes = {
"atom": true, "number": true, "variable": true, "string": true
};
// Constructor for the lexical context objects.
function PHPLexical(indented, column, type, align, prev, info) {
// indentation at start of this line
this.indented = indented;
// column at which this scope was opened
this.column = column;
// type of scope ('stat' (statement), 'form' (special form), '[', '{', or '(')
this.type = type;
// '[', '{', or '(' blocks that have any text after their opening
// character are said to be 'aligned' -- any lines below are
// indented all the way to the opening character.
if (align != null)
this.align = align;
// Parent scope, if any.
this.prev = prev;
this.info = info;
}
// PHP indentation rules
function indentPHP(lexical) {
return function(firstChars) {
var firstChar = firstChars && firstChars.charAt(0), type = lexical.type;
var closing = firstChar == type;
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(firstChars) ? indentUnit : 2 * indentUnit);
else if (lexical.align)
return lexical.column - (closing ? 1 : 0);
else
return lexical.indented + (closing ? 0 : indentUnit);
};
}
// The parser-iterator-producing function itself.
function parsePHP(input, basecolumn) {
// Wrap the input in a token stream
var tokens = tokenizePHP(input);
// The parser state. cc is a stack of actions that have to be
// performed to finish the current statement. For example we might
// know that we still need to find a closing parenthesis and a
// semicolon. Actions at the end of the stack go first. It is
// initialized with an infinitely looping action that consumes
// whole statements.
var cc = [statements];
// The lexical scope, used mostly for indentation.
var lexical = new PHPLexical((basecolumn || 0) - indentUnit, 0, "block", false);
// Current column, and the indentation at the start of the current
// line. Used to create lexical scope objects.
var column = 0;
var indented = 0;
// Variables which are used by the mark, cont, and pass functions
// below to communicate with the driver loop in the 'next' function.
var consume, marked;
// The iterator object.
var parser = {next: next, copy: copy};
// parsing is accomplished by calling next() repeatedly
function next(){
// Start by performing any 'lexical' actions (adjusting the
// lexical variable), or the operations below will be working
// with the wrong lexical state.
while(cc[cc.length - 1].lex)
cc.pop()();
// Fetch the next token.
var token = tokens.next();
// Adjust column and indented.
if (token.type == "whitespace" && column == 0)
indented = token.value.length;
column += token.value.length;
if (token.content == "\n"){
indented = column = 0;
// If the lexical scope's align property is still undefined at
// the end of the line, it is an un-aligned scope.
if (!("align" in lexical))
lexical.align = false;
// Newline tokens get an indentation function associated with
// them.
token.indentation = indentPHP(lexical);
}
// No more processing for meaningless tokens.
if (token.type == "whitespace" || token.type == "comment"
|| token.type == "string_not_terminated" )
return token;
// When a meaningful token is found and the lexical scope's
// align is undefined, it is an aligned scope.
if (!("align" in lexical))
lexical.align = true;
// Execute actions until one 'consumes' the token and we can
// return it. 'marked' is used to change the style of the current token.
while(true) {
consume = marked = false;
// Take and execute the topmost action.
var action = cc.pop();
action(token);
if (consume){
if (marked)
token.style = marked;
// Here we differentiate between local and global variables.
return token;
}
}
return 1; // Firebug workaround for http://code.google.com/p/fbug/issues/detail?id=1239#c1
}
// This makes a copy of the parser state. It stores all the
// stateful variables in a closure, and returns a function that
// will restore them when called with a new input stream. Note
// that the cc array has to be copied, because it is contantly
// being modified. Lexical objects are not mutated, so they can
// be shared between runs of the parser.
function copy(){
var _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
return function copyParser(input){
lexical = _lexical;
cc = _cc.concat([]); // copies the array
column = indented = 0;
tokens = tokenizePHP(input, _tokenState);
return parser;
};
}
// Helper function for pushing a number of actions onto the cc
// stack in reverse order.
function push(fs){
for (var i = fs.length - 1; i >= 0; i--)
cc.push(fs[i]);
}
// cont and pass are used by the action functions to add other
// actions to the stack. cont will cause the current token to be
// consumed, pass will leave it for the next action.
function cont(){
push(arguments);
consume = true;
}
function pass(){
push(arguments);
consume = false;
}
// Used to change the style of the current token.
function mark(style){
marked = style;
}
// Add a lyer of style to the current token, for example syntax-error
function mark_add(style){
marked = marked + ' ' + style;
}
// Push a new lexical context of the given type.
function pushlex(type, info) {
var result = function pushlexing() {
lexical = new PHPLexical(indented, column, type, null, lexical, info)
};
result.lex = true;
return result;
}
// Pop off the current lexical context.
function poplex(){
if (lexical.prev)
lexical = lexical.prev;
}
poplex.lex = true;
// The 'lex' flag on these actions is used by the 'next' function
// to know they can (and have to) be ran before moving on to the
// next token.
// Creates an action that discards tokens until it finds one of
// the given type. This will ignore (and recover from) syntax errors.
function expect(wanted){
return function expecting(token){
if (token.type == wanted) cont(); // consume the token
else {
cont(arguments.callee); // continue expecting() - call itself
}
};
}
// Require a specific token type, or one of the tokens passed in the 'wanted' array
// Used to detect blatant syntax errors. 'execute' is used to pass extra code
// to be executed if the token is matched. For example, a '(' match could
// 'execute' a cont( compasep(funcarg), require(")") )
function require(wanted, execute){
return function requiring(token){
var ok;
var type = token.type;
if (typeof(wanted) == "string")
ok = (type == wanted) -1;
else
ok = wanted.indexOf(type);
if (ok >= 0) {
if (execute && typeof(execute[ok]) == "function") pass(execute[ok]);
else cont();
}
else {
if (!marked) mark(token.style);
mark_add("syntax-error");
cont(arguments.callee);
}
};
}
// Looks for a statement, and then calls itself.
function statements(token){
return pass(statement, statements);
}
// Dispatches various types of statements based on the type of the current token.
function statement(token){
var type = token.type;
if (type == "keyword a") cont(pushlex("form"), expression, altsyntax, statement, poplex);
else if (type == "keyword b") cont(pushlex("form"), altsyntax, statement, poplex);
else if (type == "{") cont(pushlex("}"), block, poplex);
else if (type == "function") funcdef();
// technically, "class implode {...}" is correct, but we'll flag that as an error because it overrides a predefined function
else if (type == "class") classdef();
else if (type == "foreach") cont(pushlex("form"), require("("), pushlex(")"), expression, require("as"), require("variable"), /* => $value */ expect(")"), altsyntax, poplex, statement, poplex);
else if (type == "for") cont(pushlex("form"), require("("), pushlex(")"), expression, require(";"), expression, require(";"), expression, require(")"), altsyntax, poplex, statement, poplex);
// public final function foo(), protected static $bar;
else if (type == "modifier") cont(require(["modifier", "variable", "function", "abstract"],
[null, commasep(require("variable")), funcdef, absfun]));
else if (type == "abstract") abs();
else if (type == "switch") cont(pushlex("form"), require("("), expression, require(")"), pushlex("}", "switch"), require([":", "{"]), block, poplex, poplex);
else if (type == "case") cont(expression, require(":"));
else if (type == "default") cont(require(":"));
else if (type == "catch") cont(pushlex("form"), require("("), require("t_string"), require("variable"), require(")"), statement, poplex);
else if (type == "const") cont(require("t_string")); // 'const static x=5' is a syntax error
// technically, "namespace implode {...}" is correct, but we'll flag that as an error because it overrides a predefined function
else if (type == "namespace") cont(namespacedef, require(";"));
// $variables may be followed by operators, () for variable function calls, or [] subscripts
else pass(pushlex("stat"), expression, require(";"), poplex);
}
// Dispatch expression types.
function expression(token){
var type = token.type;
if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
else if (type == "<<<") cont(require("string"), maybeoperator); // heredoc/nowdoc
else if (type == "t_string") cont(maybe_double_colon, maybeoperator);
else if (type == "keyword c" || type == "operator") cont(expression);
// lambda
else if (type == "function") lambdadef();
// function call or parenthesized expression: $a = ($b + 1) * 2;
else if (type == "(") cont(pushlex(")"), commasep(expression), require(")"), poplex, maybeoperator);
}
// Called for places where operators, function calls, or subscripts are
// valid. Will skip on to the next action if none is found.
function maybeoperator(token){
var type = token.type;
if (type == "operator") {
if (token.content == "?") cont(expression, require(":"), expression); // ternary operator
else cont(expression);
}
else if (type == "(") cont(pushlex(")"), expression, commasep(expression), require(")"), poplex, maybeoperator /* $varfunc() + 3 */);
else if (type == "[") cont(pushlex("]"), expression, require("]"), maybeoperator /* for multidimensional arrays, or $func[$i]() */, poplex);
}
// A regular use of the double colon to specify a class, as in self::func() or myclass::$var;
// Differs from `namespace` or `use` in that only one class can be the parent; chains (A::B::$var) are a syntax error.
function maybe_double_colon(token) {
if (token.type == "t_double_colon")
// A::$var, A::func(), A::const
cont(require(["t_string", "variable"]), maybeoperator);
else {
// a t_string wasn't followed by ::, such as in a function call: foo()
pass(expression)
}
}
// the declaration or definition of a function
function funcdef() {
cont(require("t_string"), require("("), pushlex(")"), commasep(funcarg), require(")"), poplex, block);
}
// the declaration or definition of a lambda
function lambdadef() {
cont(require("("), pushlex(")"), commasep(funcarg), require(")"), maybe_lambda_use, poplex, require("{"), pushlex("}"), block, poplex);
}
// optional lambda 'use' statement
function maybe_lambda_use(token) {
if(token.type == "namespace") {
cont(require('('), commasep(funcarg), require(')'));
}
else {
pass(expression);
}
}
// the definition of a class
function classdef() {
cont(require("t_string"), expect("{"), pushlex("}"), block, poplex);
}
// either funcdef if the current token is "function", or the keyword "function" + funcdef
function absfun(token) {
if(token.type == "function") funcdef();
else cont(require(["function"], [funcdef]));
}
// the abstract class or function (with optional modifier)
function abs(token) {
cont(require(["modifier", "function", "class"], [absfun, funcdef, classdef]));
}
// Parses a comma-separated list of the things that are recognized
// by the 'what' argument.
function commasep(what){
function proceed(token) {
if (token.type == ",") cont(what, proceed);
}
return function commaSeparated() {
pass(what, proceed);
};
}
// Look for statements until a closing brace is found.
function block(token) {
if (token.type == "}") cont();
else pass(statement, block);
}
function empty_parens_if_array(token) {
if(token.content == "array")
cont(require("("), require(")"));
}
function maybedefaultparameter(token){
if (token.content == "=") cont(require(["t_string", "string", "number", "atom"], [empty_parens_if_array, null, null]));
}
function var_or_reference(token) {
if(token.type == "variable") cont(maybedefaultparameter);
else if(token.content == "&") cont(require("variable"), maybedefaultparameter);
}
// support for default arguments: http://us.php.net/manual/en/functions.arguments.php#functions.arguments.default
function funcarg(token){
// function foo(myclass $obj) {...} or function foo(myclass &objref) {...}
if (token.type == "t_string") cont(var_or_reference);
// function foo($var) {...} or function foo(&$ref) {...}
else var_or_reference(token);
}
// A namespace definition or use
function maybe_double_colon_def(token) {
if (token.type == "t_double_colon")
cont(namespacedef);
}
function namespacedef(token) {
pass(require("t_string"), maybe_double_colon_def);
}
function altsyntax(token){
if (token.content==':')
cont(altsyntaxBlock,poplex);
}
function altsyntaxBlock(token){
if (token.type == "altsyntaxend") cont(require(';'));
else pass(statement, altsyntaxBlock);
}
return parser;
}
return {make: parsePHP, electricChars: "{}:"};
})();

View File

@ -0,0 +1,116 @@
/*
Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
The copyrights embodied in the content of this file are licensed by
Yahoo! Inc. under the BSD (revised) open source license
@author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
Based on parsehtmlmixed.js by Marijn Haverbeke.
*/
var PHPHTMLMixedParser = Editor.Parser = (function() {
var processingInstructions = ["<?php"];
if (!(PHPParser && CSSParser && JSParser && XMLParser))
throw new Error("PHP, CSS, JS, and XML parsers must be loaded for PHP+HTML mixed mode to work.");
XMLParser.configure({useHTMLKludges: true});
function parseMixed(stream) {
var htmlParser = XMLParser.make(stream), localParser = null,
inTag = false, lastAtt = null, phpParserState = null;
var iter = {next: top, copy: copy};
function top() {
var token = htmlParser.next();
if (token.content == "<")
inTag = true;
else if (token.style == "xml-tagname" && inTag === true)
inTag = token.content.toLowerCase();
else if (token.style == "xml-attname")
lastAtt = token.content;
else if (token.type == "xml-processing") {
// see if this opens a PHP block
for (var i = 0; i < processingInstructions.length; i++)
if (processingInstructions[i] == token.content) {
iter.next = local(PHPParser, "?>");
break;
}
}
else if (token.style == "xml-attribute" && token.content == "\"php\"" && inTag == "script" && lastAtt == "language")
inTag = "script/php";
// "xml-processing" tokens are ignored, because they should be handled by a specific local parser
else if (token.content == ">") {
if (inTag == "script/php")
iter.next = local(PHPParser, "</script>");
else if (inTag == "script")
iter.next = local(JSParser, "</script");
else if (inTag == "style")
iter.next = local(CSSParser, "</style");
lastAtt = null;
inTag = false;
}
return token;
}
function local(parser, tag) {
var baseIndent = htmlParser.indentation();
if (parser == PHPParser && phpParserState)
localParser = phpParserState(stream);
else
localParser = parser.make(stream, baseIndent + indentUnit);
return function() {
if (stream.lookAhead(tag, false, false, true)) {
if (parser == PHPParser) phpParserState = localParser.copy();
localParser = null;
iter.next = top;
return top(); // pass the ending tag to the enclosing parser
}
var token = localParser.next();
var lt = token.value.lastIndexOf("<"), sz = Math.min(token.value.length - lt, tag.length);
if (lt != -1 && token.value.slice(lt, lt + sz).toLowerCase() == tag.slice(0, sz) &&
stream.lookAhead(tag.slice(sz), false, false, true)) {
stream.push(token.value.slice(lt));
token.value = token.value.slice(0, lt);
}
if (token.indentation) {
var oldIndent = token.indentation;
token.indentation = function(chars) {
if (chars == "</")
return baseIndent;
else
return oldIndent(chars);
}
}
return token;
};
}
function copy() {
var _html = htmlParser.copy(), _local = localParser && localParser.copy(),
_next = iter.next, _inTag = inTag, _lastAtt = lastAtt, _php = phpParserState;
return function(_stream) {
stream = _stream;
htmlParser = _html(_stream);
localParser = _local && _local(_stream);
phpParserState = _php;
iter.next = _next;
inTag = _inTag;
lastAtt = _lastAtt;
return iter;
};
}
return iter;
}
return {
make: parseMixed,
electricChars: "{}/:",
configure: function(conf) {
if (conf.opening != null) processingInstructions = conf.opening;
}
};
})();

View File

@ -0,0 +1,162 @@
var SparqlParser = Editor.Parser = (function() {
function wordRegexp(words) {
return new RegExp("^(?:" + words.join("|") + ")$", "i");
}
var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
"isblank", "isliteral", "union", "a"]);
var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
"ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
"graph", "by", "asc", "desc"]);
var operatorChars = /[*+\-<>=&|]/;
var tokenizeSparql = (function() {
function normal(source, setState) {
var ch = source.next();
if (ch == "$" || ch == "?") {
source.nextWhileMatches(/[\w\d]/);
return "sp-var";
}
else if (ch == "<" && !source.matches(/[\s\u00a0=]/)) {
source.nextWhileMatches(/[^\s\u00a0>]/);
if (source.equals(">")) source.next();
return "sp-uri";
}
else if (ch == "\"" || ch == "'") {
setState(inLiteral(ch));
return null;
}
else if (/[{}\(\),\.;\[\]]/.test(ch)) {
return "sp-punc";
}
else if (ch == "#") {
while (!source.endOfLine()) source.next();
return "sp-comment";
}
else if (operatorChars.test(ch)) {
source.nextWhileMatches(operatorChars);
return "sp-operator";
}
else if (ch == ":") {
source.nextWhileMatches(/[\w\d\._\-]/);
return "sp-prefixed";
}
else {
source.nextWhileMatches(/[_\w\d]/);
if (source.equals(":")) {
source.next();
source.nextWhileMatches(/[\w\d_\-]/);
return "sp-prefixed";
}
var word = source.get(), type;
if (ops.test(word))
type = "sp-operator";
else if (keywords.test(word))
type = "sp-keyword";
else
type = "sp-word";
return {style: type, content: word};
}
}
function inLiteral(quote) {
return function(source, setState) {
var escaped = false;
while (!source.endOfLine()) {
var ch = source.next();
if (ch == quote && !escaped) {
setState(normal);
break;
}
escaped = !escaped && ch == "\\";
}
return "sp-literal";
};
}
return function(source, startState) {
return tokenizer(source, startState || normal);
};
})();
function indentSparql(context) {
return function(nextChars) {
var firstChar = nextChars && nextChars.charAt(0);
if (/[\]\}]/.test(firstChar))
while (context && context.type == "pattern") context = context.prev;
var closing = context && firstChar == matching[context.type];
if (!context)
return 0;
else if (context.type == "pattern")
return context.col;
else if (context.align)
return context.col - (closing ? context.width : 0);
else
return context.indent + (closing ? 0 : indentUnit);
}
}
function parseSparql(source) {
var tokens = tokenizeSparql(source);
var context = null, indent = 0, col = 0;
function pushContext(type, width) {
context = {prev: context, indent: indent, col: col, type: type, width: width};
}
function popContext() {
context = context.prev;
}
var iter = {
next: function() {
var token = tokens.next(), type = token.style, content = token.content, width = token.value.length;
if (content == "\n") {
token.indentation = indentSparql(context);
indent = col = 0;
if (context && context.align == null) context.align = false;
}
else if (type == "whitespace" && col == 0) {
indent = width;
}
else if (type != "sp-comment" && context && context.align == null) {
context.align = true;
}
if (content != "\n") col += width;
if (/[\[\{\(]/.test(content)) {
pushContext(content, width);
}
else if (/[\]\}\)]/.test(content)) {
while (context && context.type == "pattern")
popContext();
if (context && content == matching[context.type])
popContext();
}
else if (content == "." && context && context.type == "pattern") {
popContext();
}
else if ((type == "sp-word" || type == "sp-prefixed" || type == "sp-uri" || type == "sp-var" || type == "sp-literal") &&
context && /[\{\[]/.test(context.type)) {
pushContext("pattern", width);
}
return token;
},
copy: function() {
var _context = context, _indent = indent, _col = col, _tokenState = tokens.state;
return function(source) {
tokens = tokenizeSparql(source, _tokenState);
context = _context;
indent = _indent;
col = _col;
return iter;
};
}
};
return iter;
}
return {make: parseSparql, electricChars: "}]"};
})();

View File

@ -0,0 +1,291 @@
/* This file defines an XML parser, with a few kludges to make it
* useable for HTML. autoSelfClosers defines a set of tag names that
* are expected to not have a closing tag, and doNotIndent specifies
* the tags inside of which no indentation should happen (see Config
* object). These can be disabled by passing the editor an object like
* {useHTMLKludges: false} as parserConfig option.
*/
var XMLParser = Editor.Parser = (function() {
var Kludges = {
autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
"meta": true, "col": true, "frame": true, "base": true, "area": true},
doNotIndent: {"pre": true, "!cdata": true}
};
var NoKludges = {autoSelfClosers: {}, doNotIndent: {"!cdata": true}};
var UseKludges = Kludges;
var alignCDATA = false;
// Simple stateful tokenizer for XML documents. Returns a
// MochiKit-style iterator, with a state property that contains a
// function encapsulating the current state. See tokenize.js.
var tokenizeXML = (function() {
function inText(source, setState) {
var ch = source.next();
if (ch == "<") {
if (source.equals("!")) {
source.next();
if (source.equals("[")) {
if (source.lookAhead("[CDATA[", true)) {
setState(inBlock("xml-cdata", "]]>"));
return null;
}
else {
return "xml-text";
}
}
else if (source.lookAhead("--", true)) {
setState(inBlock("xml-comment", "-->"));
return null;
}
else if (source.lookAhead("DOCTYPE", true)) {
source.nextWhileMatches(/[\w\._\-]/);
setState(inBlock("xml-doctype", ">"));
return "xml-doctype";
}
else {
return "xml-text";
}
}
else if (source.equals("?")) {
source.next();
source.nextWhileMatches(/[\w\._\-]/);
setState(inBlock("xml-processing", "?>"));
return "xml-processing";
}
else {
if (source.equals("/")) source.next();
setState(inTag);
return "xml-punctuation";
}
}
else if (ch == "&") {
while (!source.endOfLine()) {
if (source.next() == ";")
break;
}
return "xml-entity";
}
else {
source.nextWhileMatches(/[^&<\n]/);
return "xml-text";
}
}
function inTag(source, setState) {
var ch = source.next();
if (ch == ">") {
setState(inText);
return "xml-punctuation";
}
else if (/[?\/]/.test(ch) && source.equals(">")) {
source.next();
setState(inText);
return "xml-punctuation";
}
else if (ch == "=") {
return "xml-punctuation";
}
else if (/[\'\"]/.test(ch)) {
setState(inAttribute(ch));
return null;
}
else {
source.nextWhileMatches(/[^\s\u00a0=<>\"\'\/?]/);
return "xml-name";
}
}
function inAttribute(quote) {
return function(source, setState) {
while (!source.endOfLine()) {
if (source.next() == quote) {
setState(inTag);
break;
}
}
return "xml-attribute";
};
}
function inBlock(style, terminator) {
return function(source, setState) {
while (!source.endOfLine()) {
if (source.lookAhead(terminator, true)) {
setState(inText);
break;
}
source.next();
}
return style;
};
}
return function(source, startState) {
return tokenizer(source, startState || inText);
};
})();
// The parser. The structure of this function largely follows that of
// parseJavaScript in parsejavascript.js (there is actually a bit more
// shared code than I'd like), but it is quite a bit simpler.
function parseXML(source) {
var tokens = tokenizeXML(source), token;
var cc = [base];
var tokenNr = 0, indented = 0;
var currentTag = null, context = null;
var consume;
function push(fs) {
for (var i = fs.length - 1; i >= 0; i--)
cc.push(fs[i]);
}
function cont() {
push(arguments);
consume = true;
}
function pass() {
push(arguments);
consume = false;
}
function markErr() {
token.style += " xml-error";
}
function expect(text) {
return function(style, content) {
if (content == text) cont();
else {markErr(); cont(arguments.callee);}
};
}
function pushContext(tagname, startOfLine) {
var noIndent = UseKludges.doNotIndent.hasOwnProperty(tagname) || (context && context.noIndent);
context = {prev: context, name: tagname, indent: indented, startOfLine: startOfLine, noIndent: noIndent};
}
function popContext() {
context = context.prev;
}
function computeIndentation(baseContext) {
return function(nextChars, current) {
var context = baseContext;
if (context && context.noIndent)
return current;
if (alignCDATA && /<!\[CDATA\[/.test(nextChars))
return 0;
if (context && /^<\//.test(nextChars))
context = context.prev;
while (context && !context.startOfLine)
context = context.prev;
if (context)
return context.indent + indentUnit;
else
return 0;
};
}
function base() {
return pass(element, base);
}
var harmlessTokens = {"xml-text": true, "xml-entity": true, "xml-comment": true, "xml-processing": true, "xml-doctype": true};
function element(style, content) {
if (content == "<") cont(tagname, attributes, endtag(tokenNr == 1));
else if (content == "</") cont(closetagname, expect(">"));
else if (style == "xml-cdata") {
if (!context || context.name != "!cdata") pushContext("!cdata");
if (/\]\]>$/.test(content)) popContext();
cont();
}
else if (harmlessTokens.hasOwnProperty(style)) cont();
else {markErr(); cont();}
}
function tagname(style, content) {
if (style == "xml-name") {
currentTag = content.toLowerCase();
token.style = "xml-tagname";
cont();
}
else {
currentTag = null;
pass();
}
}
function closetagname(style, content) {
if (style == "xml-name") {
token.style = "xml-tagname";
if (context && content.toLowerCase() == context.name) popContext();
else markErr();
}
cont();
}
function endtag(startOfLine) {
return function(style, content) {
if (content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
else if (content == ">") {pushContext(currentTag, startOfLine); cont();}
else {markErr(); cont(arguments.callee);}
};
}
function attributes(style) {
if (style == "xml-name") {token.style = "xml-attname"; cont(attribute, attributes);}
else pass();
}
function attribute(style, content) {
if (content == "=") cont(value);
else if (content == ">" || content == "/>") pass(endtag);
else pass();
}
function value(style) {
if (style == "xml-attribute") cont(value);
else pass();
}
return {
indentation: function() {return indented;},
next: function(){
token = tokens.next();
if (token.style == "whitespace" && tokenNr == 0)
indented = token.value.length;
else
tokenNr++;
if (token.content == "\n") {
indented = tokenNr = 0;
token.indentation = computeIndentation(context);
}
if (token.style == "whitespace" || token.type == "xml-comment")
return token;
while(true){
consume = false;
cc.pop()(token.style, token.content);
if (consume) return token;
}
},
copy: function(){
var _cc = cc.concat([]), _tokenState = tokens.state, _context = context;
var parser = this;
return function(input){
cc = _cc.concat([]);
tokenNr = indented = 0;
context = _context;
tokens = tokenizeXML(input, _tokenState);
return parser;
};
}
};
}
return {
make: parseXML,
electricChars: "/",
configure: function(config) {
if (config.useHTMLKludges != null)
UseKludges = config.useHTMLKludges ? Kludges : NoKludges;
if (config.alignCDATA)
alignCDATA = config.alignCDATA;
}
};
})();

View File

@ -0,0 +1,699 @@
/* Functionality for finding, storing, and restoring selections
*
* This does not provide a generic API, just the minimal functionality
* required by the CodeMirror system.
*/
// Namespace object.
var select = {};
(function() {
select.ie_selection = document.selection && document.selection.createRangeCollection;
// Find the 'top-level' (defined as 'a direct child of the node
// passed as the top argument') node that the given node is
// contained in. Return null if the given node is not inside the top
// node.
function topLevelNodeAt(node, top) {
while (node && node.parentNode != top)
node = node.parentNode;
return node;
}
// Find the top-level node that contains the node before this one.
function topLevelNodeBefore(node, top) {
while (!node.previousSibling && node.parentNode != top)
node = node.parentNode;
return topLevelNodeAt(node.previousSibling, top);
}
var fourSpaces = "\u00a0\u00a0\u00a0\u00a0";
select.scrollToNode = function(node, cursor) {
if (!node) return;
var element = node, body = document.body,
html = document.documentElement,
atEnd = !element.nextSibling || !element.nextSibling.nextSibling
|| !element.nextSibling.nextSibling.nextSibling;
// In Opera (and recent Webkit versions), BR elements *always*
// have a offsetTop property of zero.
var compensateHack = 0;
while (element && !element.offsetTop) {
compensateHack++;
element = element.previousSibling;
}
// atEnd is another kludge for these browsers -- if the cursor is
// at the end of the document, and the node doesn't have an
// offset, just scroll to the end.
if (compensateHack == 0) atEnd = false;
// WebKit has a bad habit of (sometimes) happily returning bogus
// offsets when the document has just been changed. This seems to
// always be 5/5, so we don't use those.
if (webkit && element && element.offsetTop == 5 && element.offsetLeft == 5)
return;
var y = compensateHack * (element ? element.offsetHeight : 0), x = 0,
width = (node ? node.offsetWidth : 0), pos = element;
while (pos && pos.offsetParent) {
y += pos.offsetTop;
// Don't count X offset for <br> nodes
if (!isBR(pos))
x += pos.offsetLeft;
pos = pos.offsetParent;
}
var scroll_x = body.scrollLeft || html.scrollLeft || 0,
scroll_y = body.scrollTop || html.scrollTop || 0,
scroll = false, screen_width = window.innerWidth || html.clientWidth || 0;
if (cursor || width < screen_width) {
if (cursor) {
var off = select.offsetInNode(node), size = nodeText(node).length;
if (size) x += width * (off / size);
}
var screen_x = x - scroll_x;
if (screen_x < 0 || screen_x > screen_width) {
scroll_x = x;
scroll = true;
}
}
var screen_y = y - scroll_y;
if (screen_y < 0 || atEnd || screen_y > (window.innerHeight || html.clientHeight || 0) - 50) {
scroll_y = atEnd ? 1e6 : y;
scroll = true;
}
if (scroll) window.scrollTo(scroll_x, scroll_y);
};
select.scrollToCursor = function(container) {
select.scrollToNode(select.selectionTopNode(container, true) || container.firstChild, true);
};
// Used to prevent restoring a selection when we do not need to.
var currentSelection = null;
select.snapshotChanged = function() {
if (currentSelection) currentSelection.changed = true;
};
// Find the 'leaf' node (BR or text) after the given one.
function baseNodeAfter(node) {
var next = node.nextSibling;
if (next) {
while (next.firstChild) next = next.firstChild;
if (next.nodeType == 3 || isBR(next)) return next;
else return baseNodeAfter(next);
}
else {
var parent = node.parentNode;
while (parent && !parent.nextSibling) parent = parent.parentNode;
return parent && baseNodeAfter(parent);
}
}
// This is called by the code in editor.js whenever it is replacing
// a text node. The function sees whether the given oldNode is part
// of the current selection, and updates this selection if it is.
// Because nodes are often only partially replaced, the length of
// the part that gets replaced has to be taken into account -- the
// selection might stay in the oldNode if the newNode is smaller
// than the selection's offset. The offset argument is needed in
// case the selection does move to the new object, and the given
// length is not the whole length of the new node (part of it might
// have been used to replace another node).
select.snapshotReplaceNode = function(from, to, length, offset) {
if (!currentSelection) return;
function replace(point) {
if (from == point.node) {
currentSelection.changed = true;
if (length && point.offset > length) {
point.offset -= length;
}
else {
point.node = to;
point.offset += (offset || 0);
}
}
else if (select.ie_selection && point.offset == 0 && point.node == baseNodeAfter(from)) {
currentSelection.changed = true;
}
}
replace(currentSelection.start);
replace(currentSelection.end);
};
select.snapshotMove = function(from, to, distance, relative, ifAtStart) {
if (!currentSelection) return;
function move(point) {
if (from == point.node && (!ifAtStart || point.offset == 0)) {
currentSelection.changed = true;
point.node = to;
if (relative) point.offset = Math.max(0, point.offset + distance);
else point.offset = distance;
}
}
move(currentSelection.start);
move(currentSelection.end);
};
// Most functions are defined in two ways, one for the IE selection
// model, one for the W3C one.
if (select.ie_selection) {
function selRange() {
var sel = document.selection;
if (!sel) return null;
if (sel.createRange) return sel.createRange();
else return sel.createTextRange();
}
function selectionNode(start) {
var range = selRange();
range.collapse(start);
function nodeAfter(node) {
var found = null;
while (!found && node) {
found = node.nextSibling;
node = node.parentNode;
}
return nodeAtStartOf(found);
}
function nodeAtStartOf(node) {
while (node && node.firstChild) node = node.firstChild;
return {node: node, offset: 0};
}
var containing = range.parentElement();
if (!isAncestor(document.body, containing)) return null;
if (!containing.firstChild) return nodeAtStartOf(containing);
var working = range.duplicate();
working.moveToElementText(containing);
working.collapse(true);
for (var cur = containing.firstChild; cur; cur = cur.nextSibling) {
if (cur.nodeType == 3) {
var size = cur.nodeValue.length;
working.move("character", size);
}
else {
working.moveToElementText(cur);
working.collapse(false);
}
var dir = range.compareEndPoints("StartToStart", working);
if (dir == 0) return nodeAfter(cur);
if (dir == 1) continue;
if (cur.nodeType != 3) return nodeAtStartOf(cur);
working.setEndPoint("StartToEnd", range);
return {node: cur, offset: size - working.text.length};
}
return nodeAfter(containing);
}
select.markSelection = function() {
currentSelection = null;
var sel = document.selection;
if (!sel) return;
var start = selectionNode(true),
end = selectionNode(false);
if (!start || !end) return;
currentSelection = {start: start, end: end, changed: false};
};
select.selectMarked = function() {
if (!currentSelection || !currentSelection.changed) return;
function makeRange(point) {
var range = document.body.createTextRange(),
node = point.node;
if (!node) {
range.moveToElementText(document.body);
range.collapse(false);
}
else if (node.nodeType == 3) {
range.moveToElementText(node.parentNode);
var offset = point.offset;
while (node.previousSibling) {
node = node.previousSibling;
offset += (node.innerText || "").length;
}
range.move("character", offset);
}
else {
range.moveToElementText(node);
range.collapse(true);
}
return range;
}
var start = makeRange(currentSelection.start), end = makeRange(currentSelection.end);
start.setEndPoint("StartToEnd", end);
start.select();
};
select.offsetInNode = function(node) {
var range = selRange();
if (!range) return 0;
var range2 = range.duplicate();
try {range2.moveToElementText(node);} catch(e){return 0;}
range.setEndPoint("StartToStart", range2);
return range.text.length;
};
// Get the top-level node that one end of the cursor is inside or
// after. Note that this returns false for 'no cursor', and null
// for 'start of document'.
select.selectionTopNode = function(container, start) {
var range = selRange();
if (!range) return false;
var range2 = range.duplicate();
range.collapse(start);
var around = range.parentElement();
if (around && isAncestor(container, around)) {
// Only use this node if the selection is not at its start.
range2.moveToElementText(around);
if (range.compareEndPoints("StartToStart", range2) == 1)
return topLevelNodeAt(around, container);
}
// Move the start of a range to the start of a node,
// compensating for the fact that you can't call
// moveToElementText with text nodes.
function moveToNodeStart(range, node) {
if (node.nodeType == 3) {
var count = 0, cur = node.previousSibling;
while (cur && cur.nodeType == 3) {
count += cur.nodeValue.length;
cur = cur.previousSibling;
}
if (cur) {
try{range.moveToElementText(cur);}
catch(e){return false;}
range.collapse(false);
}
else range.moveToElementText(node.parentNode);
if (count) range.move("character", count);
}
else {
try{range.moveToElementText(node);}
catch(e){return false;}
}
return true;
}
// Do a binary search through the container object, comparing
// the start of each node to the selection
var start = 0, end = container.childNodes.length - 1;
while (start < end) {
var middle = Math.ceil((end + start) / 2), node = container.childNodes[middle];
if (!node) return false; // Don't ask. IE6 manages this sometimes.
if (!moveToNodeStart(range2, node)) return false;
if (range.compareEndPoints("StartToStart", range2) == 1)
start = middle;
else
end = middle - 1;
}
if (start == 0) {
var test1 = selRange(), test2 = test1.duplicate();
try {
test2.moveToElementText(container);
} catch(exception) {
return null;
}
if (test1.compareEndPoints("StartToStart", test2) == 0)
return null;
}
return container.childNodes[start] || null;
};
// Place the cursor after this.start. This is only useful when
// manually moving the cursor instead of restoring it to its old
// position.
select.focusAfterNode = function(node, container) {
var range = document.body.createTextRange();
range.moveToElementText(node || container);
range.collapse(!node);
range.select();
};
select.somethingSelected = function() {
var range = selRange();
return range && (range.text != "");
};
function insertAtCursor(html) {
var range = selRange();
if (range) {
range.pasteHTML(html);
range.collapse(false);
range.select();
}
}
// Used to normalize the effect of the enter key, since browsers
// do widely different things when pressing enter in designMode.
select.insertNewlineAtCursor = function() {
insertAtCursor("<br>");
};
select.insertTabAtCursor = function() {
insertAtCursor(fourSpaces);
};
// Get the BR node at the start of the line on which the cursor
// currently is, and the offset into the line. Returns null as
// node if cursor is on first line.
select.cursorPos = function(container, start) {
var range = selRange();
if (!range) return null;
var topNode = select.selectionTopNode(container, start);
while (topNode && !isBR(topNode))
topNode = topNode.previousSibling;
var range2 = range.duplicate();
range.collapse(start);
if (topNode) {
range2.moveToElementText(topNode);
range2.collapse(false);
}
else {
// When nothing is selected, we can get all kinds of funky errors here.
try { range2.moveToElementText(container); }
catch (e) { return null; }
range2.collapse(true);
}
range.setEndPoint("StartToStart", range2);
return {node: topNode, offset: range.text.length};
};
select.setCursorPos = function(container, from, to) {
function rangeAt(pos) {
var range = document.body.createTextRange();
if (!pos.node) {
range.moveToElementText(container);
range.collapse(true);
}
else {
range.moveToElementText(pos.node);
range.collapse(false);
}
range.move("character", pos.offset);
return range;
}
var range = rangeAt(from);
if (to && to != from)
range.setEndPoint("EndToEnd", rangeAt(to));
range.select();
}
// Some hacks for storing and re-storing the selection when the editor loses and regains focus.
select.getBookmark = function (container) {
var from = select.cursorPos(container, true), to = select.cursorPos(container, false);
if (from && to) return {from: from, to: to};
};
// Restore a stored selection.
select.setBookmark = function(container, mark) {
if (!mark) return;
select.setCursorPos(container, mark.from, mark.to);
};
}
// W3C model
else {
// Find the node right at the cursor, not one of its
// ancestors with a suitable offset. This goes down the DOM tree
// until a 'leaf' is reached (or is it *up* the DOM tree?).
function innerNode(node, offset) {
while (node.nodeType != 3 && !isBR(node)) {
var newNode = node.childNodes[offset] || node.nextSibling;
offset = 0;
while (!newNode && node.parentNode) {
node = node.parentNode;
newNode = node.nextSibling;
}
node = newNode;
if (!newNode) break;
}
return {node: node, offset: offset};
}
// Store start and end nodes, and offsets within these, and refer
// back to the selection object from those nodes, so that this
// object can be updated when the nodes are replaced before the
// selection is restored.
select.markSelection = function () {
var selection = window.getSelection();
if (!selection || selection.rangeCount == 0)
return (currentSelection = null);
var range = selection.getRangeAt(0);
currentSelection = {
start: innerNode(range.startContainer, range.startOffset),
end: innerNode(range.endContainer, range.endOffset),
changed: false
};
};
select.selectMarked = function () {
var cs = currentSelection;
// on webkit-based browsers, it is apparently possible that the
// selection gets reset even when a node that is not one of the
// endpoints get messed with. the most common situation where
// this occurs is when a selection is deleted or overwitten. we
// check for that here.
function focusIssue() {
if (cs.start.node == cs.end.node && cs.start.offset == cs.end.offset) {
var selection = window.getSelection();
if (!selection || selection.rangeCount == 0) return true;
var range = selection.getRangeAt(0), point = innerNode(range.startContainer, range.startOffset);
return cs.start.node != point.node || cs.start.offset != point.offset;
}
}
if (!cs || !(cs.changed || (webkit && focusIssue()))) return;
var range = document.createRange();
function setPoint(point, which) {
if (point.node) {
// Some magic to generalize the setting of the start and end
// of a range.
if (point.offset == 0)
range["set" + which + "Before"](point.node);
else
range["set" + which](point.node, point.offset);
}
else {
range.setStartAfter(document.body.lastChild || document.body);
}
}
setPoint(cs.end, "End");
setPoint(cs.start, "Start");
selectRange(range);
};
// Helper for selecting a range object.
function selectRange(range) {
var selection = window.getSelection();
if (!selection) return;
selection.removeAllRanges();
selection.addRange(range);
}
function selectionRange() {
var selection = window.getSelection();
if (!selection || selection.rangeCount == 0)
return false;
else
return selection.getRangeAt(0);
}
// Finding the top-level node at the cursor in the W3C is, as you
// can see, quite an involved process.
select.selectionTopNode = function(container, start) {
var range = selectionRange();
if (!range) return false;
var node = start ? range.startContainer : range.endContainer;
var offset = start ? range.startOffset : range.endOffset;
// Work around (yet another) bug in Opera's selection model.
if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
container.childNodes[range.startOffset] && isBR(container.childNodes[range.startOffset]))
offset--;
// For text nodes, we look at the node itself if the cursor is
// inside, or at the node before it if the cursor is at the
// start.
if (node.nodeType == 3){
if (offset > 0)
return topLevelNodeAt(node, container);
else
return topLevelNodeBefore(node, container);
}
// Occasionally, browsers will return the HTML node as
// selection. If the offset is 0, we take the start of the frame
// ('after null'), otherwise, we take the last node.
else if (node.nodeName.toUpperCase() == "HTML") {
return (offset == 1 ? null : container.lastChild);
}
// If the given node is our 'container', we just look up the
// correct node by using the offset.
else if (node == container) {
return (offset == 0) ? null : node.childNodes[offset - 1];
}
// In any other case, we have a regular node. If the cursor is
// at the end of the node, we use the node itself, if it is at
// the start, we use the node before it, and in any other
// case, we look up the child before the cursor and use that.
else {
if (offset == node.childNodes.length)
return topLevelNodeAt(node, container);
else if (offset == 0)
return topLevelNodeBefore(node, container);
else
return topLevelNodeAt(node.childNodes[offset - 1], container);
}
};
select.focusAfterNode = function(node, container) {
var range = document.createRange();
range.setStartBefore(container.firstChild || container);
// In Opera, setting the end of a range at the end of a line
// (before a BR) will cause the cursor to appear on the next
// line, so we set the end inside of the start node when
// possible.
if (node && !node.firstChild)
range.setEndAfter(node);
else if (node)
range.setEnd(node, node.childNodes.length);
else
range.setEndBefore(container.firstChild || container);
range.collapse(false);
selectRange(range);
};
select.somethingSelected = function() {
var range = selectionRange();
return range && !range.collapsed;
};
select.offsetInNode = function(node) {
var range = selectionRange();
if (!range) return 0;
range = range.cloneRange();
range.setStartBefore(node);
return range.toString().length;
};
select.insertNodeAtCursor = function(node) {
var range = selectionRange();
if (!range) return;
range.deleteContents();
range.insertNode(node);
webkitLastLineHack(document.body);
// work around weirdness where Opera will magically insert a new
// BR node when a BR node inside a span is moved around. makes
// sure the BR ends up outside of spans.
if (window.opera && isBR(node) && isSpan(node.parentNode)) {
var next = node.nextSibling, p = node.parentNode, outer = p.parentNode;
outer.insertBefore(node, p.nextSibling);
var textAfter = "";
for (; next && next.nodeType == 3; next = next.nextSibling) {
textAfter += next.nodeValue;
removeElement(next);
}
outer.insertBefore(makePartSpan(textAfter, document), node.nextSibling);
}
range = document.createRange();
range.selectNode(node);
range.collapse(false);
selectRange(range);
}
select.insertNewlineAtCursor = function() {
select.insertNodeAtCursor(document.createElement("BR"));
};
select.insertTabAtCursor = function() {
select.insertNodeAtCursor(document.createTextNode(fourSpaces));
};
select.cursorPos = function(container, start) {
var range = selectionRange();
if (!range) return;
var topNode = select.selectionTopNode(container, start);
while (topNode && !isBR(topNode))
topNode = topNode.previousSibling;
range = range.cloneRange();
range.collapse(start);
if (topNode)
range.setStartAfter(topNode);
else
range.setStartBefore(container);
var text = range.toString();
return {node: topNode, offset: text.length};
};
select.setCursorPos = function(container, from, to) {
var range = document.createRange();
function setPoint(node, offset, side) {
if (offset == 0 && node && !node.nextSibling) {
range["set" + side + "After"](node);
return true;
}
if (!node)
node = container.firstChild;
else
node = node.nextSibling;
if (!node) return;
if (offset == 0) {
range["set" + side + "Before"](node);
return true;
}
var backlog = []
function decompose(node) {
if (node.nodeType == 3)
backlog.push(node);
else
forEach(node.childNodes, decompose);
}
while (true) {
while (node && !backlog.length) {
decompose(node);
node = node.nextSibling;
}
var cur = backlog.shift();
if (!cur) return false;
var length = cur.nodeValue.length;
if (length >= offset) {
range["set" + side](cur, offset);
return true;
}
offset -= length;
}
}
to = to || from;
if (setPoint(to.node, to.offset, "End") && setPoint(from.node, from.offset, "Start"))
selectRange(range);
};
}
})();

View File

@ -0,0 +1,159 @@
/* String streams are the things fed to parsers (which can feed them
* to a tokenizer if they want). They provide peek and next methods
* for looking at the current character (next 'consumes' this
* character, peek does not), and a get method for retrieving all the
* text that was consumed since the last time get was called.
*
* An easy mistake to make is to let a StopIteration exception finish
* the token stream while there are still characters pending in the
* string stream (hitting the end of the buffer while parsing a
* token). To make it easier to detect such errors, the stringstreams
* throw an exception when this happens.
*/
// Make a stringstream stream out of an iterator that returns strings.
// This is applied to the result of traverseDOM (see codemirror.js),
// and the resulting stream is fed to the parser.
var stringStream = function(source){
// String that's currently being iterated over.
var current = "";
// Position in that string.
var pos = 0;
// Accumulator for strings that have been iterated over but not
// get()-ed yet.
var accum = "";
// Make sure there are more characters ready, or throw
// StopIteration.
function ensureChars() {
while (pos == current.length) {
accum += current;
current = ""; // In case source.next() throws
pos = 0;
try {current = source.next();}
catch (e) {
if (e != StopIteration) throw e;
else return false;
}
}
return true;
}
return {
// peek: -> character
// Return the next character in the stream.
peek: function() {
if (!ensureChars()) return null;
return current.charAt(pos);
},
// next: -> character
// Get the next character, throw StopIteration if at end, check
// for unused content.
next: function() {
if (!ensureChars()) {
if (accum.length > 0)
throw "End of stringstream reached without emptying buffer ('" + accum + "').";
else
throw StopIteration;
}
return current.charAt(pos++);
},
// get(): -> string
// Return the characters iterated over since the last call to
// .get().
get: function() {
var temp = accum;
accum = "";
if (pos > 0){
temp += current.slice(0, pos);
current = current.slice(pos);
pos = 0;
}
return temp;
},
// Push a string back into the stream.
push: function(str) {
current = current.slice(0, pos) + str + current.slice(pos);
},
lookAhead: function(str, consume, skipSpaces, caseInsensitive) {
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
str = cased(str);
var found = false;
var _accum = accum, _pos = pos;
if (skipSpaces) this.nextWhileMatches(/[\s\u00a0]/);
while (true) {
var end = pos + str.length, left = current.length - pos;
if (end <= current.length) {
found = str == cased(current.slice(pos, end));
pos = end;
break;
}
else if (str.slice(0, left) == cased(current.slice(pos))) {
accum += current; current = "";
try {current = source.next();}
catch (e) {if (e != StopIteration) throw e; break;}
pos = 0;
str = str.slice(left);
}
else {
break;
}
}
if (!(found && consume)) {
current = accum.slice(_accum.length) + current;
pos = _pos;
accum = _accum;
}
return found;
},
// Wont't match past end of line.
lookAheadRegex: function(regex, consume) {
if (regex.source.charAt(0) != "^")
throw new Error("Regexps passed to lookAheadRegex must start with ^");
// Fetch the rest of the line
while (current.indexOf("\n", pos) == -1) {
try {current += source.next();}
catch (e) {if (e != StopIteration) throw e; break;}
}
var matched = current.slice(pos).match(regex);
if (matched && consume) pos += matched[0].length;
return matched;
},
// Utils built on top of the above
// more: -> boolean
// Produce true if the stream isn't empty.
more: function() {
return this.peek() !== null;
},
applies: function(test) {
var next = this.peek();
return (next !== null && test(next));
},
nextWhile: function(test) {
var next;
while ((next = this.peek()) !== null && test(next))
this.next();
},
matches: function(re) {
var next = this.peek();
return (next !== null && re.test(next));
},
nextWhileMatches: function(re) {
var next;
while ((next = this.peek()) !== null && re.test(next))
this.next();
},
equals: function(ch) {
return ch === this.peek();
},
endOfLine: function() {
var next = this.peek();
return next == null || next == "\n";
}
};
};

View File

@ -0,0 +1,57 @@
// A framework for simple tokenizers. Takes care of newlines and
// white-space, and of getting the text from the source stream into
// the token object. A state is a function of two arguments -- a
// string stream and a setState function. The second can be used to
// change the tokenizer's state, and can be ignored for stateless
// tokenizers. This function should advance the stream over a token
// and return a string or object containing information about the next
// token, or null to pass and have the (new) state be called to finish
// the token. When a string is given, it is wrapped in a {style, type}
// object. In the resulting object, the characters consumed are stored
// under the content property. Any whitespace following them is also
// automatically consumed, and added to the value property. (Thus,
// content is the actual meaningful part of the token, while value
// contains all the text it spans.)
function tokenizer(source, state) {
// Newlines are always a separate token.
function isWhiteSpace(ch) {
// The messy regexp is because IE's regexp matcher is of the
// opinion that non-breaking spaces are no whitespace.
return ch != "\n" && /^[\s\u00a0]*$/.test(ch);
}
var tokenizer = {
state: state,
take: function(type) {
if (typeof(type) == "string")
type = {style: type, type: type};
type.content = (type.content || "") + source.get();
if (!/\n$/.test(type.content))
source.nextWhile(isWhiteSpace);
type.value = type.content + source.get();
return type;
},
next: function () {
if (!source.more()) throw StopIteration;
var type;
if (source.equals("\n")) {
source.next();
return this.take("whitespace");
}
if (source.applies(isWhiteSpace))
type = "whitespace";
else
while (!type)
type = this.state(source, function(s) {tokenizer.state = s;});
return this.take(type);
}
};
return tokenizer;
}

View File

@ -0,0 +1,174 @@
/* Tokenizer for JavaScript code */
var tokenizeJavaScript = (function() {
// Advance the stream until the given character (not preceded by a
// backslash) is encountered, or the end of the line is reached.
function nextUntilUnescaped(source, end) {
var escaped = false;
while (!source.endOfLine()) {
var next = source.next();
if (next == end && !escaped)
return false;
escaped = !escaped && next == "\\";
}
return escaped;
}
// A map of JavaScript's keywords. The a/b/c keyword distinction is
// very rough, but it gives the parser enough information to parse
// correct code correctly (we don't care that much how we parse
// incorrect code). The style information included in these objects
// is used by the highlighter to pick the correct CSS style for a
// token.
var keywords = function(){
function result(type, style){
return {type: type, style: "js-" + style};
}
// keywords that take a parenthised expression, and then a
// statement (if)
var keywordA = result("keyword a", "keyword");
// keywords that take just a statement (else)
var keywordB = result("keyword b", "keyword");
// keywords that optionally take an expression, and form a
// statement (return)
var keywordC = result("keyword c", "keyword");
var operator = result("operator", "keyword");
var atom = result("atom", "atom");
return {
"if": keywordA, "while": keywordA, "with": keywordA,
"else": keywordB, "do": keywordB, "try": keywordB, "finally": keywordB,
"return": keywordC, "break": keywordC, "continue": keywordC, "new": keywordC, "delete": keywordC, "throw": keywordC,
"in": operator, "typeof": operator, "instanceof": operator,
"var": result("var", "keyword"), "function": result("function", "keyword"), "catch": result("catch", "keyword"),
"for": result("for", "keyword"), "switch": result("switch", "keyword"),
"case": result("case", "keyword"), "default": result("default", "keyword"),
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
};
}();
// Some helper regexps
var isOperatorChar = /[+\-*&%=<>!?|]/;
var isHexDigit = /[0-9A-Fa-f]/;
var isWordChar = /[\w\$_]/;
// Wrapper around jsToken that helps maintain parser state (whether
// we are inside of a multi-line comment and whether the next token
// could be a regular expression).
function jsTokenState(inside, regexp) {
return function(source, setState) {
var newInside = inside;
var type = jsToken(inside, regexp, source, function(c) {newInside = c;});
var newRegexp = type.type == "operator" || type.type == "keyword c" || type.type.match(/^[\[{}\(,;:]$/);
if (newRegexp != regexp || newInside != inside)
setState(jsTokenState(newInside, newRegexp));
return type;
};
}
// The token reader, intended to be used by the tokenizer from
// tokenize.js (through jsTokenState). Advances the source stream
// over a token, and returns an object containing the type and style
// of that token.
function jsToken(inside, regexp, source, setInside) {
function readHexNumber(){
source.next(); // skip the 'x'
source.nextWhileMatches(isHexDigit);
return {type: "number", style: "js-atom"};
}
function readNumber() {
source.nextWhileMatches(/[0-9]/);
if (source.equals(".")){
source.next();
source.nextWhileMatches(/[0-9]/);
}
if (source.equals("e") || source.equals("E")){
source.next();
if (source.equals("-"))
source.next();
source.nextWhileMatches(/[0-9]/);
}
return {type: "number", style: "js-atom"};
}
// Read a word, look it up in keywords. If not found, it is a
// variable, otherwise it is a keyword of the type found.
function readWord() {
source.nextWhileMatches(isWordChar);
var word = source.get();
var known = keywords.hasOwnProperty(word) && keywords.propertyIsEnumerable(word) && keywords[word];
return known ? {type: known.type, style: known.style, content: word} :
{type: "variable", style: "js-variable", content: word};
}
function readRegexp() {
nextUntilUnescaped(source, "/");
source.nextWhileMatches(/[gimy]/); // 'y' is "sticky" option in Mozilla
return {type: "regexp", style: "js-string"};
}
// Mutli-line comments are tricky. We want to return the newlines
// embedded in them as regular newline tokens, and then continue
// returning a comment token for every line of the comment. So
// some state has to be saved (inside) to indicate whether we are
// inside a /* */ sequence.
function readMultilineComment(start){
var newInside = "/*";
var maybeEnd = (start == "*");
while (true) {
if (source.endOfLine())
break;
var next = source.next();
if (next == "/" && maybeEnd){
newInside = null;
break;
}
maybeEnd = (next == "*");
}
setInside(newInside);
return {type: "comment", style: "js-comment"};
}
function readOperator() {
source.nextWhileMatches(isOperatorChar);
return {type: "operator", style: "js-operator"};
}
function readString(quote) {
var endBackSlash = nextUntilUnescaped(source, quote);
setInside(endBackSlash ? quote : null);
return {type: "string", style: "js-string"};
}
// Fetch the next token. Dispatches on first character in the
// stream, or first two characters when the first is a slash.
if (inside == "\"" || inside == "'")
return readString(inside);
var ch = source.next();
if (inside == "/*")
return readMultilineComment(ch);
else if (ch == "\"" || ch == "'")
return readString(ch);
// with punctuation, the type of the token is the symbol itself
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
return {type: ch, style: "js-punctuation"};
else if (ch == "0" && (source.equals("x") || source.equals("X")))
return readHexNumber();
else if (/[0-9]/.test(ch))
return readNumber();
else if (ch == "/"){
if (source.equals("*"))
{ source.next(); return readMultilineComment(ch); }
else if (source.equals("/"))
{ nextUntilUnescaped(source, null); return {type: "comment", style: "js-comment"};}
else if (regexp)
return readRegexp();
else
return readOperator();
}
else if (isOperatorChar.test(ch))
return readOperator();
else
return readWord();
}
// The external interface to the tokenizer.
return function(source, startState) {
return tokenizer(source, startState || jsTokenState(false, true));
};
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,413 @@
/**
* Storage and control for undo information within a CodeMirror
* editor. 'Why on earth is such a complicated mess required for
* that?', I hear you ask. The goal, in implementing this, was to make
* the complexity of storing and reverting undo information depend
* only on the size of the edited or restored content, not on the size
* of the whole document. This makes it necessary to use a kind of
* 'diff' system, which, when applied to a DOM tree, causes some
* complexity and hackery.
*
* In short, the editor 'touches' BR elements as it parses them, and
* the UndoHistory stores these. When nothing is touched in commitDelay
* milliseconds, the changes are committed: It goes over all touched
* nodes, throws out the ones that did not change since last commit or
* are no longer in the document, and assembles the rest into zero or
* more 'chains' -- arrays of adjacent lines. Links back to these
* chains are added to the BR nodes, while the chain that previously
* spanned these nodes is added to the undo history. Undoing a change
* means taking such a chain off the undo history, restoring its
* content (text is saved per line) and linking it back into the
* document.
*/
// A history object needs to know about the DOM container holding the
// document, the maximum amount of undo levels it should store, the
// delay (of no input) after which it commits a set of changes, and,
// unfortunately, the 'parent' window -- a window that is not in
// designMode, and on which setTimeout works in every browser.
function UndoHistory(container, maxDepth, commitDelay, editor) {
this.container = container;
this.maxDepth = maxDepth; this.commitDelay = commitDelay;
this.editor = editor;
// This line object represents the initial, empty editor.
var initial = {text: "", from: null, to: null};
// As the borders between lines are represented by BR elements, the
// start of the first line and the end of the last one are
// represented by null. Since you can not store any properties
// (links to line objects) in null, these properties are used in
// those cases.
this.first = initial; this.last = initial;
// Similarly, a 'historyTouched' property is added to the BR in
// front of lines that have already been touched, and 'firstTouched'
// is used for the first line.
this.firstTouched = false;
// History is the set of committed changes, touched is the set of
// nodes touched since the last commit.
this.history = []; this.redoHistory = []; this.touched = []; this.lostundo = 0;
}
UndoHistory.prototype = {
// Schedule a commit (if no other touches come in for commitDelay
// milliseconds).
scheduleCommit: function() {
var self = this;
parent.clearTimeout(this.commitTimeout);
this.commitTimeout = parent.setTimeout(function(){self.tryCommit();}, this.commitDelay);
},
// Mark a node as touched. Null is a valid argument.
touch: function(node) {
this.setTouched(node);
this.scheduleCommit();
},
// Undo the last change.
undo: function() {
// Make sure pending changes have been committed.
this.commit();
if (this.history.length) {
// Take the top diff from the history, apply it, and store its
// shadow in the redo history.
var item = this.history.pop();
this.redoHistory.push(this.updateTo(item, "applyChain"));
this.notifyEnvironment();
return this.chainNode(item);
}
},
// Redo the last undone change.
redo: function() {
this.commit();
if (this.redoHistory.length) {
// The inverse of undo, basically.
var item = this.redoHistory.pop();
this.addUndoLevel(this.updateTo(item, "applyChain"));
this.notifyEnvironment();
return this.chainNode(item);
}
},
clear: function() {
this.history = [];
this.redoHistory = [];
this.lostundo = 0;
},
// Ask for the size of the un/redo histories.
historySize: function() {
return {undo: this.history.length, redo: this.redoHistory.length, lostundo: this.lostundo};
},
// Push a changeset into the document.
push: function(from, to, lines) {
var chain = [];
for (var i = 0; i < lines.length; i++) {
var end = (i == lines.length - 1) ? to : document.createElement("br");
chain.push({from: from, to: end, text: cleanText(lines[i])});
from = end;
}
this.pushChains([chain], from == null && to == null);
this.notifyEnvironment();
},
pushChains: function(chains, doNotHighlight) {
this.commit(doNotHighlight);
this.addUndoLevel(this.updateTo(chains, "applyChain"));
this.redoHistory = [];
},
// Retrieve a DOM node from a chain (for scrolling to it after undo/redo).
chainNode: function(chains) {
for (var i = 0; i < chains.length; i++) {
var start = chains[i][0], node = start && (start.from || start.to);
if (node) return node;
}
},
// Clear the undo history, make the current document the start
// position.
reset: function() {
this.history = []; this.redoHistory = []; this.lostundo = 0;
},
textAfter: function(br) {
return this.after(br).text;
},
nodeAfter: function(br) {
return this.after(br).to;
},
nodeBefore: function(br) {
return this.before(br).from;
},
// Commit unless there are pending dirty nodes.
tryCommit: function() {
if (!window || !window.parent || !window.UndoHistory) return; // Stop when frame has been unloaded
if (this.editor.highlightDirty()) this.commit(true);
else this.scheduleCommit();
},
// Check whether the touched nodes hold any changes, if so, commit
// them.
commit: function(doNotHighlight) {
parent.clearTimeout(this.commitTimeout);
// Make sure there are no pending dirty nodes.
if (!doNotHighlight) this.editor.highlightDirty(true);
// Build set of chains.
var chains = this.touchedChains(), self = this;
if (chains.length) {
this.addUndoLevel(this.updateTo(chains, "linkChain"));
this.redoHistory = [];
this.notifyEnvironment();
}
},
// [ end of public interface ]
// Update the document with a given set of chains, return its
// shadow. updateFunc should be "applyChain" or "linkChain". In the
// second case, the chains are taken to correspond the the current
// document, and only the state of the line data is updated. In the
// first case, the content of the chains is also pushed iinto the
// document.
updateTo: function(chains, updateFunc) {
var shadows = [], dirty = [];
for (var i = 0; i < chains.length; i++) {
shadows.push(this.shadowChain(chains[i]));
dirty.push(this[updateFunc](chains[i]));
}
if (updateFunc == "applyChain")
this.notifyDirty(dirty);
return shadows;
},
// Notify the editor that some nodes have changed.
notifyDirty: function(nodes) {
forEach(nodes, method(this.editor, "addDirtyNode"))
this.editor.scheduleHighlight();
},
notifyEnvironment: function() {
if (this.onChange) this.onChange(this.editor);
// Used by the line-wrapping line-numbering code.
if (window.frameElement && window.frameElement.CodeMirror.updateNumbers)
window.frameElement.CodeMirror.updateNumbers();
},
// Link a chain into the DOM nodes (or the first/last links for null
// nodes).
linkChain: function(chain) {
for (var i = 0; i < chain.length; i++) {
var line = chain[i];
if (line.from) line.from.historyAfter = line;
else this.first = line;
if (line.to) line.to.historyBefore = line;
else this.last = line;
}
},
// Get the line object after/before a given node.
after: function(node) {
return node ? node.historyAfter : this.first;
},
before: function(node) {
return node ? node.historyBefore : this.last;
},
// Mark a node as touched if it has not already been marked.
setTouched: function(node) {
if (node) {
if (!node.historyTouched) {
this.touched.push(node);
node.historyTouched = true;
}
}
else {
this.firstTouched = true;
}
},
// Store a new set of undo info, throw away info if there is more of
// it than allowed.
addUndoLevel: function(diffs) {
this.history.push(diffs);
if (this.history.length > this.maxDepth) {
this.history.shift();
this.lostundo += 1;
}
},
// Build chains from a set of touched nodes.
touchedChains: function() {
var self = this;
// The temp system is a crummy hack to speed up determining
// whether a (currently touched) node has a line object associated
// with it. nullTemp is used to store the object for the first
// line, other nodes get it stored in their historyTemp property.
var nullTemp = null;
function temp(node) {return node ? node.historyTemp : nullTemp;}
function setTemp(node, line) {
if (node) node.historyTemp = line;
else nullTemp = line;
}
function buildLine(node) {
var text = [];
for (var cur = node ? node.nextSibling : self.container.firstChild;
cur && (!isBR(cur) || cur.hackBR); cur = cur.nextSibling)
if (!cur.hackBR && cur.currentText) text.push(cur.currentText);
return {from: node, to: cur, text: cleanText(text.join(""))};
}
// Filter out unchanged lines and nodes that are no longer in the
// document. Build up line objects for remaining nodes.
var lines = [];
if (self.firstTouched) self.touched.push(null);
forEach(self.touched, function(node) {
if (node && (node.parentNode != self.container || node.hackBR)) return;
if (node) node.historyTouched = false;
else self.firstTouched = false;
var line = buildLine(node), shadow = self.after(node);
if (!shadow || shadow.text != line.text || shadow.to != line.to) {
lines.push(line);
setTemp(node, line);
}
});
// Get the BR element after/before the given node.
function nextBR(node, dir) {
var link = dir + "Sibling", search = node[link];
while (search && !isBR(search))
search = search[link];
return search;
}
// Assemble line objects into chains by scanning the DOM tree
// around them.
var chains = []; self.touched = [];
forEach(lines, function(line) {
// Note that this makes the loop skip line objects that have
// been pulled into chains by lines before them.
if (!temp(line.from)) return;
var chain = [], curNode = line.from, safe = true;
// Put any line objects (referred to by temp info) before this
// one on the front of the array.
while (true) {
var curLine = temp(curNode);
if (!curLine) {
if (safe) break;
else curLine = buildLine(curNode);
}
chain.unshift(curLine);
setTemp(curNode, null);
if (!curNode) break;
safe = self.after(curNode);
curNode = nextBR(curNode, "previous");
}
curNode = line.to; safe = self.before(line.from);
// Add lines after this one at end of array.
while (true) {
if (!curNode) break;
var curLine = temp(curNode);
if (!curLine) {
if (safe) break;
else curLine = buildLine(curNode);
}
chain.push(curLine);
setTemp(curNode, null);
safe = self.before(curNode);
curNode = nextBR(curNode, "next");
}
chains.push(chain);
});
return chains;
},
// Find the 'shadow' of a given chain by following the links in the
// DOM nodes at its start and end.
shadowChain: function(chain) {
var shadows = [], next = this.after(chain[0].from), end = chain[chain.length - 1].to;
while (true) {
shadows.push(next);
var nextNode = next.to;
if (!nextNode || nextNode == end)
break;
else
next = nextNode.historyAfter || this.before(end);
// (The this.before(end) is a hack -- FF sometimes removes
// properties from BR nodes, in which case the best we can hope
// for is to not break.)
}
return shadows;
},
// Update the DOM tree to contain the lines specified in a given
// chain, link this chain into the DOM nodes.
applyChain: function(chain) {
// Some attempt is made to prevent the cursor from jumping
// randomly when an undo or redo happens. It still behaves a bit
// strange sometimes.
var cursor = select.cursorPos(this.container, false), self = this;
// Remove all nodes in the DOM tree between from and to (null for
// start/end of container).
function removeRange(from, to) {
var pos = from ? from.nextSibling : self.container.firstChild;
while (pos != to) {
var temp = pos.nextSibling;
removeElement(pos);
pos = temp;
}
}
var start = chain[0].from, end = chain[chain.length - 1].to;
// Clear the space where this change has to be made.
removeRange(start, end);
// Insert the content specified by the chain into the DOM tree.
for (var i = 0; i < chain.length; i++) {
var line = chain[i];
// The start and end of the space are already correct, but BR
// tags inside it have to be put back.
if (i > 0)
self.container.insertBefore(line.from, end);
// Add the text.
var node = makePartSpan(fixSpaces(line.text));
self.container.insertBefore(node, end);
// See if the cursor was on this line. Put it back, adjusting
// for changed line length, if it was.
if (cursor && cursor.node == line.from) {
var cursordiff = 0;
var prev = this.after(line.from);
if (prev && i == chain.length - 1) {
// Only adjust if the cursor is after the unchanged part of
// the line.
for (var match = 0; match < cursor.offset &&
line.text.charAt(match) == prev.text.charAt(match); match++){}
if (cursor.offset > match)
cursordiff = line.text.length - prev.text.length;
}
select.setCursorPos(this.container, {node: line.from, offset: Math.max(0, cursor.offset + cursordiff)});
}
// Cursor was in removed line, this is last new line.
else if (cursor && (i == chain.length - 1) && cursor.node && cursor.node.parentNode != this.container) {
select.setCursorPos(this.container, {node: line.from, offset: line.text.length});
}
}
// Anchor the chain in the DOM tree.
this.linkChain(chain);
return start;
}
};

View File

@ -0,0 +1,133 @@
/* A few useful utility functions. */
// Capture a method on an object.
function method(obj, name) {
return function() {obj[name].apply(obj, arguments);};
}
// The value used to signal the end of a sequence in iterators.
var StopIteration = {toString: function() {return "StopIteration"}};
// Apply a function to each element in a sequence.
function forEach(iter, f) {
if (iter.next) {
try {while (true) f(iter.next());}
catch (e) {if (e != StopIteration) throw e;}
}
else {
for (var i = 0; i < iter.length; i++)
f(iter[i]);
}
}
// Map a function over a sequence, producing an array of results.
function map(iter, f) {
var accum = [];
forEach(iter, function(val) {accum.push(f(val));});
return accum;
}
// Create a predicate function that tests a string againsts a given
// regular expression. No longer used but might be used by 3rd party
// parsers.
function matcher(regexp){
return function(value){return regexp.test(value);};
}
// Test whether a DOM node has a certain CSS class.
function hasClass(element, className) {
var classes = element.className;
return classes && new RegExp("(^| )" + className + "($| )").test(classes);
}
function removeClass(element, className) {
element.className = element.className.replace(new RegExp(" " + className + "\\b", "g"), "");
return element;
}
// Insert a DOM node after another node.
function insertAfter(newNode, oldNode) {
var parent = oldNode.parentNode;
parent.insertBefore(newNode, oldNode.nextSibling);
return newNode;
}
function removeElement(node) {
if (node.parentNode)
node.parentNode.removeChild(node);
}
function clearElement(node) {
while (node.firstChild)
node.removeChild(node.firstChild);
}
// Check whether a node is contained in another one.
function isAncestor(node, child) {
while (child = child.parentNode) {
if (node == child)
return true;
}
return false;
}
// The non-breaking space character.
var nbsp = "\u00a0";
var matching = {"{": "}", "[": "]", "(": ")",
"}": "{", "]": "[", ")": "("};
// Standardize a few unportable event properties.
function normalizeEvent(event) {
if (!event.stopPropagation) {
event.stopPropagation = function() {this.cancelBubble = true;};
event.preventDefault = function() {this.returnValue = false;};
}
if (!event.stop) {
event.stop = function() {
this.stopPropagation();
this.preventDefault();
};
}
if (event.type == "keypress") {
event.code = (event.charCode == null) ? event.keyCode : event.charCode;
event.character = String.fromCharCode(event.code);
}
return event;
}
// Portably register event handlers.
function addEventHandler(node, type, handler, removeFunc) {
function wrapHandler(event) {
handler(normalizeEvent(event || window.event));
}
if (typeof node.addEventListener == "function") {
node.addEventListener(type, wrapHandler, false);
if (removeFunc) return function() {node.removeEventListener(type, wrapHandler, false);};
}
else {
node.attachEvent("on" + type, wrapHandler);
if (removeFunc) return function() {node.detachEvent("on" + type, wrapHandler);};
}
}
function nodeText(node) {
return node.textContent || node.innerText || node.nodeValue || "";
}
function nodeTop(node) {
var top = 0;
while (node.offsetParent) {
top += node.offsetTop;
node = node.offsetParent;
}
return top;
}
function isBR(node) {
var nn = node.nodeName;
return nn == "BR" || nn == "br";
}
function isSpan(node) {
var nn = node.nodeName;
return nn == "SPAN" || nn == "span";
}

1
media/editors/index.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -0,0 +1,5 @@
input.radio {border:1px none #000; background:transparent; vertical-align:middle;}
.panel_wrapper div.current {height:80px;}
#width {width:50px; vertical-align:middle;}
#width2 {width:50px; vertical-align:middle;}
#size {width:100px;}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.AdvancedHRPlugin",{init:function(a,b){a.addCommand("mceAdvancedHr",function(){a.windowManager.open({file:b+"/rule.htm",width:250+parseInt(a.getLang("advhr.delta_width",0)),height:160+parseInt(a.getLang("advhr.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("advhr",{title:"advhr.advhr_desc",cmd:"mceAdvancedHr"});a.onNodeChange.add(function(d,c,e){c.setActive("advhr",e.nodeName=="HR")});a.onClick.add(function(c,d){d=d.target;if(d.nodeName==="HR"){c.selection.select(d)}})},getInfo:function(){return{longname:"Advanced HR",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advhr",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advhr",tinymce.plugins.AdvancedHRPlugin)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,43 @@
var AdvHRDialog = {
init : function(ed) {
var dom = ed.dom, f = document.forms[0], n = ed.selection.getNode(), w;
w = dom.getAttrib(n, 'width');
f.width.value = w ? parseInt(w) : (dom.getStyle('width') || '');
f.size.value = dom.getAttrib(n, 'size') || parseInt(dom.getStyle('height')) || '';
f.noshade.checked = !!dom.getAttrib(n, 'noshade') || !!dom.getStyle('border-width');
selectByValue(f, 'width2', w.indexOf('%') != -1 ? '%' : 'px');
},
update : function() {
var ed = tinyMCEPopup.editor, h, f = document.forms[0], st = '';
h = '<hr';
if (f.size.value) {
h += ' size="' + f.size.value + '"';
st += ' height:' + f.size.value + 'px;';
}
if (f.width.value) {
h += ' width="' + f.width.value + (f.width2.value == '%' ? '%' : '') + '"';
st += ' width:' + f.width.value + (f.width2.value == '%' ? '%' : 'px') + ';';
}
if (f.noshade.checked) {
h += ' noshade="noshade"';
st += ' border-width: 1px; border-style: solid; border-color: #CCCCCC; color: #ffffff;';
}
if (ed.settings.inline_styles)
h += ' style="' + tinymce.trim(st) + '"';
h += ' />';
ed.execCommand("mceInsertContent", false, h);
tinyMCEPopup.close();
}
};
tinyMCEPopup.requireLangPack();
tinyMCEPopup.onInit.add(AdvHRDialog.init, AdvHRDialog);

View File

@ -0,0 +1 @@
tinyMCE.addI18n('en.advhr_dlg',{size:"Height",noshade:"No Shadow",width:"Width",normal:"Normal",widthunits:"Units"});

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,58 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#advhr.advhr_desc}</title>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="js/rule.js"></script>
<script type="text/javascript" src="../../utils/mctabs.js"></script>
<script type="text/javascript" src="../../utils/form_utils.js"></script>
<link href="css/advhr.css" rel="stylesheet" type="text/css" />
</head>
<body role="application">
<form onsubmit="AdvHRDialog.update();return false;" action="#">
<div class="tabs">
<ul>
<li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advhr.advhr_desc}</a></span></li>
</ul>
</div>
<div class="panel_wrapper">
<div id="general_panel" class="panel current">
<table role="presentation" border="0" cellpadding="4" cellspacing="0">
<tr role="group" aria-labelledby="width_label">
<td><label id="width_label" for="width">{#advhr_dlg.width}</label></td>
<td class="nowrap">
<input id="width" name="width" type="text" value="" class="mceFocus" />
<span style="display:none;" id="width_unit_label">{#advhr_dlg.widthunits}</span>
<select name="width2" id="width2" aria-labelledby="width_unit_label">
<option value="">px</option>
<option value="%">%</option>
</select>
</td>
</tr>
<tr>
<td><label for="size">{#advhr_dlg.size}</label></td>
<td><select id="size" name="size">
<option value="">{#advhr_dlg.normal}</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td>
</tr>
<tr>
<td><label for="noshade">{#advhr_dlg.noshade}</label></td>
<td><input type="checkbox" name="noshade" id="noshade" class="radio" /></td>
</tr>
</table>
</div>
</div>
<div class="mceActionPanel">
<input type="submit" id="insert" name="insert" value="{#insert}" />
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,13 @@
#src_list, #over_list, #out_list {width:280px;}
.mceActionPanel {margin-top:7px;}
.alignPreview {border:1px solid #000; width:140px; height:140px; overflow:hidden; padding:5px;}
.checkbox {border:0;}
.panel_wrapper div.current {height:305px;}
#prev {margin:0; border:1px solid #000; width:428px; height:150px; overflow:auto;}
#align, #classlist {width:150px;}
#width, #height {vertical-align:middle; width:50px; text-align:center;}
#vspace, #hspace, #border {vertical-align:middle; width:30px; text-align:center;}
#class_list {width:180px;}
input {width: 280px;}
#constrain, #onmousemovecheck {width:auto;}
#id, #dir, #lang, #usemap, #longdesc {width:200px;}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.AdvancedImagePlugin",{init:function(a,b){a.addCommand("mceAdvImage",function(){if(a.dom.getAttrib(a.selection.getNode(),"class","").indexOf("mceItem")!=-1){return}a.windowManager.open({file:b+"/image.htm",width:480+parseInt(a.getLang("advimage.delta_width",0)),height:385+parseInt(a.getLang("advimage.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("image",{title:"advimage.image_desc",cmd:"mceAdvImage"})},getInfo:function(){return{longname:"Advanced image",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advimage",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advimage",tinymce.plugins.AdvancedImagePlugin)})();

View File

@ -0,0 +1,235 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#advimage_dlg.dialog_title}</title>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="../../utils/mctabs.js"></script>
<script type="text/javascript" src="../../utils/form_utils.js"></script>
<script type="text/javascript" src="../../utils/validate.js"></script>
<script type="text/javascript" src="../../utils/editable_selects.js"></script>
<script type="text/javascript" src="js/image.js"></script>
<link href="css/advimage.css" rel="stylesheet" type="text/css" />
</head>
<body id="advimage" style="display: none" role="application" aria-labelledby="app_title">
<span id="app_title" style="display:none">{#advimage_dlg.dialog_title}</span>
<form onsubmit="ImageDialog.insert();return false;" action="#">
<div class="tabs">
<ul>
<li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advimage_dlg.tab_general}</a></span></li>
<li id="appearance_tab" aria-controls="appearance_panel"><span><a href="javascript:mcTabs.displayTab('appearance_tab','appearance_panel');" onmousedown="return false;">{#advimage_dlg.tab_appearance}</a></span></li>
<li id="advanced_tab" aria-controls="advanced_panel"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#advimage_dlg.tab_advanced}</a></span></li>
</ul>
</div>
<div class="panel_wrapper">
<div id="general_panel" class="panel current">
<fieldset>
<legend>{#advimage_dlg.general}</legend>
<table role="presentation" class="properties">
<tr>
<td class="column1"><label id="srclabel" for="src">{#advimage_dlg.src}</label></td>
<td colspan="2"><table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><input name="src" type="text" id="src" value="" class="mceFocus" onchange="ImageDialog.showPreviewImage(this.value);" aria-required="true" /></td>
<td id="srcbrowsercontainer">&nbsp;</td>
</tr>
</table></td>
</tr>
<tr>
<td><label for="src_list">{#advimage_dlg.image_list}</label></td>
<td><select id="src_list" name="src_list" onchange="document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;document.getElementById('title').value=this.options[this.selectedIndex].text;ImageDialog.showPreviewImage(this.options[this.selectedIndex].value);"><option value=""></option></select></td>
</tr>
<tr>
<td class="column1"><label id="altlabel" for="alt">{#advimage_dlg.alt}</label></td>
<td colspan="2"><input id="alt" name="alt" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label id="titlelabel" for="title">{#advimage_dlg.title}</label></td>
<td colspan="2"><input id="title" name="title" type="text" value="" /></td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>{#advimage_dlg.preview}</legend>
<div id="prev"></div>
</fieldset>
</div>
<div id="appearance_panel" class="panel">
<fieldset>
<legend>{#advimage_dlg.tab_appearance}</legend>
<table role="presentation" border="0" cellpadding="4" cellspacing="0">
<tr>
<td class="column1"><label id="alignlabel" for="align">{#advimage_dlg.align}</label></td>
<td><select id="align" name="align" onchange="ImageDialog.updateStyle('align');ImageDialog.changeAppearance();">
<option value="">{#not_set}</option>
<option value="baseline">{#advimage_dlg.align_baseline}</option>
<option value="top">{#advimage_dlg.align_top}</option>
<option value="middle">{#advimage_dlg.align_middle}</option>
<option value="bottom">{#advimage_dlg.align_bottom}</option>
<option value="text-top">{#advimage_dlg.align_texttop}</option>
<option value="text-bottom">{#advimage_dlg.align_textbottom}</option>
<option value="left">{#advimage_dlg.align_left}</option>
<option value="right">{#advimage_dlg.align_right}</option>
</select>
</td>
<td rowspan="6" valign="top">
<div class="alignPreview">
<img id="alignSampleImg" src="img/sample.gif" alt="{#advimage_dlg.example_img}" />
Lorem ipsum, Dolor sit amet, consectetuer adipiscing loreum ipsum edipiscing elit, sed diam
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.Loreum ipsum
edipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam
erat volutpat.
</div>
</td>
</tr>
<tr role="group" aria-labelledby="widthlabel">
<td class="column1"><label id="widthlabel" for="width">{#advimage_dlg.dimensions}</label></td>
<td class="nowrap">
<span style="display:none" id="width_voiceLabel">{#advimage_dlg.width}</span>
<input name="width" type="text" id="width" value="" size="5" maxlength="5" class="size" onchange="ImageDialog.changeHeight();" aria-labelledby="width_voiceLabel" /> x
<span style="display:none" id="height_voiceLabel">{#advimage_dlg.height}</span>
<input name="height" type="text" id="height" value="" size="5" maxlength="5" class="size" onchange="ImageDialog.changeWidth();" aria-labelledby="height_voiceLabel" /> px
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><input id="constrain" type="checkbox" name="constrain" class="checkbox" /></td>
<td><label id="constrainlabel" for="constrain">{#advimage_dlg.constrain_proportions}</label></td>
</tr>
</table></td>
</tr>
<tr>
<td class="column1"><label id="vspacelabel" for="vspace">{#advimage_dlg.vspace}</label></td>
<td><input name="vspace" type="text" id="vspace" value="" size="3" maxlength="3" class="number" onchange="ImageDialog.updateStyle('vspace');ImageDialog.changeAppearance();" onblur="ImageDialog.updateStyle('vspace');ImageDialog.changeAppearance();" />
</td>
</tr>
<tr>
<td class="column1"><label id="hspacelabel" for="hspace">{#advimage_dlg.hspace}</label></td>
<td><input name="hspace" type="text" id="hspace" value="" size="3" maxlength="3" class="number" onchange="ImageDialog.updateStyle('hspace');ImageDialog.changeAppearance();" onblur="ImageDialog.updateStyle('hspace');ImageDialog.changeAppearance();" /></td>
</tr>
<tr>
<td class="column1"><label id="borderlabel" for="border">{#advimage_dlg.border}</label></td>
<td><input id="border" name="border" type="text" value="" size="3" maxlength="3" class="number" onchange="ImageDialog.updateStyle('border');ImageDialog.changeAppearance();" onblur="ImageDialog.updateStyle('border');ImageDialog.changeAppearance();" /></td>
</tr>
<tr>
<td><label for="class_list">{#class_name}</label></td>
<td colspan="2"><select id="class_list" name="class_list" class="mceEditableSelect"><option value=""></option></select></td>
</tr>
<tr>
<td class="column1"><label id="stylelabel" for="style">{#advimage_dlg.style}</label></td>
<td colspan="2"><input id="style" name="style" type="text" value="" onchange="ImageDialog.changeAppearance();" /></td>
</tr>
<!-- <tr>
<td class="column1"><label id="classeslabel" for="classes">{#advimage_dlg.classes}</label></td>
<td colspan="2"><input id="classes" name="classes" type="text" value="" onchange="selectByValue(this.form,'classlist',this.value,true);" /></td>
</tr> -->
</table>
</fieldset>
</div>
<div id="advanced_panel" class="panel">
<fieldset>
<legend>{#advimage_dlg.swap_image}</legend>
<input type="checkbox" id="onmousemovecheck" name="onmousemovecheck" class="checkbox" onclick="ImageDialog.setSwapImage(this.checked);" aria-controls="onmouseoversrc onmouseoutsrc" />
<label id="onmousemovechecklabel" for="onmousemovecheck">{#advimage_dlg.alt_image}</label>
<table role="presentation" border="0" cellpadding="4" cellspacing="0" width="100%">
<tr>
<td class="column1"><label id="onmouseoversrclabel" for="onmouseoversrc">{#advimage_dlg.mouseover}</label></td>
<td><table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><input id="onmouseoversrc" name="onmouseoversrc" type="text" value="" /></td>
<td id="onmouseoversrccontainer">&nbsp;</td>
</tr>
</table></td>
</tr>
<tr>
<td><label for="over_list">{#advimage_dlg.image_list}</label></td>
<td><select id="over_list" name="over_list" onchange="document.getElementById('onmouseoversrc').value=this.options[this.selectedIndex].value;"><option value=""></option></select></td>
</tr>
<tr>
<td class="column1"><label id="onmouseoutsrclabel" for="onmouseoutsrc">{#advimage_dlg.mouseout}</label></td>
<td class="column2"><table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><input id="onmouseoutsrc" name="onmouseoutsrc" type="text" value="" /></td>
<td id="onmouseoutsrccontainer">&nbsp;</td>
</tr>
</table></td>
</tr>
<tr>
<td><label for="out_list">{#advimage_dlg.image_list}</label></td>
<td><select id="out_list" name="out_list" onchange="document.getElementById('onmouseoutsrc').value=this.options[this.selectedIndex].value;"><option value=""></option></select></td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>{#advimage_dlg.misc}</legend>
<table role="presentation" border="0" cellpadding="4" cellspacing="0">
<tr>
<td class="column1"><label id="idlabel" for="id">{#advimage_dlg.id}</label></td>
<td><input id="id" name="id" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label id="dirlabel" for="dir">{#advimage_dlg.langdir}</label></td>
<td>
<select id="dir" name="dir" onchange="ImageDialog.changeAppearance();">
<option value="">{#not_set}</option>
<option value="ltr">{#advimage_dlg.ltr}</option>
<option value="rtl">{#advimage_dlg.rtl}</option>
</select>
</td>
</tr>
<tr>
<td class="column1"><label id="langlabel" for="lang">{#advimage_dlg.langcode}</label></td>
<td>
<input id="lang" name="lang" type="text" value="" />
</td>
</tr>
<tr>
<td class="column1"><label id="usemaplabel" for="usemap">{#advimage_dlg.map}</label></td>
<td>
<input id="usemap" name="usemap" type="text" value="" />
</td>
</tr>
<tr>
<td class="column1"><label id="longdesclabel" for="longdesc">{#advimage_dlg.long_desc}</label></td>
<td><table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><input id="longdesc" name="longdesc" type="text" value="" /></td>
<td id="longdesccontainer">&nbsp;</td>
</tr>
</table></td>
</tr>
</table>
</fieldset>
</div>
</div>
<div class="mceActionPanel">
<input type="submit" id="insert" name="insert" value="{#insert}" />
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,464 @@
var ImageDialog = {
preInit : function() {
var url;
tinyMCEPopup.requireLangPack();
if (url = tinyMCEPopup.getParam("external_image_list_url"))
document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');
},
init : function(ed) {
var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, dom = ed.dom, n = ed.selection.getNode(), fl = tinyMCEPopup.getParam('external_image_list', 'tinyMCEImageList');
tinyMCEPopup.resizeToInnerSize();
this.fillClassList('class_list');
this.fillFileList('src_list', fl);
this.fillFileList('over_list', fl);
this.fillFileList('out_list', fl);
TinyMCE_EditableSelects.init();
if (n.nodeName == 'IMG') {
nl.src.value = dom.getAttrib(n, 'src');
nl.width.value = dom.getAttrib(n, 'width');
nl.height.value = dom.getAttrib(n, 'height');
nl.alt.value = dom.getAttrib(n, 'alt');
nl.title.value = dom.getAttrib(n, 'title');
nl.vspace.value = this.getAttrib(n, 'vspace');
nl.hspace.value = this.getAttrib(n, 'hspace');
nl.border.value = this.getAttrib(n, 'border');
selectByValue(f, 'align', this.getAttrib(n, 'align'));
selectByValue(f, 'class_list', dom.getAttrib(n, 'class'), true, true);
nl.style.value = dom.getAttrib(n, 'style');
nl.id.value = dom.getAttrib(n, 'id');
nl.dir.value = dom.getAttrib(n, 'dir');
nl.lang.value = dom.getAttrib(n, 'lang');
nl.usemap.value = dom.getAttrib(n, 'usemap');
nl.longdesc.value = dom.getAttrib(n, 'longdesc');
nl.insert.value = ed.getLang('update');
if (/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/.test(dom.getAttrib(n, 'onmouseover')))
nl.onmouseoversrc.value = dom.getAttrib(n, 'onmouseover').replace(/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/, '$1');
if (/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/.test(dom.getAttrib(n, 'onmouseout')))
nl.onmouseoutsrc.value = dom.getAttrib(n, 'onmouseout').replace(/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/, '$1');
if (ed.settings.inline_styles) {
// Move attribs to styles
if (dom.getAttrib(n, 'align'))
this.updateStyle('align');
if (dom.getAttrib(n, 'hspace'))
this.updateStyle('hspace');
if (dom.getAttrib(n, 'border'))
this.updateStyle('border');
if (dom.getAttrib(n, 'vspace'))
this.updateStyle('vspace');
}
}
// Setup browse button
document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image');
if (isVisible('srcbrowser'))
document.getElementById('src').style.width = '260px';
// Setup browse button
document.getElementById('onmouseoversrccontainer').innerHTML = getBrowserHTML('overbrowser','onmouseoversrc','image','theme_advanced_image');
if (isVisible('overbrowser'))
document.getElementById('onmouseoversrc').style.width = '260px';
// Setup browse button
document.getElementById('onmouseoutsrccontainer').innerHTML = getBrowserHTML('outbrowser','onmouseoutsrc','image','theme_advanced_image');
if (isVisible('outbrowser'))
document.getElementById('onmouseoutsrc').style.width = '260px';
// If option enabled default contrain proportions to checked
if (ed.getParam("advimage_constrain_proportions", true))
f.constrain.checked = true;
// Check swap image if valid data
if (nl.onmouseoversrc.value || nl.onmouseoutsrc.value)
this.setSwapImage(true);
else
this.setSwapImage(false);
this.changeAppearance();
this.showPreviewImage(nl.src.value, 1);
},
insert : function(file, title) {
var ed = tinyMCEPopup.editor, t = this, f = document.forms[0];
if (f.src.value === '') {
if (ed.selection.getNode().nodeName == 'IMG') {
ed.dom.remove(ed.selection.getNode());
ed.execCommand('mceRepaint');
}
tinyMCEPopup.close();
return;
}
if (tinyMCEPopup.getParam("accessibility_warnings", 1)) {
if (!f.alt.value) {
tinyMCEPopup.confirm(tinyMCEPopup.getLang('advimage_dlg.missing_alt'), function(s) {
if (s)
t.insertAndClose();
});
return;
}
}
t.insertAndClose();
},
insertAndClose : function() {
var ed = tinyMCEPopup.editor, f = document.forms[0], nl = f.elements, v, args = {}, el;
tinyMCEPopup.restoreSelection();
// Fixes crash in Safari
if (tinymce.isWebKit)
ed.getWin().focus();
if (!ed.settings.inline_styles) {
args = {
vspace : nl.vspace.value,
hspace : nl.hspace.value,
border : nl.border.value,
align : getSelectValue(f, 'align')
};
} else {
// Remove deprecated values
args = {
vspace : '',
hspace : '',
border : '',
align : ''
};
}
tinymce.extend(args, {
src : nl.src.value.replace(/ /g, '%20'),
width : nl.width.value,
height : nl.height.value,
alt : nl.alt.value,
title : nl.title.value,
'class' : getSelectValue(f, 'class_list'),
style : nl.style.value,
id : nl.id.value,
dir : nl.dir.value,
lang : nl.lang.value,
usemap : nl.usemap.value,
longdesc : nl.longdesc.value
});
args.onmouseover = args.onmouseout = '';
if (f.onmousemovecheck.checked) {
if (nl.onmouseoversrc.value)
args.onmouseover = "this.src='" + nl.onmouseoversrc.value + "';";
if (nl.onmouseoutsrc.value)
args.onmouseout = "this.src='" + nl.onmouseoutsrc.value + "';";
}
el = ed.selection.getNode();
if (el && el.nodeName == 'IMG') {
ed.dom.setAttribs(el, args);
} else {
tinymce.each(args, function(value, name) {
if (value === "") {
delete args[name];
}
});
ed.execCommand('mceInsertContent', false, tinyMCEPopup.editor.dom.createHTML('img', args), {skip_undo : 1});
ed.undoManager.add();
}
tinyMCEPopup.editor.execCommand('mceRepaint');
tinyMCEPopup.editor.focus();
tinyMCEPopup.close();
},
getAttrib : function(e, at) {
var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2;
if (ed.settings.inline_styles) {
switch (at) {
case 'align':
if (v = dom.getStyle(e, 'float'))
return v;
if (v = dom.getStyle(e, 'vertical-align'))
return v;
break;
case 'hspace':
v = dom.getStyle(e, 'margin-left')
v2 = dom.getStyle(e, 'margin-right');
if (v && v == v2)
return parseInt(v.replace(/[^0-9]/g, ''));
break;
case 'vspace':
v = dom.getStyle(e, 'margin-top')
v2 = dom.getStyle(e, 'margin-bottom');
if (v && v == v2)
return parseInt(v.replace(/[^0-9]/g, ''));
break;
case 'border':
v = 0;
tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) {
sv = dom.getStyle(e, 'border-' + sv + '-width');
// False or not the same as prev
if (!sv || (sv != v && v !== 0)) {
v = 0;
return false;
}
if (sv)
v = sv;
});
if (v)
return parseInt(v.replace(/[^0-9]/g, ''));
break;
}
}
if (v = dom.getAttrib(e, at))
return v;
return '';
},
setSwapImage : function(st) {
var f = document.forms[0];
f.onmousemovecheck.checked = st;
setBrowserDisabled('overbrowser', !st);
setBrowserDisabled('outbrowser', !st);
if (f.over_list)
f.over_list.disabled = !st;
if (f.out_list)
f.out_list.disabled = !st;
f.onmouseoversrc.disabled = !st;
f.onmouseoutsrc.disabled = !st;
},
fillClassList : function(id) {
var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl;
if (v = tinyMCEPopup.getParam('theme_advanced_styles')) {
cl = [];
tinymce.each(v.split(';'), function(v) {
var p = v.split('=');
cl.push({'title' : p[0], 'class' : p[1]});
});
} else
cl = tinyMCEPopup.editor.dom.getClasses();
if (cl.length > 0) {
lst.options.length = 0;
lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), '');
tinymce.each(cl, function(o) {
lst.options[lst.options.length] = new Option(o.title || o['class'], o['class']);
});
} else
dom.remove(dom.getParent(id, 'tr'));
},
fillFileList : function(id, l) {
var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl;
l = typeof(l) === 'function' ? l() : window[l];
lst.options.length = 0;
if (l && l.length > 0) {
lst.options[lst.options.length] = new Option('', '');
tinymce.each(l, function(o) {
lst.options[lst.options.length] = new Option(o[0], o[1]);
});
} else
dom.remove(dom.getParent(id, 'tr'));
},
resetImageData : function() {
var f = document.forms[0];
f.elements.width.value = f.elements.height.value = '';
},
updateImageData : function(img, st) {
var f = document.forms[0];
if (!st) {
f.elements.width.value = img.width;
f.elements.height.value = img.height;
}
this.preloadImg = img;
},
changeAppearance : function() {
var ed = tinyMCEPopup.editor, f = document.forms[0], img = document.getElementById('alignSampleImg');
if (img) {
if (ed.getParam('inline_styles')) {
ed.dom.setAttrib(img, 'style', f.style.value);
} else {
img.align = f.align.value;
img.border = f.border.value;
img.hspace = f.hspace.value;
img.vspace = f.vspace.value;
}
}
},
changeHeight : function() {
var f = document.forms[0], tp, t = this;
if (!f.constrain.checked || !t.preloadImg) {
return;
}
if (f.width.value == "" || f.height.value == "")
return;
tp = (parseInt(f.width.value) / parseInt(t.preloadImg.width)) * t.preloadImg.height;
f.height.value = tp.toFixed(0);
},
changeWidth : function() {
var f = document.forms[0], tp, t = this;
if (!f.constrain.checked || !t.preloadImg) {
return;
}
if (f.width.value == "" || f.height.value == "")
return;
tp = (parseInt(f.height.value) / parseInt(t.preloadImg.height)) * t.preloadImg.width;
f.width.value = tp.toFixed(0);
},
updateStyle : function(ty) {
var dom = tinyMCEPopup.dom, b, bStyle, bColor, v, isIE = tinymce.isIE, f = document.forms[0], img = dom.create('img', {style : dom.get('style').value});
if (tinyMCEPopup.editor.settings.inline_styles) {
// Handle align
if (ty == 'align') {
dom.setStyle(img, 'float', '');
dom.setStyle(img, 'vertical-align', '');
v = getSelectValue(f, 'align');
if (v) {
if (v == 'left' || v == 'right')
dom.setStyle(img, 'float', v);
else
img.style.verticalAlign = v;
}
}
// Handle border
if (ty == 'border') {
b = img.style.border ? img.style.border.split(' ') : [];
bStyle = dom.getStyle(img, 'border-style');
bColor = dom.getStyle(img, 'border-color');
dom.setStyle(img, 'border', '');
v = f.border.value;
if (v || v == '0') {
if (v == '0')
img.style.border = isIE ? '0' : '0 none none';
else {
var isOldIE = tinymce.isIE && (!document.documentMode || document.documentMode < 9);
if (b.length == 3 && b[isOldIE ? 2 : 1])
bStyle = b[isOldIE ? 2 : 1];
else if (!bStyle || bStyle == 'none')
bStyle = 'solid';
if (b.length == 3 && b[isIE ? 0 : 2])
bColor = b[isOldIE ? 0 : 2];
else if (!bColor || bColor == 'none')
bColor = 'black';
img.style.border = v + 'px ' + bStyle + ' ' + bColor;
}
}
}
// Handle hspace
if (ty == 'hspace') {
dom.setStyle(img, 'marginLeft', '');
dom.setStyle(img, 'marginRight', '');
v = f.hspace.value;
if (v) {
img.style.marginLeft = v + 'px';
img.style.marginRight = v + 'px';
}
}
// Handle vspace
if (ty == 'vspace') {
dom.setStyle(img, 'marginTop', '');
dom.setStyle(img, 'marginBottom', '');
v = f.vspace.value;
if (v) {
img.style.marginTop = v + 'px';
img.style.marginBottom = v + 'px';
}
}
// Merge
dom.get('style').value = dom.serializeStyle(dom.parseStyle(img.style.cssText), 'img');
}
},
changeMouseMove : function() {
},
showPreviewImage : function(u, st) {
if (!u) {
tinyMCEPopup.dom.setHTML('prev', '');
return;
}
if (!st && tinyMCEPopup.getParam("advimage_update_dimensions_onchange", true))
this.resetImageData();
u = tinyMCEPopup.editor.documentBaseURI.toAbsolute(u);
if (!st)
tinyMCEPopup.dom.setHTML('prev', '<img id="previewImg" src="' + u + '" border="0" onload="ImageDialog.updateImageData(this);" onerror="ImageDialog.resetImageData();" />');
else
tinyMCEPopup.dom.setHTML('prev', '<img id="previewImg" src="' + u + '" border="0" onload="ImageDialog.updateImageData(this, 1);" />');
}
};
ImageDialog.preInit();
tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog);

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
tinyMCE.addI18n('en.advimage_dlg',{"image_list":"Image List","align_right":"Right","align_left":"Left","align_textbottom":"Text Bottom","align_texttop":"Text Top","align_bottom":"Bottom","align_middle":"Middle","align_top":"Top","align_baseline":"Baseline",align:"Alignment",hspace:"Horizontal Space",vspace:"Vertical Space",dimensions:"Dimensions",border:"Border",list:"Image List",alt:"Image Description",src:"Image URL","dialog_title":"Insert/Edit Image","missing_alt":"Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.","example_img":"Appearance Preview Image",misc:"Miscellaneous",mouseout:"For Mouse Out",mouseover:"For Mouse Over","alt_image":"Alternative Image","swap_image":"Swap Image",map:"Image Map",id:"ID",rtl:"Right to Left",ltr:"Left to Right",classes:"Classes",style:"Style","long_desc":"Long Description Link",langcode:"Language Code",langdir:"Language Direction","constrain_proportions":"Constrain Proportions",preview:"Preview",title:"Title",general:"General","tab_advanced":"Advanced","tab_appearance":"Appearance","tab_general":"General",width:"Width",height:"Height"});

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,8 @@
.mceLinkList, .mceAnchorList, #targetlist {width:280px;}
.mceActionPanel {margin-top:7px;}
.panel_wrapper div.current {height:320px;}
#classlist, #title, #href {width:280px;}
#popupurl, #popupname {width:200px;}
#popupwidth, #popupheight, #popupleft, #popuptop {width:30px;vertical-align:middle;text-align:center;}
#id, #style, #classes, #target, #dir, #hreflang, #lang, #charset, #type, #rel, #rev, #tabindex, #accesskey {width:200px;}
#events_panel input {width:200px;}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.AdvancedLinkPlugin",{init:function(a,b){this.editor=a;a.addCommand("mceAdvLink",function(){var c=a.selection;if(c.isCollapsed()&&!a.dom.getParent(c.getNode(),"A")){return}a.windowManager.open({file:b+"/link.htm",width:480+parseInt(a.getLang("advlink.delta_width",0)),height:400+parseInt(a.getLang("advlink.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("link",{title:"advlink.link_desc",cmd:"mceAdvLink"});a.addShortcut("ctrl+k","advlink.advlink_desc","mceAdvLink");a.onNodeChange.add(function(d,c,f,e){c.setDisabled("link",e&&f.nodeName!="A");c.setActive("link",f.nodeName=="A"&&!f.name)})},getInfo:function(){return{longname:"Advanced link",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advlink",tinymce.plugins.AdvancedLinkPlugin)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,539 @@
/* Functions for the advlink plugin popup */
tinyMCEPopup.requireLangPack();
var templates = {
"window.open" : "window.open('${url}','${target}','${options}')"
};
function preinit() {
var url;
if (url = tinyMCEPopup.getParam("external_link_list_url"))
document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');
}
function changeClass() {
var f = document.forms[0];
f.classes.value = getSelectValue(f, 'classlist');
}
function init() {
tinyMCEPopup.resizeToInnerSize();
var formObj = document.forms[0];
var inst = tinyMCEPopup.editor;
var elm = inst.selection.getNode();
var action = "insert";
var html;
document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','advlink');
document.getElementById('popupurlbrowsercontainer').innerHTML = getBrowserHTML('popupurlbrowser','popupurl','file','advlink');
document.getElementById('targetlistcontainer').innerHTML = getTargetListHTML('targetlist','target');
// Link list
html = getLinkListHTML('linklisthref','href');
if (html == "")
document.getElementById("linklisthrefrow").style.display = 'none';
else
document.getElementById("linklisthrefcontainer").innerHTML = html;
// Anchor list
html = getAnchorListHTML('anchorlist','href');
if (html == "")
document.getElementById("anchorlistrow").style.display = 'none';
else
document.getElementById("anchorlistcontainer").innerHTML = html;
// Resize some elements
if (isVisible('hrefbrowser'))
document.getElementById('href').style.width = '260px';
if (isVisible('popupurlbrowser'))
document.getElementById('popupurl').style.width = '180px';
elm = inst.dom.getParent(elm, "A");
if (elm == null) {
var prospect = inst.dom.create("p", null, inst.selection.getContent());
if (prospect.childNodes.length === 1) {
elm = prospect.firstChild;
}
}
if (elm != null && elm.nodeName == "A")
action = "update";
formObj.insert.value = tinyMCEPopup.getLang(action, 'Insert', true);
setPopupControlsDisabled(true);
if (action == "update") {
var href = inst.dom.getAttrib(elm, 'href');
var onclick = inst.dom.getAttrib(elm, 'onclick');
// Setup form data
setFormValue('href', href);
setFormValue('title', inst.dom.getAttrib(elm, 'title'));
setFormValue('id', inst.dom.getAttrib(elm, 'id'));
setFormValue('style', inst.dom.getAttrib(elm, "style"));
setFormValue('rel', inst.dom.getAttrib(elm, 'rel'));
setFormValue('rev', inst.dom.getAttrib(elm, 'rev'));
setFormValue('charset', inst.dom.getAttrib(elm, 'charset'));
setFormValue('hreflang', inst.dom.getAttrib(elm, 'hreflang'));
setFormValue('dir', inst.dom.getAttrib(elm, 'dir'));
setFormValue('lang', inst.dom.getAttrib(elm, 'lang'));
setFormValue('tabindex', inst.dom.getAttrib(elm, 'tabindex', typeof(elm.tabindex) != "undefined" ? elm.tabindex : ""));
setFormValue('accesskey', inst.dom.getAttrib(elm, 'accesskey', typeof(elm.accesskey) != "undefined" ? elm.accesskey : ""));
setFormValue('type', inst.dom.getAttrib(elm, 'type'));
setFormValue('onfocus', inst.dom.getAttrib(elm, 'onfocus'));
setFormValue('onblur', inst.dom.getAttrib(elm, 'onblur'));
setFormValue('onclick', onclick);
setFormValue('ondblclick', inst.dom.getAttrib(elm, 'ondblclick'));
setFormValue('onmousedown', inst.dom.getAttrib(elm, 'onmousedown'));
setFormValue('onmouseup', inst.dom.getAttrib(elm, 'onmouseup'));
setFormValue('onmouseover', inst.dom.getAttrib(elm, 'onmouseover'));
setFormValue('onmousemove', inst.dom.getAttrib(elm, 'onmousemove'));
setFormValue('onmouseout', inst.dom.getAttrib(elm, 'onmouseout'));
setFormValue('onkeypress', inst.dom.getAttrib(elm, 'onkeypress'));
setFormValue('onkeydown', inst.dom.getAttrib(elm, 'onkeydown'));
setFormValue('onkeyup', inst.dom.getAttrib(elm, 'onkeyup'));
setFormValue('target', inst.dom.getAttrib(elm, 'target'));
setFormValue('classes', inst.dom.getAttrib(elm, 'class'));
// Parse onclick data
if (onclick != null && onclick.indexOf('window.open') != -1)
parseWindowOpen(onclick);
else
parseFunction(onclick);
// Select by the values
selectByValue(formObj, 'dir', inst.dom.getAttrib(elm, 'dir'));
selectByValue(formObj, 'rel', inst.dom.getAttrib(elm, 'rel'));
selectByValue(formObj, 'rev', inst.dom.getAttrib(elm, 'rev'));
selectByValue(formObj, 'linklisthref', href);
if (href.charAt(0) == '#')
selectByValue(formObj, 'anchorlist', href);
addClassesToList('classlist', 'advlink_styles');
selectByValue(formObj, 'classlist', inst.dom.getAttrib(elm, 'class'), true);
selectByValue(formObj, 'targetlist', inst.dom.getAttrib(elm, 'target'), true);
} else
addClassesToList('classlist', 'advlink_styles');
}
function checkPrefix(n) {
if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_email')))
n.value = 'mailto:' + n.value;
if (/^\s*www\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_external')))
n.value = 'http://' + n.value;
}
function setFormValue(name, value) {
document.forms[0].elements[name].value = value;
}
function parseWindowOpen(onclick) {
var formObj = document.forms[0];
// Preprocess center code
if (onclick.indexOf('return false;') != -1) {
formObj.popupreturn.checked = true;
onclick = onclick.replace('return false;', '');
} else
formObj.popupreturn.checked = false;
var onClickData = parseLink(onclick);
if (onClickData != null) {
formObj.ispopup.checked = true;
setPopupControlsDisabled(false);
var onClickWindowOptions = parseOptions(onClickData['options']);
var url = onClickData['url'];
formObj.popupname.value = onClickData['target'];
formObj.popupurl.value = url;
formObj.popupwidth.value = getOption(onClickWindowOptions, 'width');
formObj.popupheight.value = getOption(onClickWindowOptions, 'height');
formObj.popupleft.value = getOption(onClickWindowOptions, 'left');
formObj.popuptop.value = getOption(onClickWindowOptions, 'top');
if (formObj.popupleft.value.indexOf('screen') != -1)
formObj.popupleft.value = "c";
if (formObj.popuptop.value.indexOf('screen') != -1)
formObj.popuptop.value = "c";
formObj.popuplocation.checked = getOption(onClickWindowOptions, 'location') == "yes";
formObj.popupscrollbars.checked = getOption(onClickWindowOptions, 'scrollbars') == "yes";
formObj.popupmenubar.checked = getOption(onClickWindowOptions, 'menubar') == "yes";
formObj.popupresizable.checked = getOption(onClickWindowOptions, 'resizable') == "yes";
formObj.popuptoolbar.checked = getOption(onClickWindowOptions, 'toolbar') == "yes";
formObj.popupstatus.checked = getOption(onClickWindowOptions, 'status') == "yes";
formObj.popupdependent.checked = getOption(onClickWindowOptions, 'dependent') == "yes";
buildOnClick();
}
}
function parseFunction(onclick) {
var formObj = document.forms[0];
var onClickData = parseLink(onclick);
// TODO: Add stuff here
}
function getOption(opts, name) {
return typeof(opts[name]) == "undefined" ? "" : opts[name];
}
function setPopupControlsDisabled(state) {
var formObj = document.forms[0];
formObj.popupname.disabled = state;
formObj.popupurl.disabled = state;
formObj.popupwidth.disabled = state;
formObj.popupheight.disabled = state;
formObj.popupleft.disabled = state;
formObj.popuptop.disabled = state;
formObj.popuplocation.disabled = state;
formObj.popupscrollbars.disabled = state;
formObj.popupmenubar.disabled = state;
formObj.popupresizable.disabled = state;
formObj.popuptoolbar.disabled = state;
formObj.popupstatus.disabled = state;
formObj.popupreturn.disabled = state;
formObj.popupdependent.disabled = state;
setBrowserDisabled('popupurlbrowser', state);
}
function parseLink(link) {
link = link.replace(new RegExp('&#39;', 'g'), "'");
var fnName = link.replace(new RegExp("\\s*([A-Za-z0-9\.]*)\\s*\\(.*", "gi"), "$1");
// Is function name a template function
var template = templates[fnName];
if (template) {
// Build regexp
var variableNames = template.match(new RegExp("'?\\$\\{[A-Za-z0-9\.]*\\}'?", "gi"));
var regExp = "\\s*[A-Za-z0-9\.]*\\s*\\(";
var replaceStr = "";
for (var i=0; i<variableNames.length; i++) {
// Is string value
if (variableNames[i].indexOf("'${") != -1)
regExp += "'(.*)'";
else // Number value
regExp += "([0-9]*)";
replaceStr += "$" + (i+1);
// Cleanup variable name
variableNames[i] = variableNames[i].replace(new RegExp("[^A-Za-z0-9]", "gi"), "");
if (i != variableNames.length-1) {
regExp += "\\s*,\\s*";
replaceStr += "<delim>";
} else
regExp += ".*";
}
regExp += "\\);?";
// Build variable array
var variables = [];
variables["_function"] = fnName;
var variableValues = link.replace(new RegExp(regExp, "gi"), replaceStr).split('<delim>');
for (var i=0; i<variableNames.length; i++)
variables[variableNames[i]] = variableValues[i];
return variables;
}
return null;
}
function parseOptions(opts) {
if (opts == null || opts == "")
return [];
// Cleanup the options
opts = opts.toLowerCase();
opts = opts.replace(/;/g, ",");
opts = opts.replace(/[^0-9a-z=,]/g, "");
var optionChunks = opts.split(',');
var options = [];
for (var i=0; i<optionChunks.length; i++) {
var parts = optionChunks[i].split('=');
if (parts.length == 2)
options[parts[0]] = parts[1];
}
return options;
}
function buildOnClick() {
var formObj = document.forms[0];
if (!formObj.ispopup.checked) {
formObj.onclick.value = "";
return;
}
var onclick = "window.open('";
var url = formObj.popupurl.value;
onclick += url + "','";
onclick += formObj.popupname.value + "','";
if (formObj.popuplocation.checked)
onclick += "location=yes,";
if (formObj.popupscrollbars.checked)
onclick += "scrollbars=yes,";
if (formObj.popupmenubar.checked)
onclick += "menubar=yes,";
if (formObj.popupresizable.checked)
onclick += "resizable=yes,";
if (formObj.popuptoolbar.checked)
onclick += "toolbar=yes,";
if (formObj.popupstatus.checked)
onclick += "status=yes,";
if (formObj.popupdependent.checked)
onclick += "dependent=yes,";
if (formObj.popupwidth.value != "")
onclick += "width=" + formObj.popupwidth.value + ",";
if (formObj.popupheight.value != "")
onclick += "height=" + formObj.popupheight.value + ",";
if (formObj.popupleft.value != "") {
if (formObj.popupleft.value != "c")
onclick += "left=" + formObj.popupleft.value + ",";
else
onclick += "left='+(screen.availWidth/2-" + (formObj.popupwidth.value/2) + ")+',";
}
if (formObj.popuptop.value != "") {
if (formObj.popuptop.value != "c")
onclick += "top=" + formObj.popuptop.value + ",";
else
onclick += "top='+(screen.availHeight/2-" + (formObj.popupheight.value/2) + ")+',";
}
if (onclick.charAt(onclick.length-1) == ',')
onclick = onclick.substring(0, onclick.length-1);
onclick += "');";
if (formObj.popupreturn.checked)
onclick += "return false;";
// tinyMCE.debug(onclick);
formObj.onclick.value = onclick;
if (formObj.href.value == "")
formObj.href.value = url;
}
function setAttrib(elm, attrib, value) {
var formObj = document.forms[0];
var valueElm = formObj.elements[attrib.toLowerCase()];
var dom = tinyMCEPopup.editor.dom;
if (typeof(value) == "undefined" || value == null) {
value = "";
if (valueElm)
value = valueElm.value;
}
// Clean up the style
if (attrib == 'style')
value = dom.serializeStyle(dom.parseStyle(value), 'a');
dom.setAttrib(elm, attrib, value);
}
function getAnchorListHTML(id, target) {
var ed = tinyMCEPopup.editor, nodes = ed.dom.select('a'), name, i, len, html = "";
for (i=0, len=nodes.length; i<len; i++) {
if ((name = ed.dom.getAttrib(nodes[i], "name")) != "")
html += '<option value="#' + name + '">' + name + '</option>';
}
if (html == "")
return "";
html = '<select id="' + id + '" name="' + id + '" class="mceAnchorList"'
+ ' onchange="this.form.' + target + '.value=this.options[this.selectedIndex].value"'
+ '>'
+ '<option value="">---</option>'
+ html
+ '</select>';
return html;
}
function insertAction() {
var inst = tinyMCEPopup.editor;
var elm, elementArray, i;
elm = inst.selection.getNode();
checkPrefix(document.forms[0].href);
elm = inst.dom.getParent(elm, "A");
// Remove element if there is no href
if (!document.forms[0].href.value) {
i = inst.selection.getBookmark();
inst.dom.remove(elm, 1);
inst.selection.moveToBookmark(i);
tinyMCEPopup.execCommand("mceEndUndoLevel");
tinyMCEPopup.close();
return;
}
// Create new anchor elements
if (elm == null) {
inst.getDoc().execCommand("unlink", false, null);
tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1});
elementArray = tinymce.grep(inst.dom.select("a"), function(n) {return inst.dom.getAttrib(n, 'href') == '#mce_temp_url#';});
for (i=0; i<elementArray.length; i++)
setAllAttribs(elm = elementArray[i]);
} else
setAllAttribs(elm);
// Don't move caret if selection was image
if (elm.childNodes.length != 1 || elm.firstChild.nodeName != 'IMG') {
inst.focus();
inst.selection.select(elm);
inst.selection.collapse(0);
tinyMCEPopup.storeSelection();
}
tinyMCEPopup.execCommand("mceEndUndoLevel");
tinyMCEPopup.close();
}
function setAllAttribs(elm) {
var formObj = document.forms[0];
var href = formObj.href.value.replace(/ /g, '%20');
var target = getSelectValue(formObj, 'targetlist');
setAttrib(elm, 'href', href);
setAttrib(elm, 'title');
setAttrib(elm, 'target', target == '_self' ? '' : target);
setAttrib(elm, 'id');
setAttrib(elm, 'style');
setAttrib(elm, 'class', getSelectValue(formObj, 'classlist'));
setAttrib(elm, 'rel');
setAttrib(elm, 'rev');
setAttrib(elm, 'charset');
setAttrib(elm, 'hreflang');
setAttrib(elm, 'dir');
setAttrib(elm, 'lang');
setAttrib(elm, 'tabindex');
setAttrib(elm, 'accesskey');
setAttrib(elm, 'type');
setAttrib(elm, 'onfocus');
setAttrib(elm, 'onblur');
setAttrib(elm, 'onclick');
setAttrib(elm, 'ondblclick');
setAttrib(elm, 'onmousedown');
setAttrib(elm, 'onmouseup');
setAttrib(elm, 'onmouseover');
setAttrib(elm, 'onmousemove');
setAttrib(elm, 'onmouseout');
setAttrib(elm, 'onkeypress');
setAttrib(elm, 'onkeydown');
setAttrib(elm, 'onkeyup');
// Refresh in old MSIE
if (tinyMCE.isMSIE5)
elm.outerHTML = elm.outerHTML;
}
function getSelectValue(form_obj, field_name) {
var elm = form_obj.elements[field_name];
if (!elm || elm.options == null || elm.selectedIndex == -1)
return "";
return elm.options[elm.selectedIndex].value;
}
function getLinkListHTML(elm_id, target_form_element, onchange_func) {
if (typeof(tinyMCELinkList) == "undefined" || tinyMCELinkList.length == 0)
return "";
var html = "";
html += '<select id="' + elm_id + '" name="' + elm_id + '"';
html += ' class="mceLinkList" onchange="this.form.' + target_form_element + '.value=';
html += 'this.options[this.selectedIndex].value;';
if (typeof(onchange_func) != "undefined")
html += onchange_func + '(\'' + target_form_element + '\',this.options[this.selectedIndex].text,this.options[this.selectedIndex].value);';
html += '"><option value="">---</option>';
for (var i=0; i<tinyMCELinkList.length; i++)
html += '<option value="' + tinyMCELinkList[i][1] + '">' + tinyMCELinkList[i][0] + '</option>';
html += '</select>';
return html;
// tinyMCE.debug('-- image list start --', html, '-- image list end --');
}
function getTargetListHTML(elm_id, target_form_element) {
var targets = tinyMCEPopup.getParam('theme_advanced_link_targets', '').split(';');
var html = '';
html += '<select id="' + elm_id + '" name="' + elm_id + '" onchange="this.form.' + target_form_element + '.value=';
html += 'this.options[this.selectedIndex].value;">';
html += '<option value="_self">' + tinyMCEPopup.getLang('advlink_dlg.target_same') + '</option>';
html += '<option value="_blank">' + tinyMCEPopup.getLang('advlink_dlg.target_blank') + ' (_blank)</option>';
html += '<option value="_parent">' + tinyMCEPopup.getLang('advlink_dlg.target_parent') + ' (_parent)</option>';
html += '<option value="_top">' + tinyMCEPopup.getLang('advlink_dlg.target_top') + ' (_top)</option>';
for (var i=0; i<targets.length; i++) {
var key, value;
if (targets[i] == "")
continue;
key = targets[i].split('=')[0];
value = targets[i].split('=')[1];
html += '<option value="' + key + '">' + value + ' (' + key + ')</option>';
}
html += '</select>';
return html;
}
// While loading
preinit();
tinyMCEPopup.onInit.add(init);

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
tinyMCE.addI18n('en.advlink_dlg',{"target_name":"Target Name",classes:"Classes",style:"Style",id:"ID","popup_position":"Position (X/Y)",langdir:"Language Direction","popup_size":"Size","popup_dependent":"Dependent (Mozilla/Firefox Only)","popup_resizable":"Make Window Resizable","popup_location":"Show Location Bar","popup_menubar":"Show Menu Bar","popup_toolbar":"Show Toolbars","popup_statusbar":"Show Status Bar","popup_scrollbars":"Show Scrollbars","popup_return":"Insert \'return false\'","popup_name":"Window Name","popup_url":"Popup URL",popup:"JavaScript Popup","target_blank":"Open in New Window","target_top":"Open in Top Frame (Replaces All Frames)","target_parent":"Open in Parent Window/Frame","target_same":"Open in This Window/Frame","anchor_names":"Anchors","popup_opts":"Options","advanced_props":"Advanced Properties","event_props":"Events","popup_props":"Popup Properties","general_props":"General Properties","advanced_tab":"Advanced","events_tab":"Events","popup_tab":"Popup","general_tab":"General",list:"Link List","is_external":"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?","is_email":"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",titlefield:"Title",target:"Target",url:"Link URL",title:"Insert/Edit Link","link_list":"Link List",rtl:"Right to Left",ltr:"Left to Right",accesskey:"AccessKey",tabindex:"TabIndex",rev:"Relationship Target to Page",rel:"Relationship Page to Target",mime:"Target MIME Type",encoding:"Target Character Encoding",langcode:"Language Code","target_langcode":"Target Language",width:"Width",height:"Height"});

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,338 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#advlink_dlg.title}</title>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="../../utils/mctabs.js"></script>
<script type="text/javascript" src="../../utils/form_utils.js"></script>
<script type="text/javascript" src="../../utils/validate.js"></script>
<script type="text/javascript" src="js/advlink.js"></script>
<link href="css/advlink.css" rel="stylesheet" type="text/css" />
</head>
<body id="advlink" style="display: none" role="application" onload="javascript:mcTabs.displayTab('general_tab','general_panel', true);" aria-labelledby="app_label">
<span class="mceVoiceLabel" id="app_label" style="display:none;">{#advlink_dlg.title}</span>
<form onsubmit="insertAction();return false;" action="#">
<div class="tabs" role="presentation">
<ul>
<li id="general_tab" class="current" aria-controls="general_panel" ><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advlink_dlg.general_tab}</a></span></li>
<li id="popup_tab" aria-controls="popup_panel" ><span><a href="javascript:mcTabs.displayTab('popup_tab','popup_panel');" onmousedown="return false;">{#advlink_dlg.popup_tab}</a></span></li>
<li id="events_tab" aria-controls="events_panel"><span><a href="javascript:mcTabs.displayTab('events_tab','events_panel');" onmousedown="return false;">{#advlink_dlg.events_tab}</a></span></li>
<li id="advanced_tab" aria-controls="advanced_panel"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#advlink_dlg.advanced_tab}</a></span></li>
</ul>
</div>
<div class="panel_wrapper" role="presentation">
<div id="general_panel" class="panel current">
<fieldset>
<legend>{#advlink_dlg.general_props}</legend>
<table border="0" cellpadding="4" cellspacing="0" role="presentation">
<tr>
<td class="nowrap"><label id="hreflabel" for="href">{#advlink_dlg.url}</label></td>
<td><table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><input id="href" name="href" type="text" class="mceFocus" value="" onchange="selectByValue(this.form,'linklisthref',this.value);" aria-required="true" /></td>
<td id="hrefbrowsercontainer">&nbsp;</td>
</tr>
</table></td>
</tr>
<tr id="linklisthrefrow">
<td class="column1"><label for="linklisthref">{#advlink_dlg.list}</label></td>
<td colspan="2" id="linklisthrefcontainer"><select id="linklisthref"><option value=""></option></select></td>
</tr>
<tr id="anchorlistrow">
<td class="column1"><label for="anchorlist">{#advlink_dlg.anchor_names}</label></td>
<td colspan="2" id="anchorlistcontainer"><select id="anchorlist"><option value=""></option></select></td>
</tr>
<tr>
<td><label id="targetlistlabel" for="targetlist">{#advlink_dlg.target}</label></td>
<td id="targetlistcontainer"><select id="targetlist"><option value=""></option></select></td>
</tr>
<tr>
<td class="nowrap"><label id="titlelabel" for="title">{#advlink_dlg.titlefield}</label></td>
<td><input id="title" name="title" type="text" value="" /></td>
</tr>
<tr>
<td><label id="classlabel" for="classlist">{#class_name}</label></td>
<td>
<select id="classlist" name="classlist" onchange="changeClass();">
<option value="" selected="selected">{#not_set}</option>
</select>
</td>
</tr>
</table>
</fieldset>
</div>
<div id="popup_panel" class="panel">
<fieldset>
<legend>{#advlink_dlg.popup_props}</legend>
<input type="checkbox" id="ispopup" name="ispopup" class="radio" onclick="setPopupControlsDisabled(!this.checked);buildOnClick();" />
<label id="ispopuplabel" for="ispopup">{#advlink_dlg.popup}</label>
<table border="0" cellpadding="0" cellspacing="4" role="presentation" >
<tr>
<td class="nowrap"><label for="popupurl">{#advlink_dlg.popup_url}</label>&nbsp;</td>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><input type="text" name="popupurl" id="popupurl" value="" onchange="buildOnClick();" /></td>
<td id="popupurlbrowsercontainer">&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="nowrap"><label for="popupname">{#advlink_dlg.popup_name}</label>&nbsp;</td>
<td><input type="text" name="popupname" id="popupname" value="" onchange="buildOnClick();" /></td>
</tr>
<tr role="group" aria-labelledby="popup_size_label">
<td class="nowrap"><label id="popup_size_label">{#advlink_dlg.popup_size}</label>&nbsp;</td>
<td class="nowrap">
<span style="display:none" id="width_voiceLabel">{#advlink_dlg.width}</span>
<input type="text" id="popupwidth" name="popupwidth" value="" onchange="buildOnClick();" aria-labelledby="width_voiceLabel" /> x
<span style="display:none" id="height_voiceLabel">{#advlink_dlg.height}</span>
<input type="text" id="popupheight" name="popupheight" value="" onchange="buildOnClick();" aria-labelledby="height_voiceLabel" /> px
</td>
</tr>
<tr role="group" aria-labelledby="popup_position_label center_hint">
<td class="nowrap" id="labelleft"><label id="popup_position_label">{#advlink_dlg.popup_position}</label>&nbsp;</td>
<td class="nowrap">
<span style="display:none" id="x_voiceLabel">X</span>
<input type="text" id="popupleft" name="popupleft" value="" onchange="buildOnClick();" aria-labelledby="x_voiceLabel" /> /
<span style="display:none" id="y_voiceLabel">Y</span>
<input type="text" id="popuptop" name="popuptop" value="" onchange="buildOnClick();" aria-labelledby="y_voiceLabel" /> <span id="center_hint">(c /c = center)</span>
</td>
</tr>
</table>
<fieldset>
<legend>{#advlink_dlg.popup_opts}</legend>
<table border="0" cellpadding="0" cellspacing="4" role="presentation" >
<tr>
<td><input type="checkbox" id="popuplocation" name="popuplocation" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popuplocationlabel" for="popuplocation">{#advlink_dlg.popup_location}</label></td>
<td><input type="checkbox" id="popupscrollbars" name="popupscrollbars" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popupscrollbarslabel" for="popupscrollbars">{#advlink_dlg.popup_scrollbars}</label></td>
</tr>
<tr>
<td><input type="checkbox" id="popupmenubar" name="popupmenubar" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popupmenubarlabel" for="popupmenubar">{#advlink_dlg.popup_menubar}</label></td>
<td><input type="checkbox" id="popupresizable" name="popupresizable" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popupresizablelabel" for="popupresizable">{#advlink_dlg.popup_resizable}</label></td>
</tr>
<tr>
<td><input type="checkbox" id="popuptoolbar" name="popuptoolbar" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popuptoolbarlabel" for="popuptoolbar">{#advlink_dlg.popup_toolbar}</label></td>
<td><input type="checkbox" id="popupdependent" name="popupdependent" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popupdependentlabel" for="popupdependent">{#advlink_dlg.popup_dependent}</label></td>
</tr>
<tr>
<td><input type="checkbox" id="popupstatus" name="popupstatus" class="checkbox" onchange="buildOnClick();" /></td>
<td class="nowrap"><label id="popupstatuslabel" for="popupstatus">{#advlink_dlg.popup_statusbar}</label></td>
<td><input type="checkbox" id="popupreturn" name="popupreturn" class="checkbox" onchange="buildOnClick();" checked="checked" /></td>
<td class="nowrap"><label id="popupreturnlabel" for="popupreturn">{#advlink_dlg.popup_return}</label></td>
</tr>
</table>
</fieldset>
</fieldset>
</div>
<div id="advanced_panel" class="panel">
<fieldset>
<legend>{#advlink_dlg.advanced_props}</legend>
<table border="0" cellpadding="0" cellspacing="4" role="presentation" >
<tr>
<td class="column1"><label id="idlabel" for="id">{#advlink_dlg.id}</label></td>
<td><input id="id" name="id" type="text" value="" /></td>
</tr>
<tr>
<td><label id="stylelabel" for="style">{#advlink_dlg.style}</label></td>
<td><input type="text" id="style" name="style" value="" /></td>
</tr>
<tr>
<td><label id="classeslabel" for="classes">{#advlink_dlg.classes}</label></td>
<td><input type="text" id="classes" name="classes" value="" onchange="selectByValue(this.form,'classlist',this.value,true);" /></td>
</tr>
<tr>
<td><label id="targetlabel" for="target">{#advlink_dlg.target_name}</label></td>
<td><input type="text" id="target" name="target" value="" onchange="selectByValue(this.form,'targetlist',this.value,true);" /></td>
</tr>
<tr>
<td class="column1"><label id="dirlabel" for="dir">{#advlink_dlg.langdir}</label></td>
<td>
<select id="dir" name="dir">
<option value="">{#not_set}</option>
<option value="ltr">{#advlink_dlg.ltr}</option>
<option value="rtl">{#advlink_dlg.rtl}</option>
</select>
</td>
</tr>
<tr>
<td><label id="hreflanglabel" for="hreflang">{#advlink_dlg.target_langcode}</label></td>
<td><input type="text" id="hreflang" name="hreflang" value="" /></td>
</tr>
<tr>
<td class="column1"><label id="langlabel" for="lang">{#advlink_dlg.langcode}</label></td>
<td>
<input id="lang" name="lang" type="text" value="" />
</td>
</tr>
<tr>
<td><label id="charsetlabel" for="charset">{#advlink_dlg.encoding}</label></td>
<td><input type="text" id="charset" name="charset" value="" /></td>
</tr>
<tr>
<td><label id="typelabel" for="type">{#advlink_dlg.mime}</label></td>
<td><input type="text" id="type" name="type" value="" /></td>
</tr>
<tr>
<td><label id="rellabel" for="rel">{#advlink_dlg.rel}</label></td>
<td><select id="rel" name="rel">
<option value="">{#not_set}</option>
<option value="lightbox">Lightbox</option>
<option value="alternate">Alternate</option>
<option value="designates">Designates</option>
<option value="stylesheet">Stylesheet</option>
<option value="start">Start</option>
<option value="next">Next</option>
<option value="prev">Prev</option>
<option value="contents">Contents</option>
<option value="index">Index</option>
<option value="glossary">Glossary</option>
<option value="copyright">Copyright</option>
<option value="chapter">Chapter</option>
<option value="subsection">Subsection</option>
<option value="appendix">Appendix</option>
<option value="help">Help</option>
<option value="bookmark">Bookmark</option>
<option value="nofollow">No Follow</option>
<option value="tag">Tag</option>
</select>
</td>
</tr>
<tr>
<td><label id="revlabel" for="rev">{#advlink_dlg.rev}</label></td>
<td><select id="rev" name="rev">
<option value="">{#not_set}</option>
<option value="alternate">Alternate</option>
<option value="designates">Designates</option>
<option value="stylesheet">Stylesheet</option>
<option value="start">Start</option>
<option value="next">Next</option>
<option value="prev">Prev</option>
<option value="contents">Contents</option>
<option value="index">Index</option>
<option value="glossary">Glossary</option>
<option value="copyright">Copyright</option>
<option value="chapter">Chapter</option>
<option value="subsection">Subsection</option>
<option value="appendix">Appendix</option>
<option value="help">Help</option>
<option value="bookmark">Bookmark</option>
</select>
</td>
</tr>
<tr>
<td><label id="tabindexlabel" for="tabindex">{#advlink_dlg.tabindex}</label></td>
<td><input type="text" id="tabindex" name="tabindex" value="" /></td>
</tr>
<tr>
<td><label id="accesskeylabel" for="accesskey">{#advlink_dlg.accesskey}</label></td>
<td><input type="text" id="accesskey" name="accesskey" value="" /></td>
</tr>
</table>
</fieldset>
</div>
<div id="events_panel" class="panel">
<fieldset>
<legend>{#advlink_dlg.event_props}</legend>
<table border="0" cellpadding="0" cellspacing="4" role="presentation" >
<tr>
<td class="column1"><label for="onfocus">onfocus</label></td>
<td><input id="onfocus" name="onfocus" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onblur">onblur</label></td>
<td><input id="onblur" name="onblur" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onclick">onclick</label></td>
<td><input id="onclick" name="onclick" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="ondblclick">ondblclick</label></td>
<td><input id="ondblclick" name="ondblclick" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onmousedown">onmousedown</label></td>
<td><input id="onmousedown" name="onmousedown" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onmouseup">onmouseup</label></td>
<td><input id="onmouseup" name="onmouseup" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onmouseover">onmouseover</label></td>
<td><input id="onmouseover" name="onmouseover" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onmousemove">onmousemove</label></td>
<td><input id="onmousemove" name="onmousemove" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onmouseout">onmouseout</label></td>
<td><input id="onmouseout" name="onmouseout" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onkeypress">onkeypress</label></td>
<td><input id="onkeypress" name="onkeypress" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onkeydown">onkeydown</label></td>
<td><input id="onkeydown" name="onkeydown" type="text" value="" /></td>
</tr>
<tr>
<td class="column1"><label for="onkeyup">onkeyup</label></td>
<td><input id="onkeyup" name="onkeyup" type="text" value="" /></td>
</tr>
</table>
</fieldset>
</div>
</div>
<div class="mceActionPanel">
<input type="submit" id="insert" name="insert" value="{#insert}" />
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1 @@
(function(){var a=tinymce.each;tinymce.create("tinymce.plugins.AdvListPlugin",{init:function(b,c){var d=this;d.editor=b;function e(g){var f=[];a(g.split(/,/),function(h){f.push({title:"advlist."+(h=="default"?"def":h.replace(/-/g,"_")),styles:{listStyleType:h=="default"?"":h}})});return f}d.numlist=b.getParam("advlist_number_styles")||e("default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");d.bullist=b.getParam("advlist_bullet_styles")||e("default,circle,disc,square");if(tinymce.isIE&&/MSIE [2-7]/.test(navigator.userAgent)){d.isIE7=true}},createControl:function(d,b){var f=this,e,i,g=f.editor;if(d=="numlist"||d=="bullist"){if(f[d][0].title=="advlist.def"){i=f[d][0]}function c(j,l){var k=true;a(l.styles,function(n,m){if(g.dom.getStyle(j,m)!=n){k=false;return false}});return k}function h(){var k,l=g.dom,j=g.selection;k=l.getParent(j.getNode(),"ol,ul");if(!k||k.nodeName==(d=="bullist"?"OL":"UL")||c(k,i)){g.execCommand(d=="bullist"?"InsertUnorderedList":"InsertOrderedList")}if(i){k=l.getParent(j.getNode(),"ol,ul");if(k){l.setStyles(k,i.styles);k.removeAttribute("data-mce-style")}}g.focus()}e=b.createSplitButton(d,{title:"advanced."+d+"_desc","class":"mce_"+d,onclick:function(){h()}});e.onRenderMenu.add(function(j,k){k.onHideMenu.add(function(){if(f.bookmark){g.selection.moveToBookmark(f.bookmark);f.bookmark=0}});k.onShowMenu.add(function(){var n=g.dom,m=n.getParent(g.selection.getNode(),"ol,ul"),l;if(m||i){l=f[d];a(k.items,function(o){var p=true;o.setSelected(0);if(m&&!o.isDisabled()){a(l,function(q){if(q.id==o.id){if(!c(m,q)){p=false;return false}}});if(p){o.setSelected(1)}}});if(!m){k.items[i.id].setSelected(1)}}g.focus();if(tinymce.isIE){f.bookmark=g.selection.getBookmark(1)}});k.add({id:g.dom.uniqueId(),title:"advlist.types","class":"mceMenuItemTitle",titleItem:true}).setDisabled(1);a(f[d],function(l){if(f.isIE7&&l.styles.listStyleType=="lower-greek"){return}l.id=g.dom.uniqueId();k.add({id:l.id,title:l.title,onclick:function(){i=l;h()}})})});return e}},getInfo:function(){return{longname:"Advanced lists",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlist",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("advlist",tinymce.plugins.AdvListPlugin)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;a.onKeyDown.addToTop(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});if(tinyMCE.isIE){return}a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng(true).cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}if(n.nodeType==3){a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}var m=a.toString();if(m.charAt(m.length-1)=="."){a.setEnd(n,c-1)}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])&&!/^mailto:/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);i.nodeChanged();if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.AutoResizePlugin",{init:function(a,c){var d=this,e=0;if(a.getParam("fullscreen_is_enabled")){return}function b(){var j,i=a.getDoc(),f=i.body,l=i.documentElement,h=tinymce.DOM,k=d.autoresize_min_height,g;g=tinymce.isIE?f.scrollHeight:(tinymce.isWebKit&&f.clientHeight==0?0:f.offsetHeight);if(g>d.autoresize_min_height){k=g}if(d.autoresize_max_height&&g>d.autoresize_max_height){k=d.autoresize_max_height;f.style.overflowY="auto";l.style.overflowY="auto"}else{f.style.overflowY="hidden";l.style.overflowY="hidden";f.scrollTop=0}if(k!==e){j=k-e;h.setStyle(h.get(a.id+"_ifr"),"height",k+"px");e=k;if(tinymce.isWebKit&&j<0){b()}}}d.editor=a;d.autoresize_min_height=parseInt(a.getParam("autoresize_min_height",a.getElement().offsetHeight));d.autoresize_max_height=parseInt(a.getParam("autoresize_max_height",0));a.onInit.add(function(f){f.dom.setStyle(f.getBody(),"paddingBottom",f.getParam("autoresize_bottom_margin",50)+"px")});a.onChange.add(b);a.onSetContent.add(b);a.onPaste.add(b);a.onKeyUp.add(b);a.onPostRender.add(b);if(a.getParam("autoresize_on_init",true)){a.onLoad.add(b);a.onLoadContent.add(b)}a.addCommand("mceAutoResize",b)},getInfo:function(){return{longname:"Auto Resize",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autoresize",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autoresize",tinymce.plugins.AutoResizePlugin)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(e){var c="autosave",g="restoredraft",b=true,f,d,a=e.util.Dispatcher;e.create("tinymce.plugins.AutoSave",{init:function(i,j){var h=this,l=i.settings;h.editor=i;function k(n){var m={s:1000,m:60000};n=/^(\d+)([ms]?)$/.exec(""+n);return(n[2]?m[n[2]]:1)*parseInt(n)}e.each({ask_before_unload:b,interval:"30s",retention:"20m",minlength:50},function(n,m){m=c+"_"+m;if(l[m]===f){l[m]=n}});l.autosave_interval=k(l.autosave_interval);l.autosave_retention=k(l.autosave_retention);i.addButton(g,{title:c+".restore_content",onclick:function(){if(i.getContent({draft:true}).replace(/\s|&nbsp;|<\/?p[^>]*>|<br[^>]*>/gi,"").length>0){i.windowManager.confirm(c+".warning_message",function(m){if(m){h.restoreDraft()}})}else{h.restoreDraft()}}});i.onNodeChange.add(function(){var m=i.controlManager;if(m.get(g)){m.setDisabled(g,!h.hasDraft())}});i.onInit.add(function(){if(i.controlManager.get(g)){h.setupStorage(i);setInterval(function(){if(!i.removed){h.storeDraft();i.nodeChanged()}},l.autosave_interval)}});h.onStoreDraft=new a(h);h.onRestoreDraft=new a(h);h.onRemoveDraft=new a(h);if(!d){window.onbeforeunload=e.plugins.AutoSave._beforeUnloadHandler;d=b}},getInfo:function(){return{longname:"Auto save",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave",version:e.majorVersion+"."+e.minorVersion}},getExpDate:function(){return new Date(new Date().getTime()+this.editor.settings.autosave_retention).toUTCString()},setupStorage:function(i){var h=this,k=c+"_test",j="OK";h.key=c+i.id;e.each([function(){if(localStorage){localStorage.setItem(k,j);if(localStorage.getItem(k)===j){localStorage.removeItem(k);return localStorage}}},function(){if(sessionStorage){sessionStorage.setItem(k,j);if(sessionStorage.getItem(k)===j){sessionStorage.removeItem(k);return sessionStorage}}},function(){if(e.isIE){i.getElement().style.behavior="url('#default#userData')";return{autoExpires:b,setItem:function(l,n){var m=i.getElement();m.setAttribute(l,n);m.expires=h.getExpDate();try{m.save("TinyMCE")}catch(o){}},getItem:function(l){var m=i.getElement();try{m.load("TinyMCE");return m.getAttribute(l)}catch(n){return null}},removeItem:function(l){i.getElement().removeAttribute(l)}}}},],function(l){try{h.storage=l();if(h.storage){return false}}catch(m){}})},storeDraft:function(){var i=this,l=i.storage,j=i.editor,h,k;if(l){if(!l.getItem(i.key)&&!j.isDirty()){return}k=j.getContent({draft:true});if(k.length>j.settings.autosave_minlength){h=i.getExpDate();if(!i.storage.autoExpires){i.storage.setItem(i.key+"_expires",h)}i.storage.setItem(i.key,k);i.onStoreDraft.dispatch(i,{expires:h,content:k})}}},restoreDraft:function(){var h=this,j=h.storage,i;if(j){i=j.getItem(h.key);if(i){h.editor.setContent(i);h.onRestoreDraft.dispatch(h,{content:i})}}},hasDraft:function(){var h=this,k=h.storage,i,j;if(k){j=!!k.getItem(h.key);if(j){if(!h.storage.autoExpires){i=new Date(k.getItem(h.key+"_expires"));if(new Date().getTime()<i.getTime()){return b}h.removeDraft()}else{return b}}}return false},removeDraft:function(){var h=this,k=h.storage,i=h.key,j;if(k){j=k.getItem(i);k.removeItem(i);k.removeItem(i+"_expires");if(j){h.onRemoveDraft.dispatch(h,{content:j})}}},"static":{_beforeUnloadHandler:function(h){var i;e.each(tinyMCE.editors,function(j){if(j.plugins.autosave){j.plugins.autosave.storeDraft()}if(j.getParam("fullscreen_is_enabled")){return}if(!i&&j.isDirty()&&j.getParam("autosave_ask_before_unload")){i=j.getLang("autosave.unload_msg")}});return i}}});e.PluginManager.add("autosave",e.plugins.AutoSave)})(tinymce);

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,4 @@
tinyMCE.addI18n('en.autosave',{
restore_content: "Restore auto-saved content",
warning_message: "If you restore the saved content, you will lose all the content that is currently in the editor.\n\nAre you sure you want to restore the saved content?"
});

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(a,b){var d=this,c=a.getParam("bbcode_dialect","punbb").toLowerCase();a.onBeforeSetContent.add(function(e,f){f.content=d["_"+c+"_bbcode2html"](f.content)});a.onPostProcess.add(function(e,f){if(f.set){f.content=d["_"+c+"_bbcode2html"](f.content)}if(f.get){f.content=d["_"+c+"_html2bbcode"](f.content)}})},getInfo:function(){return{longname:"BBCode Plugin",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_punbb_html2bbcode:function(a){a=tinymce.trim(a);function b(c,d){a=a.replace(c,d)}b(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");b(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");b(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");b(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");b(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");b(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]");b(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]");b(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]");b(/<font>(.*?)<\/font>/gi,"$1");b(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]");b(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]");b(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]");b(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]");b(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]");b(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]");b(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]");b(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]");b(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]");b(/<\/(strong|b)>/gi,"[/b]");b(/<(strong|b)>/gi,"[b]");b(/<\/(em|i)>/gi,"[/i]");b(/<(em|i)>/gi,"[i]");b(/<\/u>/gi,"[/u]");b(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]");b(/<u>/gi,"[u]");b(/<blockquote[^>]*>/gi,"[quote]");b(/<\/blockquote>/gi,"[/quote]");b(/<br \/>/gi,"\n");b(/<br\/>/gi,"\n");b(/<br>/gi,"\n");b(/<p>/gi,"");b(/<\/p>/gi,"\n");b(/&nbsp;|\u00a0/gi," ");b(/&quot;/gi,'"');b(/&lt;/gi,"<");b(/&gt;/gi,">");b(/&amp;/gi,"&");return a},_punbb_bbcode2html:function(a){a=tinymce.trim(a);function b(c,d){a=a.replace(c,d)}b(/\n/gi,"<br />");b(/\[b\]/gi,"<strong>");b(/\[\/b\]/gi,"</strong>");b(/\[i\]/gi,"<em>");b(/\[\/i\]/gi,"</em>");b(/\[u\]/gi,"<u>");b(/\[\/u\]/gi,"</u>");b(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>');b(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>');b(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />');b(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>');b(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span>&nbsp;');b(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span>&nbsp;');return a}});tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(f){var i=this,g,d,j,e;i.editor=f;d=f.settings.contextmenu_never_use_native;i.onContextMenu=new tinymce.util.Dispatcher(this);e=function(k){h(f,k)};g=f.onContextMenu.add(function(k,l){if((j!==0?j:l.ctrlKey)&&!d){return}a.cancel(l);if(l.target.nodeName=="IMG"){k.selection.select(l.target)}i._getMenu(k).showMenu(l.clientX||l.pageX,l.clientY||l.pageY);a.add(k.getDoc(),"click",e);k.nodeChanged()});f.onRemove.add(function(){if(i._menu){i._menu.removeAll()}});function h(k,l){j=0;if(l&&l.button==2){j=l.ctrlKey;return}if(i._menu){i._menu.removeAll();i._menu.destroy();a.remove(k.getDoc(),"click",e);i._menu=null}}f.onMouseDown.add(h);f.onKeyDown.add(h);f.onKeyDown.add(function(k,l){if(l.shiftKey&&!l.ctrlKey&&!l.altKey&&l.keyCode===121){a.cancel(l);g(k,l)}})},getInfo:function(){return{longname:"Contextmenu",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getMenu:function(e){var g=this,d=g._menu,j=e.selection,f=j.isCollapsed(),h=j.getNode()||e.getBody(),i,k;if(d){d.removeAll();d.destroy()}k=b.getPos(e.getContentAreaContainer());d=e.controlManager.createDropMenu("contextmenu",{offset_x:k.x+e.getParam("contextmenu_offset_x",0),offset_y:k.y+e.getParam("contextmenu_offset_y",0),constrain:1,keyboard_focus:true});g._menu=d;d.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(f);d.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(f);d.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((h.nodeName=="A"&&!e.dom.getAttrib(h,"name"))||!f){d.addSeparator();d.add({title:"advanced.link_desc",icon:"link",cmd:e.plugins.advlink?"mceAdvLink":"mceLink",ui:true});d.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}d.addSeparator();d.add({title:"advanced.image_desc",icon:"image",cmd:e.plugins.advimage?"mceAdvImage":"mceImage",ui:true});d.addSeparator();i=d.addMenu({title:"contextmenu.align"});i.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});i.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});i.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});i.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});g.onContextMenu.dispatch(g,d,h,f);return d}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(){tinymce.create("tinymce.plugins.Directionality",{init:function(b,c){var d=this;d.editor=b;function a(e){var h=b.dom,g,f=b.selection.getSelectedBlocks();if(f.length){g=h.getAttrib(f[0],"dir");tinymce.each(f,function(i){if(!h.getParent(i.parentNode,"*[dir='"+e+"']",h.getRoot())){if(g!=e){h.setAttrib(i,"dir",e)}else{h.setAttrib(i,"dir",null)}}});b.nodeChanged()}}b.addCommand("mceDirectionLTR",function(){a("ltr")});b.addCommand("mceDirectionRTL",function(){a("rtl")});b.addButton("ltr",{title:"directionality.ltr_desc",cmd:"mceDirectionLTR"});b.addButton("rtl",{title:"directionality.rtl_desc",cmd:"mceDirectionRTL"});b.onNodeChange.add(d._nodeChange,d)},getInfo:function(){return{longname:"Directionality",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_nodeChange:function(b,a,e){var d=b.dom,c;e=d.getParent(e,d.isBlock);if(!e){a.setDisabled("ltr",1);a.setDisabled("rtl",1);return}c=d.getAttrib(e,"dir");a.setActive("ltr",c=="ltr");a.setDisabled("ltr",0);a.setActive("rtl",c=="rtl");a.setDisabled("rtl",0)}});tinymce.PluginManager.add("directionality",tinymce.plugins.Directionality)})();

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1 @@
(function(a){a.create("tinymce.plugins.EmotionsPlugin",{init:function(b,c){b.addCommand("mceEmotion",function(){b.windowManager.open({file:c+"/emotions.htm",width:250+parseInt(b.getLang("emotions.delta_width",0)),height:160+parseInt(b.getLang("emotions.delta_height",0)),inline:1},{plugin_url:c})});b.addButton("emotions",{title:"emotions.emotions_desc",cmd:"mceEmotion"})},getInfo:function(){return{longname:"Emotions",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions",version:a.majorVersion+"."+a.minorVersion}}});a.PluginManager.add("emotions",a.plugins.EmotionsPlugin)})(tinymce);

View File

@ -0,0 +1,42 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#emotions_dlg.title}</title>
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
<script type="text/javascript" src="js/emotions.js"></script>
</head>
<body style="display: none" role="application" aria-labelledby="app_title">
<span style="display:none;" id="app_title">{#emotions_dlg.title}</span>
<div align="center">
<div class="title">{#emotions_dlg.title}:<br /><br /></div>
<table id="emoticon_table" role="presentation" border="0" cellspacing="0" cellpadding="4">
<tr>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.cool}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-cool.gif','emotions_dlg.cool');"><img src="img/smiley-cool.gif" width="18" height="18" border="0" alt="{#emotions_dlg.cool}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.cry}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-cry.gif','emotions_dlg.cry');"><img src="img/smiley-cry.gif" width="18" height="18" border="0" alt="{#emotions_dlg.cry}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.embarassed}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-embarassed.gif','emotions_dlg.embarassed');"><img src="img/smiley-embarassed.gif" width="18" height="18" border="0" alt="{#emotions_dlg.embarassed}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.foot_in_mouth}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-foot-in-mouth.gif','emotions_dlg.foot_in_mouth');"><img src="img/smiley-foot-in-mouth.gif" width="18" height="18" border="0" alt="{#emotions_dlg.foot_in_mouth}. {#emotions_dlg.usage}" /></a></td>
</tr>
<tr>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.frown}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-frown.gif','emotions_dlg.frown');"><img src="img/smiley-frown.gif" width="18" height="18" border="0" alt="{#emotions_dlg.frown}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.innocent}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-innocent.gif','emotions_dlg.innocent');"><img src="img/smiley-innocent.gif" width="18" height="18" border="0" alt="{#emotions_dlg.innocent}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.kiss}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-kiss.gif','emotions_dlg.kiss');"><img src="img/smiley-kiss.gif" width="18" height="18" border="0" alt="{#emotions_dlg.kiss}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.laughing}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-laughing.gif','emotions_dlg.laughing');"><img src="img/smiley-laughing.gif" width="18" height="18" border="0" alt="{#emotions_dlg.laughing}. {#emotions_dlg.usage}" /></a></td>
</tr>
<tr>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.money_mouth}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-money-mouth.gif','emotions_dlg.money_mouth');"><img src="img/smiley-money-mouth.gif" width="18" height="18" border="0" alt="{#emotions_dlg.money_mouth}. {#emotions_dlg.usage}"/></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.sealed}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-sealed.gif','emotions_dlg.sealed');"><img src="img/smiley-sealed.gif" width="18" height="18" border="0" alt="{#emotions_dlg.sealed}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.smile}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-smile.gif','emotions_dlg.smile');"><img src="img/smiley-smile.gif" width="18" height="18" border="0" alt="{#emotions_dlg.smile}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.surprised}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-surprised.gif','emotions_dlg.surprised');"><img src="img/smiley-surprised.gif" width="18" height="18" border="0" alt="{#emotions_dlg.surprised}. {#emotions_dlg.usage}" /></a></td>
</tr>
<tr>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.tongue_out}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-tongue-out.gif','emotions_dlg.tongue_out');"><img src="img/smiley-tongue-out.gif" width="18" height="18" border="0" alt="{#emotions_dlg.tongue-out}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.undecided}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-undecided.gif','emotions_dlg.undecided');"><img src="img/smiley-undecided.gif" width="18" height="18" border="0" alt="{#emotions_dlg.undecided}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.wink}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-wink.gif','emotions_dlg.wink');"><img src="img/smiley-wink.gif" width="18" height="18" border="0" alt="{#emotions_dlg.wink}. {#emotions_dlg.usage}" /></a></td>
<td><a class="emoticon_link" role="button" title="{#emotions_dlg.yell}. {#emotions_dlg.usage}" href="javascript:EmotionsDialog.insert('smiley-yell.gif','emotions_dlg.yell');"><img src="img/smiley-yell.gif" width="18" height="18" border="0" alt="{#emotions_dlg.yell}. {#emotions_dlg.usage}" /></a></td>
</tr>
</table>
<div>{#emotions_dlg.usage}</div>
</div>
</body>
</html>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Some files were not shown because too many files have changed in this diff Show More