Compare commits

..

53 Commits

Author SHA1 Message Date
Matt Pass
c56af14f52 stickyTab, login, plugin & settings improvements/features
New vars for stickyTab and plugin interval refs
New login container, adjusts to width of file manager
Upon login, slide login box up to reveal icons
New vars to allow stickyTab on CTRL+S+Enter
Improvement so you don't end up with a locked nav thats collapsed
Fix so we only switchtab if we have associated CM instance
Also updates found results display on switching tab
SwitchMode only does this if there is a filename (tab name) available
Plugin timers now created under vars so they can be cleared
If there is a login attempt, slide login box up to reveal icons
New function to show settings screen on demand
New function to update theme, tabsIndent, lockedNav, visibleTabs & file manager
(This is so changed settings can be applied straight away)
File manager refresh only happens if it needs to, for efficiency
2012-05-01 08:18:46 +01:00
Matt Pass
ed8fb0dd67 Settings can now be updated and changes applied on the fly
Moved various items around in code
Identified settings area with start & end comment blocks
.sql files are now a banned file type
new vars for tabsIndent, codeAssist & lockedNav
When settings are changed from settings screen, this file updates itself
Also then applies settings and refreshes/reloads intelligently
Work out if we have an approved IP or not, if not boot to root
Apply plugins (display & setIntervals) on load or on change of this file
Also apply autoOpenFiles onload from index.php
Refresh file manager and show icons if we have a correct login
2012-05-01 08:07:21 +01:00
Matt Pass
f906b41cd2 CSS classes for new settings popup screen 2012-05-01 07:56:37 +01:00
Matt Pass
1491e24039 Settings screen show in popup on right click of logo
Right clicking the ICEcoder logo now shows this settings screen in a popup
This allows you to control all main settings for ICEcoder
Saving settings applies changes to settings.php
Also intelligently reloads & refreshes relevant items for efficiency
Thanked a few people in this screen, hope they don't mind
2012-05-01 07:55:53 +01:00
Matt Pass
30dbad53a7 Session IP, plugin, autoOpenFiles, settingsScreen, & login improvements
Checking of IP now done via session var, so it's updatable via settings
Plugin intervals, display of icons & autoOpenFiles moved to settings.php
(This is so these things can be updated upon settings change)
init function now takes param to determin if you are logged in or not
Logo now right clickable to show settings screen
Account login box now in own container so it can slide out of view on login
Other minor changes to fit in with new features
2012-05-01 07:44:40 +01:00
Matt Pass
b129bc39cb Save now works with stickyTabs, plus minor improvements
When you save, if there is a stickyTab window, it reloads
Popups for images now have white glow around them, plus fix to text color
Moved clearing the server message to cover images too
2012-05-01 07:35:00 +01:00
Matt Pass
5ffba58802 Classes for h1, h2, whiteGlow, accountLogin & container, blue glow & more
Many new classes, including a few adjustments
whiteGlow class to surround popups and a similar blue one for input boxes
Minor adjustments to others to fit new features
2012-05-01 07:31:19 +01:00
Matt Pass
3cd5b99edd Tabbing can now dynamically switch between tab & indent
tab:after now always available, has dynamic content (blank or tab symbol)
Tabbing can now dynamically switch and is either default or indents
(default tabs, but if you've something selected will indent selected lines)
2012-05-01 07:26:01 +01:00
Matt Pass
89b1b51097 Upgrade to CodeMirror 2.24 2012-05-01 07:15:56 +01:00
Matt Pass
6b5c95fc3a Remove CodeMirror 2.23 (upgrading to 2.24) 2012-05-01 07:14:15 +01:00
Matt Pass
8019f66a78 Default = icecoder fix
If you choose the default theme, we need to identify that as 'iceocder'
2012-04-20 08:01:13 +01:00
Matt Pass
b5e8afb8d9 Fix to match new function variable name 2012-04-20 08:00:29 +01:00
Matt Pass
e2b585027b Various CSS styles back in theme
cursor, selected, gutter & matching bracket styles back in default theme
These styles pertain to this theme only and to avoid conflicts with another themne are back in
2012-04-20 07:47:04 +01:00
Matt Pass
56ade7fa75 Some CSS moved back into default theme & visibleTabs option back in
selected, gutter, cursor & matching bracket moved back into default theme
(As it pertains to that theme only)
$visibleTabs option back in
2012-04-20 07:45:58 +01:00
Matt Pass
efbef411f9 Theme setting, open last files if logged in plus fragmenting file menu
User selected 'Theme' variable set here and used later
Last opened files only loaded on start if you are logged in
Rename & View Webpage now within their own wrapper
(This allows us to only show if we have 1 file selected, done via JS)
2012-04-19 17:50:33 +01:00
Matt Pass
6ef524e4ce Themes applied to editor & styling made more general
Some of the general styling moved from default theme to here
(margin on HTML & body, plus selected, gutter, cursor & matching styles)
Removed setting of theme here, done dynamically with existing functions
2012-04-19 17:47:49 +01:00
Matt Pass
dff7573531 Theme can now be chosen, right click menu now dynamic & reload FM
Updates to allow usage of theme as chosen by user
Menu that displays when user click is now more dynamic
(Shows options based on number of files selected)
Function to reload File Manager on demand plus show loading screen
2012-04-19 17:43:41 +01:00
Matt Pass
881b8f014b Adjustment to onContextMenu & FM reloader
Removed selecting of files/folders func when right clicking
Added refresh icon to reload file manager on click
2012-04-19 17:40:19 +01:00
Matt Pass
d273c82b86 Removed clipboard plugin, theme setting & fix to stop UI jamming
Infinite Clipboard plugin removed as no longer developing this idea
Theme setting now available to choose the default or a CM based theme
UI now doesn't jam when opening/closing files if you're not logged in
2012-04-19 17:39:05 +01:00
Matt Pass
6e5ab719a4 Simplified default CSS file
HTML & body styling now spplied to tags
selected, gutter, cursor and matching elements now applied in editor.php
This all allows CodeMirror themes to be used if users want to switch from default
2012-04-19 17:34:28 +01:00
Matt Pass
b416dd79f5 CSS class for refresh icon 2012-04-19 17:29:46 +01:00
Matt Pass
1e4237a483 Refresh icon added to File Manager
Users can now reload file manager by clicking icon
2012-04-19 17:29:00 +01:00
Matt Pass
a90a53458d Clipboard plugin icon removed
Icon removed as no longer including an Infinite Clipboard plugin
2012-04-19 17:28:22 +01:00
Matt Pass
54fa471d26 CodeMirror themes dir added
CodeMirror themes can now be used by ICEcoder
All themes folder included so users can choose if they wish
2012-04-19 17:27:48 +01:00
Matt Pass
be20e8f302 Updates to the fold code function to standardise folding
Orig pull request approved by Marijn and merged into CodeMirror repo
(Not this one, but my previous fix)
2012-04-19 17:25:56 +01:00
Matt Pass
222f651d68 Minor fix to start session from beginnig of file
Was causing problems when opening a file, not able to set as session not started
2012-04-14 18:26:44 +01:00
Matt Pass
b70ee4553a Ruby language support & visible tabs
CodeMirror mode now loaded for Ruby code highlighting
CSS for visible tabs if setting turned on
2012-04-14 18:10:00 +01:00
Matt Pass
493037a01b Ruby language support & auto loading of last opened files
Ruby now supported as a language in .rb files or within % blocks
List of last opened files updates on opening, closing and renaming tabs
Comment toggle function now handles Ruby commenting via # hashes
(Decided not to go for =begin and =end as this requires extra lines)
New function to handle opening of previously opened files
A few global vars that have been added recently now closed
2012-04-14 18:08:03 +01:00
Matt Pass
8233763511 Extra code to allow for auto opening of files
On opening and files being auto loaded, we need to establish the shortURL
This is so tabs can have the correct name on auto loading files
2012-04-14 17:54:52 +01:00
Matt Pass
2c01eeba17 Visible tabs and auto opening last opened files
Option to show tabs as arrows or blanks
Option to open last opened files on next session or not
Accompanying coding to update list of last opened files on demand
Version no update to v0.6.3
2012-04-14 17:53:11 +01:00
Matt Pass
82fd2a5b5d Handling of unsaved changes & loading of previous files
Closing or reloading the window now checks for unsaved files and alerts user
Filenames opened in previous session loaded into array on start
If we have the setting on to open these files, they are opened sequentially on load
2012-04-14 17:44:02 +01:00
Matt Pass
e297fd049f Ruby code highlighting mode added
Mode added from CodeMirror modes lib to handle highlighting of Ruby coding
2012-04-14 17:36:44 +01:00
Matt Pass
ef9d8ed5de Nest hover/click function, better code folding plus error catching
You can now hover mouse over nest positions to have them selected
Can also click to set cursor position to within that nest
Removed old code folding function in favour of lib that comes with CodeMirror
Errors catched so clicking on a blank area of the file manager doesn't attempt anything
2012-04-07 21:17:33 +01:00
Matt Pass
07e44ecfb5 Overwrite permission prompt plus better display & error catching
Now asks for overwrite permission if saving new file or save as over another file
Server message now shows your new filename when saving
Error catching so if not saving it clears server message
2012-04-07 21:14:24 +01:00
Matt Pass
fee53144d9 Code folding upon gutter click
New fileName var
CodeMirror lib used to allow folding of code on clicking gutter
HTML folds on <tags> and JS & PHP fold on {braces}
+ in gutter indicates folded area
2012-04-07 21:11:45 +01:00
Matt Pass
e899c2f1bd Version no. update to v0.6.2 2012-04-07 20:27:40 +01:00
Matt Pass
579dc7d5d0 Version no update to v0.6.1 2012-04-05 07:58:09 +01:00
Matt Pass
bdb7433c4a Minor CSS adjustment to show pointer mouse cursor on file names 2012-04-05 07:54:28 +01:00
Matt Pass
2a2a631c99 Minor CSS adjustment to show default mouse cursor on gutter text 2012-04-05 07:53:56 +01:00
Matt Pass
a28213983b Hitting escape key outside of content area now cancels all actions
This stops parent from loading, hides the loading mask and clears server queue tasks other than one that is processing
Also displays message to inform you it's cancelled tasks
Function added to mediate file manager icon clicks to relevant functions
Icon visibility changes depending on actions you are taking and what is available to you right now
Simple function to handle icon visibility added
Code folding function added to allow collapsing and expanding of code blocks
(Its a bit slow & basic right now and only works for HTML, but improvements to come)
2012-04-05 07:52:57 +01:00
Matt Pass
0bcbc1a222 Account Options CSS added
New classes added to cover file manager icons
Also small adjustment to plugin icons position to line up with them
2012-04-05 07:46:48 +01:00
Matt Pass
978e2145e6 File Manager Icon Options Added
When you are logged in, in place of the login box there are now icons
These icons relate to tasks you can perform using key combos
Functions already established for these, though on click calls mediating function
Icons are mostly hidden by default, and light up/hide depending on functions available to you
2012-04-05 07:45:38 +01:00
Matt Pass
e4e75ccbef New file manager icons
Icons added to allow users option to click rather than press keys
Also means ICE coder now works with tablets as well as via mouse devices
These icons only show when you are logged in
2012-04-05 07:42:32 +01:00
Matt Pass
4a804e71df Interaction improvements via CSS and alternate functions
Pointing mouse over file manager icons now shows a CSS pointer cursor
On click of the HTML tag, selectFileFolder function is called, rather than just hide context menu
Calling this from HTML rather than body tag now
This in turn means the whole line for a file isn't clickable, just the name
2012-04-05 07:40:58 +01:00
Matt Pass
c758a2ff37 Gutter click now triggers code folding
Clicking gutter in CM editor triggers new code fold/expand function
2012-04-05 07:34:14 +01:00
Matt Pass
77aaa16be4 Extra nestTagException for ?php (not that it makes difference)
Removed ICEcoder.tD var as it was hardly used and theress no char saving really
Switched a few areas to ternary if statements
Code improvements, structure tidy up & improved commenting
Removed unnecessary code, stopped a few global vars
Also considering ?php as well as ?
Breaking tagEnd var on new lines to avoid nesting false errors
CTRL+I searches for highlighted word on Google in a context aware way
(ie, highlight 'echo' in a PHP block and it will search for 'PHP echo',
highlighting 'echo' in content area will search for just 'echo')
New function to select/deselect file/folder by changing CSS class
Only show New File and New Folder context menu options if we right clicked a folder
Simplified getcMInstance function
Improved commenting function to allow partial line commenting
Fixed issue with clicking plugin icons and server queue deletion on return
Fixed issue with CSS color blocks so they only show if they have a BG color
2012-04-01 12:43:18 +01:00
Matt Pass
215229d051 Fix & improvements to end tag postfixing, tab key & removing old code
Code assist now won't add an end tag if yours starts with a / (ie, it's already an end tag)
Also won't add an end tag if yours starts with ? (ie, it's ending a PHP block: ?>)
Switched from using the htmlTagArray to determin an end tag, to the tagString var
CodeMirror 2.23 handles tabs in a different way, so extraKeys has been set up to handle differently to new default
Old code removed related to showing results on clicking (now handled onChange as that's more efficient)
2012-04-01 12:18:04 +01:00
Matt Pass
dbf7e4e834 Span wrapper for dynamic context menu and fix to plugin icons clickability
New file and new folder options now inside span wrapper so it can be shown or not
(This is because these options are only suitable for folders and not files)
Fix to plugins that run through fileControl iFrame to make icon clickable again
2012-04-01 12:10:54 +01:00
Matt Pass
cafd79b03d Version & CodeMirror Update
Update ICEcoder to v0.6.0 and CodeMirror to v2.23
2012-04-01 12:07:17 +01:00
Matt Pass
0b1073fdbe Display server message
Now shows server message when loaded, to also cover clicking plugin icon
2012-04-01 12:05:21 +01:00
Matt Pass
d23171b8f1 Updated CodeMirror to v2.23 2012-04-01 12:04:00 +01:00
Matt Pass
64b026ca6e Removed CodeMirror v2.22
Update to v2.23
2012-04-01 12:01:03 +01:00
Matt Pass
422b013330 Minor bug fix to better detect file saving capabilities
Now tests if a file exists and is writable or is new before saving
Avoids false error problem
2012-03-26 07:54:11 +01:00
67 changed files with 2704 additions and 1254 deletions

View File

@@ -1,368 +0,0 @@
<!doctype html>
<html>
<head>
<title>CodeMirror</title>
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans:bold"/>
<link rel="stylesheet" type="text/css" href="doc/docs.css"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="alternate" href="http://twitter.com/statuses/user_timeline/242283288.rss" type="application/rss+xml"/>
</head>
<body>
<h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMirror</a></h1>
<pre class="grey">
<img src="doc/baboon.png" class="logo" alt="logo"/>/* In-browser code editing
made bearable */
</pre>
<div class="clear"><div class="left blk">
<p style="margin-top: 0">CodeMirror is a JavaScript library that can
be used to create a relatively pleasant editor interface for
code-like content &#x2015; computer programs, HTML markup, and
similar. If a mode has been written for the language you are
editing, the code will be coloured, and the editor will optionally
help you with indentation.</p>
<p>This is the project page for CodeMirror 2, the currently more
actively developed, and recommended
version. <a href="1/index.html">CodeMirror 1</a> is still available
from here.</p>
<div class="clear"><div class="left1 blk">
<h2 style="margin-top: 0">Supported modes:</h2>
<ul>
<li><a href="mode/clike/index.html">C, C++, Java, and similar</a></li>
<li><a href="mode/clojure/index.html">Clojure</a></li>
<li><a href="mode/coffeescript/index.html">CoffeeScript</a></li>
<li><a href="mode/css/index.html">CSS</a></li>
<li><a href="mode/diff/index.html">diff</a></li>
<li><a href="mode/ecl/index.html">ECL</a></li>
<li><a href="mode/go/index.html">Go</a></li>
<li><a href="mode/groovy/index.html">Groovy</a></li>
<li><a href="mode/haskell/index.html">Haskell</a></li>
<li><a href="mode/htmlembedded/index.html">HTML embedded scripts</a></li>
<li><a href="mode/htmlmixed/index.html">HTML mixed-mode</a></li>
<li><a href="mode/javascript/index.html">JavaScript</a></li>
<li><a href="mode/jinja2/index.html">Jinja2</a></li>
<li><a href="mode/less/index.html">LESS</a></li>
<li><a href="mode/lua/index.html">Lua</a></li>
<li><a href="mode/markdown/index.html">Markdown</a> (<a href="mode/gfm/index.html">Github-flavour</a>)</li>
<li><a href="mode/mysql/index.html">MySQL</a></li>
<li><a href="mode/ntriples/index.html">NTriples</a></li>
<li><a href="mode/pascal/index.html">Pascal</a></li>
<li><a href="mode/perl/index.html">Perl</a></li>
<li><a href="mode/php/index.html">PHP</a></li>
<li><a href="mode/plsql/index.html">PL/SQL</a></li>
<li><a href="mode/properties/index.html">Properties files</a></li>
<li><a href="mode/python/index.html">Python</a></li>
<li><a href="mode/r/index.html">R</a></li>
<li>RPM <a href="mode/rpm/spec/index.html">spec</a> and <a href="mode/rpm/changes/index.html">changelog</a></li>
<li><a href="mode/rst/index.html">reStructuredText</a></li>
<li><a href="mode/ruby/index.html">Ruby</a></li>
<li><a href="mode/rust/index.html">Rust</a></li>
<li><a href="mode/scheme/index.html">Scheme</a></li>
<li><a href="mode/smalltalk/index.html">Smalltalk</a></li>
<li><a href="mode/sparql/index.html">SPARQL</a></li>
<li><a href="mode/stex/index.html">sTeX, LaTeX</a></li>
<li><a href="mode/tiddlywiki/index.html">Tiddlywiki</a></li>
<li><a href="mode/velocity/index.html">Velocity</a></li>
<li><a href="mode/verilog/index.html">Verilog</a></li>
<li><a href="mode/xml/index.html">XML/HTML</a> (<a href="mode/xmlpure/index.html">alternative XML</a>)</li>
<li><a href="mode/yaml/index.html">YAML</a></li>
</ul>
</div><div class="left2 blk">
<h2 style="margin-top: 0">Usage demos:</h2>
<ul>
<li><a href="demo/complete.html">Autocompletion</a></li>
<li><a href="demo/mustache.html">Mode overlays</a></li>
<li><a href="demo/search.html">Search/replace</a></li>
<li><a href="demo/folding.html">Code folding</a></li>
<li><a href="demo/preview.html">HTML editor with preview</a></li>
<li><a href="demo/resize.html">Auto-resizing editor</a></li>
<li><a href="demo/marker.html">Setting breakpoints</a></li>
<li><a href="demo/activeline.html">Highlighting the current line</a></li>
<li><a href="demo/matchhighlighter.html">Highlighting selection matches</a></li>
<li><a href="demo/theme.html">Theming</a></li>
<li><a href="demo/runmode.html">Stand-alone highlighting</a></li>
<li><a href="demo/fullscreen.html">Full-screen editing</a></li>
<li><a href="demo/changemode.html">Mode auto-changing</a></li>
<li><a href="demo/visibletabs.html">Visible tabs</a></li>
<li><a href="demo/formatting.html">Autoformatting of code</a></li>
<li><a href="demo/emacs.html">Emacs keybindings</a></li>
<li><a href="demo/vim.html">Vim keybindings</a></li>
</ul>
<h2>Real-world uses:</h2>
<ul>
<li><a href="http://jsbin.com">jsbin.com</a> (JS playground)</li>
<li><a href="http://buzzard.ups.edu/">Sage demo</a> (math system)</li>
<li><a href="http://www.sourcelair.com/">sourceLair</a> (online IDE)</li>
<li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</a></li>
<li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
<li><a href="http://paperjs.org/">Paper.js</a> (graphics scripting)</li>
<li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
<li><a href="http://webglplayground.net/">WebGL playground</a></li>
<li><a href="http://ql.io/">ql.io</a> (http API query helper)</li>
<li><a href="http://elm-lang.org/Examples.elm">Elm language examples</a></li>
<li><a href="http://bluegriffon.org/">BlueGriffon</a> (HTML editor)</li>
<li><a href="http://www.jshint.com/">JSHint</a> (JS linter)</li>
<li><a href="http://kl1p.com/cmtest/1">kl1p</a> (paste service)</li>
</ul>
</div></div>
<h2 id="code">Getting the code</h2>
<p>All of CodeMirror is released under a <a
href="LICENSE">MIT-style</a> license. To get it, you can download
the <a href="http://codemirror.net/codemirror.zip">latest
release</a> or the current <a
href="http://codemirror.net/codemirror2-latest.zip">development
snapshot</a> as zip files. To create a custom minified script file,
you can use the <a href="doc/compress.html">compression API</a>.</p>
<p>We use <a href="http://git-scm.com/">git</a> for version control.
The main repository can be fetched in this way:</p>
<pre class="code">git clone http://marijnhaverbeke.nl/git/codemirror2</pre>
<p>CodeMirror can also be found on GitHub at <a
href="http://github.com/marijnh/CodeMirror2">marijnh/CodeMirror2</a>.
If you plan to hack on the code and contribute patches, the best way
to do it is to create a GitHub fork, and send pull requests.</p>
<h2 id="documention">Documentation</h2>
<p>The <a href="doc/manual.html">manual</a> is your first stop for
learning how to use this library. It starts with a quick explanation
of how to use the editor, and then describes the API in detail.</p>
<p>For those who want to learn more about the code, there is
an <a href="doc/internals.html">overview of the internals</a> available.
The <a href="http://github.com/marijnh/CodeMirror2">source code</a>
itself is, for the most part, also well commented.</p>
<h2 id="support">Support and bug reports</h2>
<p>There is
a <a href="http://groups.google.com/group/codemirror">Google
group</a> (a sort of mailing list/newsgroup thing) for discussion
and news related to CodeMirror. When reporting a bug,
<a href="doc/reporting.html">read this first</a>. If you have
a <a href="http://github.com">github</a> account,
simply <a href="http://github.com/marijnh/CodeMirror2/issues">open
an issue there</a>. Otherwise, post something to
the <a href="http://groups.google.com/group/codemirror">group</a>,
or e-mail me directly: <a href="mailto:marijnh@gmail.com">Marijn
Haverbeke</a>.</p>
<h2 id="supported">Supported browsers</h2>
<p>The following browsers are able to run CodeMirror:</p>
<ul>
<li>Firefox 2 or higher</li>
<li>Chrome, any version</li>
<li>Safari 3 or higher</li>
<li>Internet Explorer 6 or higher in standards (<strong>non-quirks</strong>) mode</li>
<li>Opera 9 or higher (with some key-handling problems on OS X)</li>
</ul>
<p>I am not actively testing against every new browser release, and
vendors have a habit of introducing bugs all the time, so I am
relying on the community to tell me when something breaks.
See <a href="#support">here</a> for information on how to contact
me.</p>
<h2 id="commercial">Commercial support</h2>
<p>CodeMirror is developed and maintained by me, Marijn Haverbeke,
in my own time. If your company is getting value out of CodeMirror,
please consider purchasing a support contract.</p>
<ul>
<li>You'll be funding further work on CodeMirror.</li>
<li>You ensure that you get a quick response when you have a
problem, even when I am otherwise busy.</li>
</ul>
<p>CodeMirror support contracts exist in two
forms—<strong>basic</strong> at €100 per month,
and <strong>premium</strong> at €500 per
month. <a href="mailto:marijnh@gmail.com">Contact me</a> for further
information.</p>
</div>
<div class="right blk">
<a href="http://codemirror.net/codemirror.zip" class="download">Download the latest release</a>
<h2>Support CodeMirror</h2>
<ul>
<li>Donate
(<span onclick="document.getElementById('paypal').submit();"
class="quasilink">Paypal</span>
or <span onclick="document.getElementById('bankinfo').style.display = 'block';"
class="quasilink">bank</span>)</li>
<li>Purchase <a href="#commercial">commercial support</a></li>
</ul>
<p id="bankinfo" style="display: none;">
Bank: <i>Rabobank</i><br/>
Country: <i>Netherlands</i><br/>
SWIFT: <i>RABONL2U</i><br/>
Account: <i>147850770</i><br/>
Name: <i>Marijn Haverbeke</i><br/>
IBAN: <i>NL26 RABO 0147 8507 70</i>
</p>
<h2>Releases:</h2>
<p class="rel">27-02-2012: <a href="http://codemirror.net/codemirror-2.22.zip">Version 2.22</a>:</p>
<ul class="rel-note">
<li>Allow <a href="doc/manual.html#keymaps">key handlers</a> to pass up events, allow binding characters.</li>
<li>Add <a href="doc/manual.html#option_autoClearEmptyLines"><code>autoClearEmptyLines</code></a> option.</li>
<li>Properly use tab stops when rendering tabs.</li>
<li>Make PHP mode more robust.</li>
<li>Support indentation blocks in <a href="doc/manual.html#util_foldcode">code folder</a>.</li>
<li>Add a script for <a href="doc/manual.html#util_match-highlighter">highlighting instances of the selection</a>.</li>
<li>New <a href="mode/properties/index.html">.properties</a> mode.</li>
<li>Fix many bugs.</li>
</ul>
<p class="rel">27-01-2012: <a href="http://codemirror.net/codemirror-2.21.zip">Version 2.21</a>:</p>
<ul class="rel-note">
<li>Added <a href="mode/less/index.html">LESS</a>, <a href="mode/mysql/index.html">MySQL</a>,
<a href="mode/go/index.html">Go</a>, and <a href="mode/verilog/index.html">Verilog</a> modes.</li>
<li>Add <a href="doc/manual.html#option_smartIndent"><code>smartIndent</code></a>
option.</li>
<li>Support a cursor in <a href="doc/manual.html#option_readOnly"><code>readOnly</code></a>-mode.</li>
<li>Support assigning multiple styles to a token.</li>
<li>Use a new approach to drawing the selection.</li>
<li>Add <a href="doc/manual.html#scrollTo"><code>scrollTo</code></a> method.</li>
<li>Allow undo/redo events to span non-adjacent lines.</li>
<li>Lots and lots of bugfixes.</li>
</ul>
<p class="rel">20-12-2011: <a href="http://codemirror.net/codemirror-2.2.zip">Version 2.2</a>:</p>
<ul class="rel-note">
<li>Slightly incompatible API changes. Read <a href="doc/upgrade_v2.2.html">this</a>.</li>
<li>New approach
to <a href="doc/manual.html#option_extraKeys">binding</a> keys,
support for <a href="doc/manual.html#option_keyMap">custom
bindings</a>.</li>
<li>Support for overwrite (insert).</li>
<li><a href="doc/manual.html#option_tabSize">Custom-width</a>
and <a href="demo/visibletabs.html">stylable</a> tabs.</li>
<li>Moved more code into <a href="doc/manual.html#addons">add-on scripts</a>.</li>
<li>Support for sane vertical cursor movement in wrapped lines.</li>
<li>More reliable handling of
editing <a href="doc/manual.html#markText">marked text</a>.</li>
<li>Add minimal <a href="demo/emacs.html">emacs</a>
and <a href="demo/vim.html">vim</a> bindings.</li>
<li>Rename <code>coordsFromIndex</code>
to <a href="doc/manual.html#posFromIndex"><code>posFromIndex</code></a>,
add <a href="doc/manual.html#indexFromPos"><code>indexFromPos</code></a>
method.</li>
</ul>
<p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.18.zip">Version 2.18</a>:</p>
<p class="rel-note">Fixes <code>TextMarker.clear</code>, which is broken in 2.17.</p>
<p class="rel">21-11-2011: <a href="http://codemirror.net/codemirror-2.17.zip">Version 2.17</a>:</p>
<ul class="rel-note">
<li>Add support for <a href="doc/manual.html#option_lineWrapping">line
wrapping</a> and <a href="doc/manual.html#hideLine">code
folding</a>.</li>
<li>Add <a href="mode/gfm/index.html">Github-style Markdown</a> mode.</li>
<li>Add <a href="theme/monokai.css">Monokai</a>
and <a href="theme/rubyblue.css">Rubyblue</a> themes.</li>
<li>Add <a href="doc/manual.html#setBookmark"><code>setBookmark</code></a> method.</li>
<li>Move some of the demo code into reusable components
under <a href="lib/util/"><code>lib/util</code></a>.</li>
<li>Make screen-coord-finding code faster and more reliable.</li>
<li>Fix drag-and-drop in Firefox.</li>
<li>Improve support for IME.</li>
<li>Speed up content rendering.</li>
<li>Fix browser's built-in search in Webkit.</li>
<li>Make double- and triple-click work in IE.</li>
<li>Various fixes to modes.</li>
</ul>
<p class="rel">27-10-2011: <a href="http://codemirror.net/codemirror-2.16.zip">Version 2.16</a>:</p>
<ul class="rel-note">
<li>Add <a href="mode/perl/index.html">Perl</a>, <a href="mode/rust/index.html">Rust</a>, <a href="mode/tiddlywiki/index.html">TiddlyWiki</a>, and <a href="mode/groovy/index.html">Groovy</a> modes.</li>
<li>Dragging text inside the editor now moves, rather than copies.</li>
<li>Add a <a href="doc/manual.html#coordsFromIndex"><code>coordsFromIndex</code></a> method.</li>
<li><strong>API change</strong>: <code>setValue</code> now no longer clears history. Use <a href="doc/manual.html#clearHistory"><code>clearHistory</code></a> for that.</li>
<li><strong>API change</strong>: <a href="doc/manual.html#markText"><code>markText</code></a> now
returns an object with <code>clear</code> and <code>find</code>
methods. Marked text is now more robust when edited.</li>
<li>Fix editing code with tabs in Internet Explorer.</li>
</ul>
<p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.15.zip">Version 2.15</a>:</p>
<p class="rel-note">Fix bug that snuck into 2.14: Clicking the
character that currently has the cursor didn't re-focus the
editor.</p>
<p class="rel">26-09-2011: <a href="http://codemirror.net/codemirror-2.14.zip">Version 2.14</a>:</p>
<ul class="rel-note">
<li>Add <a href="mode/clojure/index.html">Clojure</a>, <a href="mode/pascal/index.html">Pascal</a>, <a href="mode/ntriples/index.html">NTriples</a>, <a href="mode/jinja2/index.html">Jinja2</a>, and <a href="mode/markdown/index.html">Markdown</a> modes.</li>
<li>Add <a href="theme/cobalt.css">Cobalt</a> and <a href="theme/eclipse.css">Eclipse</a> themes.</li>
<li>Add a <a href="doc/manual.html#option_fixedGutter"><code>fixedGutter</code></a> option.</li>
<li>Fix bug with <code>setValue</code> breaking cursor movement.</li>
<li>Make gutter updates much more efficient.</li>
<li>Allow dragging of text out of the editor (on modern browsers).</li>
</ul>
<p class="rel">23-08-2011: <a href="http://codemirror.net/codemirror-2.13.zip">Version 2.13</a>:</p>
<ul class="rel-note">
<li>Add <a href="mode/ruby/index.html">Ruby</a>, <a href="mode/r/index.html">R</a>, <a href="mode/coffeescript/index.html">CoffeeScript</a>, and <a href="mode/velocity/index.html">Velocity</a> modes.</li>
<li>Add <a href="doc/manual.html#getGutterElement"><code>getGutterElement</code></a> to API.</li>
<li>Several fixes to scrolling and positioning.</li>
<li>Add <a href="doc/manual.html#option_smartHome"><code>smartHome</code></a> option.</li>
<li>Add an experimental <a href="mode/xmlpure/index.html">pure XML</a> mode.</li>
</ul>
<p class="rel">25-07-2011: <a href="http://codemirror.net/codemirror-2.12.zip">Version 2.12</a>:</p>
<ul class="rel-note">
<li>Add a <a href="mode/sparql/index.html">SPARQL</a> mode.</li>
<li>Fix bug with cursor jumping around in an unfocused editor in IE.</li>
<li>Allow key and mouse events to bubble out of the editor. Ignore widget clicks.</li>
<li>Solve cursor flakiness after undo/redo.</li>
<li>Fix block-reindent ignoring the last few lines.</li>
<li>Fix parsing of multi-line attrs in XML mode.</li>
<li>Use <code>innerHTML</code> for HTML-escaping.</li>
<li>Some fixes to indentation in C-like mode.</li>
<li>Shrink horiz scrollbars when long lines removed.</li>
<li>Fix width feedback loop bug that caused the width of an inner DIV to shrink.</li>
</ul>
<p><a href="doc/oldrelease.html">Older releases...</a></p>
</div></div>
<div style="height: 2em">&nbsp;</div>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" name="hosted_button_id" value="3FVHS5FGUY7CC"/>
</form>
</body>
</html>

View File

@@ -1,347 +0,0 @@
(function() {
var count = "";
var sdir = "f";
var buf = "";
var yank = 0;
var mark = [];
function emptyBuffer() { buf = ""; }
function pushInBuffer(str) { buf += str; };
function pushCountDigit(digit) { return function(cm) {count += digit;} }
function popCount() { var i = parseInt(count); count = ""; return i || 1; }
function countTimes(func) {
if (typeof func == "string") func = CodeMirror.commands[func];
return function(cm) { for (var i = 0, c = popCount(); i < c; ++i) func(cm); }
}
function iterObj(o, f) {
for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
}
var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
function findWord(line, pos, dir, regexps) {
var stop = 0, next = -1;
if (dir > 0) { stop = line.length; next = 0; }
var start = stop, end = stop;
// Find bounds of next one.
outer: for (; pos != stop; pos += dir) {
for (var i = 0; i < regexps.length; ++i) {
if (regexps[i].test(line.charAt(pos + next))) {
start = pos;
for (; pos != stop; pos += dir) {
if (!regexps[i].test(line.charAt(pos + next))) break;
}
end = pos;
break outer;
}
}
}
return {from: Math.min(start, end), to: Math.max(start, end)};
}
function moveToWord(cm, regexps, dir, where) {
var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line), word;
while (true) {
word = findWord(line, ch, dir, regexps);
ch = word[where == "end" ? "to" : "from"];
if (ch == cur.ch && word.from != word.to) ch = word[dir < 0 ? "from" : "to"];
else break;
}
cm.setCursor(cur.line, word[where == "end" ? "to" : "from"], true);
}
function joinLineNext(cm) {
var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line);
CodeMirror.commands.goLineEnd(cm);
if (cur.line != cm.lineCount()) {
CodeMirror.commands.goLineEnd(cm);
cm.replaceSelection(" ", "end");
CodeMirror.commands.delCharRight(cm);
}
}
function editCursor(mode) {
if (mode == "vim-insert") {
// put in your cursor css changing code
} else if (mode == "vim") {
// put in your cursor css changing code
}
}
function delTillMark(cm, cHar) {
var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
cm.setCursor(start);
for (var c = start; c <= end; c++) {
pushInBuffer("\n"+cm.getLine(start));
cm.removeLine(start);
}
}
function yankTillMark(cm, cHar) {
var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
for (var c = start; c <= end; c++) {
pushInBuffer("\n"+cm.getLine(c));
}
cm.setCursor(start);
}
var map = CodeMirror.keyMap.vim = {
"0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);},
"A": function(cm) {popCount(); cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"Shift-A": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"Shift-I": function(cm) {popCount(); CodeMirror.commands.goLineStartSmart(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"O": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.replaceSelection("\n", "end"); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"Shift-O": function(cm) {popCount(); CodeMirror.commands.goLineStart(cm); cm.replaceSelection("\n", "start"); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");},
"D": function(cm) {cm.setOption("keyMap", "vim-prefix-d"); emptyBuffer();},
"M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
"Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
"/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f"},
"Shift-/": function(cm) {
var f = CodeMirror.commands.find;
if (f) { f(cm); CodeMirror.commands.findPrev(cm); sdir = "r"; }
},
"N": function(cm) {
var fn = CodeMirror.commands.findNext;
if (fn) sdir != "r" ? fn(cm) : CodeMirror.commands.findPrev(cm);
},
"Shift-N": function(cm) {
var fn = CodeMirror.commands.findNext;
if (fn) sdir != "r" ? CodeMirror.commands.findPrev(cm) : fn.findNext(cm);
},
"Shift-G": function(cm) {count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count)-1); popCount(); CodeMirror.commands.goLineStart(cm);},
catchall: function(cm) {/*ignore*/}
};
// Add bindings for number keys
for (var i = 1; i < 10; ++i) map[i] = pushCountDigit(i);
// Add bindings that are influenced by number keys
iterObj({"H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown", "K": "goLineUp",
"Left": "goColumnLeft", "Right": "goColumnRight", "Down": "goLineDown", "Up": "goLineUp",
"Backspace": "goCharLeft", "Space": "goCharRight",
"B": function(cm) {moveToWord(cm, word, -1, "end");},
"E": function(cm) {moveToWord(cm, word, 1, "end");},
"W": function(cm) {moveToWord(cm, word, 1, "start");},
"Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");},
"Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");},
"Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");},
"X": function(cm) {CodeMirror.commands.delCharRight(cm)},
"P": function(cm) {
var cur = cm.getCursor().line;
if (buf!= "") {
CodeMirror.commands.goLineEnd(cm);
cm.replaceSelection(buf, "end");
}
cm.setCursor(cur+1);
},
"Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm)},
"Shift-J": function(cm) {joinLineNext(cm)},
"Shift-`": function(cm) {
var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
cm.setCursor(cur.line, cur.ch+1);
},
"Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm)},
"Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm)},
"Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
"U": "undo", "Ctrl-R": "redo", "Shift-4": "goLineEnd"},
function(key, cmd) { map[key] = countTimes(cmd); });
CodeMirror.keyMap["vim-prefix-g"] = {
"E": countTimes(function(cm) { moveToWord(cm, word, -1, "start");}),
"Shift-E": countTimes(function(cm) { moveToWord(cm, bigWord, -1, "start");}),
auto: "vim",
catchall: function(cm) {/*ignore*/}
};
CodeMirror.keyMap["vim-prefix-m"] = {
"A": function(cm) {mark["A"] = cm.getCursor().line;},
"Shift-A": function(cm) {mark["Shift-A"] = cm.getCursor().line;},
"B": function(cm) {mark["B"] = cm.getCursor().line;},
"Shift-B": function(cm) {mark["Shift-B"] = cm.getCursor().line;},
"C": function(cm) {mark["C"] = cm.getCursor().line;},
"Shift-C": function(cm) {mark["Shift-C"] = cm.getCursor().line;},
"D": function(cm) {mark["D"] = cm.getCursor().line;},
"Shift-D": function(cm) {mark["Shift-D"] = cm.getCursor().line;},
"E": function(cm) {mark["E"] = cm.getCursor().line;},
"Shift-E": function(cm) {mark["Shift-E"] = cm.getCursor().line;},
"F": function(cm) {mark["F"] = cm.getCursor().line;},
"Shift-F": function(cm) {mark["Shift-F"] = cm.getCursor().line;},
"G": function(cm) {mark["G"] = cm.getCursor().line;},
"Shift-G": function(cm) {mark["Shift-G"] = cm.getCursor().line;},
"H": function(cm) {mark["H"] = cm.getCursor().line;},
"Shift-H": function(cm) {mark["Shift-H"] = cm.getCursor().line;},
"I": function(cm) {mark["I"] = cm.getCursor().line;},
"Shift-I": function(cm) {mark["Shift-I"] = cm.getCursor().line;},
"J": function(cm) {mark["J"] = cm.getCursor().line;},
"Shift-J": function(cm) {mark["Shift-J"] = cm.getCursor().line;},
"K": function(cm) {mark["K"] = cm.getCursor().line;},
"Shift-K": function(cm) {mark["Shift-K"] = cm.getCursor().line;},
"L": function(cm) {mark["L"] = cm.getCursor().line;},
"Shift-L": function(cm) {mark["Shift-L"] = cm.getCursor().line;},
"M": function(cm) {mark["M"] = cm.getCursor().line;},
"Shift-M": function(cm) {mark["Shift-M"] = cm.getCursor().line;},
"N": function(cm) {mark["N"] = cm.getCursor().line;},
"Shift-N": function(cm) {mark["Shift-N"] = cm.getCursor().line;},
"O": function(cm) {mark["O"] = cm.getCursor().line;},
"Shift-O": function(cm) {mark["Shift-O"] = cm.getCursor().line;},
"P": function(cm) {mark["P"] = cm.getCursor().line;},
"Shift-P": function(cm) {mark["Shift-P"] = cm.getCursor().line;},
"Q": function(cm) {mark["Q"] = cm.getCursor().line;},
"Shift-Q": function(cm) {mark["Shift-Q"] = cm.getCursor().line;},
"R": function(cm) {mark["R"] = cm.getCursor().line;},
"Shift-R": function(cm) {mark["Shift-R"] = cm.getCursor().line;},
"S": function(cm) {mark["S"] = cm.getCursor().line;},
"Shift-S": function(cm) {mark["Shift-S"] = cm.getCursor().line;},
"T": function(cm) {mark["T"] = cm.getCursor().line;},
"Shift-T": function(cm) {mark["Shift-T"] = cm.getCursor().line;},
"U": function(cm) {mark["U"] = cm.getCursor().line;},
"Shift-U": function(cm) {mark["Shift-U"] = cm.getCursor().line;},
"V": function(cm) {mark["V"] = cm.getCursor().line;},
"Shift-V": function(cm) {mark["Shift-V"] = cm.getCursor().line;},
"W": function(cm) {mark["W"] = cm.getCursor().line;},
"Shift-W": function(cm) {mark["Shift-W"] = cm.getCursor().line;},
"X": function(cm) {mark["X"] = cm.getCursor().line;},
"Shift-X": function(cm) {mark["Shift-X"] = cm.getCursor().line;},
"Y": function(cm) {mark["Y"] = cm.getCursor().line;},
"Shift-Y": function(cm) {mark["Shift-Y"] = cm.getCursor().line;},
"Z": function(cm) {mark["Z"] = cm.getCursor().line;},
"Shift-Z": function(cm) {mark["Shift-Z"] = cm.getCursor().line;},
auto: "vim",
catchall: function(cm) {/*ignore*/}
}
CodeMirror.keyMap["vim-prefix-d"] = {
"D": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line)); cm.removeLine(cm.getCursor().line); }),
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-d'"); emptyBuffer();},
auto: "vim",
catchall: function(cm) {/*ignore*/}
};
CodeMirror.keyMap["vim-prefix-d'"] = {
"A": function(cm) {delTillMark(cm,"A");},
"Shift-A": function(cm) {delTillMark(cm,"Shift-A");},
"B": function(cm) {delTillMark(cm,"B");},
"Shift-B": function(cm) {delTillMark(cm,"Shift-B");},
"C": function(cm) {delTillMark(cm,"C");},
"Shift-C": function(cm) {delTillMark(cm,"Shift-C");},
"D": function(cm) {delTillMark(cm,"D");},
"Shift-D": function(cm) {delTillMark(cm,"Shift-D");},
"E": function(cm) {delTillMark(cm,"E");},
"Shift-E": function(cm) {delTillMark(cm,"Shift-E");},
"F": function(cm) {delTillMark(cm,"F");},
"Shift-F": function(cm) {delTillMark(cm,"Shift-F");},
"G": function(cm) {delTillMark(cm,"G");},
"Shift-G": function(cm) {delTillMark(cm,"Shift-G");},
"H": function(cm) {delTillMark(cm,"H");},
"Shift-H": function(cm) {delTillMark(cm,"Shift-H");},
"I": function(cm) {delTillMark(cm,"I");},
"Shift-I": function(cm) {delTillMark(cm,"Shift-I");},
"J": function(cm) {delTillMark(cm,"J");},
"Shift-J": function(cm) {delTillMark(cm,"Shift-J");},
"K": function(cm) {delTillMark(cm,"K");},
"Shift-K": function(cm) {delTillMark(cm,"Shift-K");},
"L": function(cm) {delTillMark(cm,"L");},
"Shift-L": function(cm) {delTillMark(cm,"Shift-L");},
"M": function(cm) {delTillMark(cm,"M");},
"Shift-M": function(cm) {delTillMark(cm,"Shift-M");},
"N": function(cm) {delTillMark(cm,"N");},
"Shift-N": function(cm) {delTillMark(cm,"Shift-N");},
"O": function(cm) {delTillMark(cm,"O");},
"Shift-O": function(cm) {delTillMark(cm,"Shift-O");},
"P": function(cm) {delTillMark(cm,"P");},
"Shift-P": function(cm) {delTillMark(cm,"Shift-P");},
"Q": function(cm) {delTillMark(cm,"Q");},
"Shift-Q": function(cm) {delTillMark(cm,"Shift-Q");},
"R": function(cm) {delTillMark(cm,"R");},
"Shift-R": function(cm) {delTillMark(cm,"Shift-R");},
"S": function(cm) {delTillMark(cm,"S");},
"Shift-S": function(cm) {delTillMark(cm,"Shift-S");},
"T": function(cm) {delTillMark(cm,"T");},
"Shift-T": function(cm) {delTillMark(cm,"Shift-T");},
"U": function(cm) {delTillMark(cm,"U");},
"Shift-U": function(cm) {delTillMark(cm,"Shift-U");},
"V": function(cm) {delTillMark(cm,"V");},
"Shift-V": function(cm) {delTillMark(cm,"Shift-V");},
"W": function(cm) {delTillMark(cm,"W");},
"Shift-W": function(cm) {delTillMark(cm,"Shift-W");},
"X": function(cm) {delTillMark(cm,"X");},
"Shift-X": function(cm) {delTillMark(cm,"Shift-X");},
"Y": function(cm) {delTillMark(cm,"Y");},
"Shift-Y": function(cm) {delTillMark(cm,"Shift-Y");},
"Z": function(cm) {delTillMark(cm,"Z");},
"Shift-Z": function(cm) {delTillMark(cm,"Shift-Z");},
auto: "vim",
catchall: function(cm) {/*ignore*/}
};
CodeMirror.keyMap["vim-prefix-y'"] = {
"A": function(cm) {yankTillMark(cm,"A");},
"Shift-A": function(cm) {yankTillMark(cm,"Shift-A");},
"B": function(cm) {yankTillMark(cm,"B");},
"Shift-B": function(cm) {yankTillMark(cm,"Shift-B");},
"C": function(cm) {yankTillMark(cm,"C");},
"Shift-C": function(cm) {yankTillMark(cm,"Shift-C");},
"D": function(cm) {yankTillMark(cm,"D");},
"Shift-D": function(cm) {yankTillMark(cm,"Shift-D");},
"E": function(cm) {yankTillMark(cm,"E");},
"Shift-E": function(cm) {yankTillMark(cm,"Shift-E");},
"F": function(cm) {yankTillMark(cm,"F");},
"Shift-F": function(cm) {yankTillMark(cm,"Shift-F");},
"G": function(cm) {yankTillMark(cm,"G");},
"Shift-G": function(cm) {yankTillMark(cm,"Shift-G");},
"H": function(cm) {yankTillMark(cm,"H");},
"Shift-H": function(cm) {yankTillMark(cm,"Shift-H");},
"I": function(cm) {yankTillMark(cm,"I");},
"Shift-I": function(cm) {yankTillMark(cm,"Shift-I");},
"J": function(cm) {yankTillMark(cm,"J");},
"Shift-J": function(cm) {yankTillMark(cm,"Shift-J");},
"K": function(cm) {yankTillMark(cm,"K");},
"Shift-K": function(cm) {yankTillMark(cm,"Shift-K");},
"L": function(cm) {yankTillMark(cm,"L");},
"Shift-L": function(cm) {yankTillMark(cm,"Shift-L");},
"M": function(cm) {yankTillMark(cm,"M");},
"Shift-M": function(cm) {yankTillMark(cm,"Shift-M");},
"N": function(cm) {yankTillMark(cm,"N");},
"Shift-N": function(cm) {yankTillMark(cm,"Shift-N");},
"O": function(cm) {yankTillMark(cm,"O");},
"Shift-O": function(cm) {yankTillMark(cm,"Shift-O");},
"P": function(cm) {yankTillMark(cm,"P");},
"Shift-P": function(cm) {yankTillMark(cm,"Shift-P");},
"Q": function(cm) {yankTillMark(cm,"Q");},
"Shift-Q": function(cm) {yankTillMark(cm,"Shift-Q");},
"R": function(cm) {yankTillMark(cm,"R");},
"Shift-R": function(cm) {yankTillMark(cm,"Shift-R");},
"S": function(cm) {yankTillMark(cm,"S");},
"Shift-S": function(cm) {yankTillMark(cm,"Shift-S");},
"T": function(cm) {yankTillMark(cm,"T");},
"Shift-T": function(cm) {yankTillMark(cm,"Shift-T");},
"U": function(cm) {yankTillMark(cm,"U");},
"Shift-U": function(cm) {yankTillMark(cm,"Shift-U");},
"V": function(cm) {yankTillMark(cm,"V");},
"Shift-V": function(cm) {yankTillMark(cm,"Shift-V");},
"W": function(cm) {yankTillMark(cm,"W");},
"Shift-W": function(cm) {yankTillMark(cm,"Shift-W");},
"X": function(cm) {yankTillMark(cm,"X");},
"Shift-X": function(cm) {yankTillMark(cm,"Shift-X");},
"Y": function(cm) {yankTillMark(cm,"Y");},
"Shift-Y": function(cm) {yankTillMark(cm,"Shift-Y");},
"Z": function(cm) {yankTillMark(cm,"Z");},
"Shift-Z": function(cm) {yankTillMark(cm,"Shift-Z");},
auto: "vim",
catchall: function(cm) {/*ignore*/}
};
CodeMirror.keyMap["vim-prefix-y"] = {
"Y": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line+yank)); yank++; }),
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-y'"); emptyBuffer();},
auto: "vim",
catchall: function(cm) {/*ignore*/}
};
CodeMirror.keyMap["vim-insert"] = {
"Esc": function(cm) {
cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
cm.setOption("keyMap", "vim");
editCursor("vim");
},
"Ctrl-N": function(cm) {/* Code to bring up autocomplete hint */},
"Ctrl-P": function(cm) {/* Code to bring up autocomplete hint */},
fallthrough: ["default"]
};
})();

View File

@@ -1,4 +1,4 @@
Copyright (C) 2011 by Marijn Haverbeke <marijnh@gmail.com>
Copyright (C) 2012 by Marijn Haverbeke <marijnh@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -24,6 +24,6 @@
CodeMirror.keyMap["emacs-Ctrl-X"] = {
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": "undo", "K": "close",
auto: "emacs", catchall: function(cm) {/*ignore*/}
auto: "emacs", nofallthrough: true
};
})();

View File

@@ -0,0 +1,230 @@
(function() {
var count = "";
var sdir = "f";
var buf = "";
var yank = 0;
var mark = [];
function emptyBuffer() { buf = ""; }
function pushInBuffer(str) { buf += str; };
function pushCountDigit(digit) { return function(cm) {count += digit;} }
function popCount() { var i = parseInt(count); count = ""; return i || 1; }
function countTimes(func) {
if (typeof func == "string") func = CodeMirror.commands[func];
return function(cm) { for (var i = 0, c = popCount(); i < c; ++i) func(cm); }
}
function iterObj(o, f) {
for (var prop in o) if (o.hasOwnProperty(prop)) f(prop, o[prop]);
}
var word = [/\w/, /[^\w\s]/], bigWord = [/\S/];
function findWord(line, pos, dir, regexps) {
var stop = 0, next = -1;
if (dir > 0) { stop = line.length; next = 0; }
var start = stop, end = stop;
// Find bounds of next one.
outer: for (; pos != stop; pos += dir) {
for (var i = 0; i < regexps.length; ++i) {
if (regexps[i].test(line.charAt(pos + next))) {
start = pos;
for (; pos != stop; pos += dir) {
if (!regexps[i].test(line.charAt(pos + next))) break;
}
end = pos;
break outer;
}
}
}
return {from: Math.min(start, end), to: Math.max(start, end)};
}
function moveToWord(cm, regexps, dir, where) {
var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line), word;
while (true) {
word = findWord(line, ch, dir, regexps);
ch = word[where == "end" ? "to" : "from"];
if (ch == cur.ch && word.from != word.to) ch = word[dir < 0 ? "from" : "to"];
else break;
}
cm.setCursor(cur.line, word[where == "end" ? "to" : "from"], true);
}
function joinLineNext(cm) {
var cur = cm.getCursor(), ch = cur.ch, line = cm.getLine(cur.line);
CodeMirror.commands.goLineEnd(cm);
if (cur.line != cm.lineCount()) {
CodeMirror.commands.goLineEnd(cm);
cm.replaceSelection(" ", "end");
CodeMirror.commands.delCharRight(cm);
}
}
function editCursor(mode) {
if (mode == "vim-insert") {
// put in your cursor css changing code
} else if (mode == "vim") {
// put in your cursor css changing code
}
}
function delTillMark(cm, cHar) {
var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
cm.setCursor(start);
for (var c = start; c <= end; c++) {
pushInBuffer("\n"+cm.getLine(start));
cm.removeLine(start);
}
}
function yankTillMark(cm, cHar) {
var i = mark[cHar], l = cm.getCursor().line, start = i > l ? l : i, end = i > l ? i : l;
for (var c = start; c <= end; c++) {
pushInBuffer("\n"+cm.getLine(c));
}
cm.setCursor(start);
}
function goLineStartText(cm) {
// Go to the start of the line where the text begins, or the end for whitespace-only lines
var cur = cm.getCursor(), firstNonWS = cm.getLine(cur.line).search(/\S/);
cm.setCursor(cur.line, firstNonWS == -1 ? line.length : firstNonWS, true);
}
var map = CodeMirror.keyMap.vim = {
"0": function(cm) {count.length > 0 ? pushCountDigit("0")(cm) : CodeMirror.commands.goLineStart(cm);},
// Pipe (|); TODO: should be *screen* chars, so need a util function to turn tabs into spaces?
"'|'": function(cm) {cm.setCursor(cm.getCursor().line, popCount() - 1, true);},
"'^'": function(cm) {popCount(); goLineStartText(cm);},
"A": function(cm) {popCount(); cm.setCursor(cm.getCursor().line, cm.getCursor().ch+1, true); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"Shift-A": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"I": function(cm) {popCount(); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"Shift-I": function(cm) {popCount(); goLineStartText(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"O": function(cm) {popCount(); CodeMirror.commands.goLineEnd(cm); CodeMirror.commands.newlineAndIndent(cm); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"Shift-O": function(cm) {popCount(); CodeMirror.commands.goLineStart(cm); cm.replaceSelection("\n", "start"); cm.indentLine(cm.getCursor().line); cm.setOption("keyMap", "vim-insert"); editCursor("vim-insert");},
"G": function(cm) {cm.setOption("keyMap", "vim-prefix-g");},
"D": function(cm) {cm.setOption("keyMap", "vim-prefix-d"); emptyBuffer();},
"Shift-D": function(cm) {
emptyBuffer();
mark["Shift-D"] = cm.getCursor(false).line;
cm.setCursor(cm.getCursor(true).line);
delTillMark(cm,"Shift-D"); mark = [];
},
"M": function(cm) {cm.setOption("keyMap", "vim-prefix-m"); mark = [];},
"Y": function(cm) {cm.setOption("keyMap", "vim-prefix-y"); emptyBuffer(); yank = 0;},
"Shift-Y": function(cm) {
emptyBuffer();
mark["Shift-D"] = cm.getCursor(false).line;
cm.setCursor(cm.getCursor(true).line);
yankTillMark(cm,"Shift-D"); mark = [];
},
"/": function(cm) {var f = CodeMirror.commands.find; f && f(cm); sdir = "f"},
"'?'": function(cm) {
var f = CodeMirror.commands.find;
if (f) { f(cm); CodeMirror.commands.findPrev(cm); sdir = "r"; }
},
"N": function(cm) {
var fn = CodeMirror.commands.findNext;
if (fn) sdir != "r" ? fn(cm) : CodeMirror.commands.findPrev(cm);
},
"Shift-N": function(cm) {
var fn = CodeMirror.commands.findNext;
if (fn) sdir != "r" ? CodeMirror.commands.findPrev(cm) : fn.findNext(cm);
},
"Shift-G": function(cm) {count == "" ? cm.setCursor(cm.lineCount()) : cm.setCursor(parseInt(count)-1); popCount(); CodeMirror.commands.goLineStart(cm);},
nofallthrough: true
};
// Add bindings for number keys
for (var i = 1; i < 10; ++i) map[i] = pushCountDigit(i);
// Add bindings that are influenced by number keys
iterObj({
"H": "goColumnLeft", "L": "goColumnRight", "J": "goLineDown",
"K": "goLineUp", "Left": "goColumnLeft", "Right": "goColumnRight",
"Down": "goLineDown", "Up": "goLineUp", "Backspace": "goCharLeft",
"Space": "goCharRight",
"B": function(cm) {moveToWord(cm, word, -1, "end");},
"E": function(cm) {moveToWord(cm, word, 1, "end");},
"W": function(cm) {moveToWord(cm, word, 1, "start");},
"Shift-B": function(cm) {moveToWord(cm, bigWord, -1, "end");},
"Shift-E": function(cm) {moveToWord(cm, bigWord, 1, "end");},
"Shift-W": function(cm) {moveToWord(cm, bigWord, 1, "start");},
"X": function(cm) {CodeMirror.commands.delCharRight(cm)},
"P": function(cm) {
var cur = cm.getCursor().line;
if (buf!= "") {
CodeMirror.commands.goLineEnd(cm);
cm.replaceSelection(buf, "end");
}
cm.setCursor(cur+1);
},
"Shift-X": function(cm) {CodeMirror.commands.delCharLeft(cm)},
"Shift-J": function(cm) {joinLineNext(cm)},
"'~'": function(cm) {
var cur = cm.getCursor(), cHar = cm.getRange({line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
cHar = cHar != cHar.toLowerCase() ? cHar.toLowerCase() : cHar.toUpperCase();
cm.replaceRange(cHar, {line: cur.line, ch: cur.ch}, {line: cur.line, ch: cur.ch+1});
cm.setCursor(cur.line, cur.ch+1);
},
"Ctrl-B": function(cm) {CodeMirror.commands.goPageUp(cm)},
"Ctrl-F": function(cm) {CodeMirror.commands.goPageDown(cm)},
"Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
"U": "undo", "Ctrl-R": "redo", "'$'": "goLineEnd"
}, function(key, cmd) { map[key] = countTimes(cmd); });
CodeMirror.keyMap["vim-prefix-g"] = {
"E": countTimes(function(cm) { moveToWord(cm, word, -1, "start");}),
"Shift-E": countTimes(function(cm) { moveToWord(cm, bigWord, -1, "start");}),
auto: "vim",
nofallthrough: true
};
CodeMirror.keyMap["vim-prefix-m"] = {
auto: "vim",
nofallthrough: true
};
CodeMirror.keyMap["vim-prefix-d"] = {
"D": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line)); cm.removeLine(cm.getCursor().line); }),
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-d'"); emptyBuffer();},
auto: "vim",
nofallthrough: true
};
CodeMirror.keyMap["vim-prefix-d'"] = {
auto: "vim",
nofallthrough: true
};
CodeMirror.keyMap["vim-prefix-y'"] = {
auto: "vim",
nofallthrough: true
};
// iterate through uppercase alphabet char codes
for (var i = 65; i < 65 + 26; i++) {
// apply for `letter` and 'Shift-' + `letter`
for (var m = String.fromCharCode(i); m.length < 8; m = "Shift-" + m) {
CodeMirror.keyMap["vim-prefix-m"][m] = function(cm) {
mark[m] = cm.getCursor().line;
};
CodeMirror.keyMap["vim-prefix-d'"][m] = function(cm) {
delTillMark(cm,m);
};
CodeMirror.keyMap["vim-prefix-y'"][m] = function(cm) {
yankTillMark(cm,m);
};
}
}
CodeMirror.keyMap["vim-prefix-y"] = {
"Y": countTimes(function(cm) { pushInBuffer("\n"+cm.getLine(cm.getCursor().line+yank)); yank++; }),
"'": function(cm) {cm.setOption("keyMap", "vim-prefix-y'"); emptyBuffer();},
auto: "vim",
nofallthrough: true
};
CodeMirror.keyMap["vim-insert"] = {
// TODO: override navigation keys so that Esc will cancel automatic indentation from o, O, i_<CR>
"Esc": function(cm) {
cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
cm.setOption("keyMap", "vim");
editCursor("vim");
},
"Ctrl-N": function(cm) {/* Code to bring up autocomplete hint */},
"Ctrl-P": function(cm) {/* Code to bring up autocomplete hint */},
fallthrough: ["default"]
};
})();

View File

@@ -9,6 +9,7 @@
/* This is needed to prevent an IE[67] bug where the scrolled content
is visible outside of the scrolling box. */
position: relative;
outline: none;
}
.CodeMirror-gutter {
@@ -27,6 +28,7 @@
}
.CodeMirror-lines {
padding: .4em;
white-space: pre;
}
.CodeMirror pre {
@@ -40,11 +42,13 @@
padding: 0; margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;

View File

@@ -0,0 +1,174 @@
/**
* Tag-closer extension for CodeMirror.
*
* This extension adds a "closeTag" utility function that can be used with key bindings to
* insert a matching end tag after the ">" character of a start tag has been typed. It can
* also complete "</" if a matching start tag is found. It will correctly ignore signal
* characters for empty tags, comments, CDATA, etc.
*
* The function depends on internal parser state to identify tags. It is compatible with the
* following CodeMirror modes and will ignore all others:
* - htmlmixed
* - xml
* - xmlpure
*
* See demos/closetag.html for a usage example.
*
* @author Nathan Williams <nathan@nlwillia.net>
* Contributed under the same license terms as CodeMirror.
*/
(function() {
/** Option that allows tag closing behavior to be toggled. Default is true. */
CodeMirror.defaults['closeTagEnabled'] = true;
/** Array of tag names to add indentation after the start tag for. Default is the list of block-level html tags. */
CodeMirror.defaults['closeTagIndent'] = ['applet', 'blockquote', 'body', 'button', 'div', 'dl', 'fieldset', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', 'iframe', 'layer', 'legend', 'object', 'ol', 'p', 'select', 'table', 'ul'];
/**
* Call during key processing to close tags. Handles the key event if the tag is closed, otherwise throws CodeMirror.Pass.
* - cm: The editor instance.
* - ch: The character being processed.
* - indent: Optional. Omit or pass true to use the default indentation tag list defined in the 'closeTagIndent' option.
* Pass false to disable indentation. Pass an array to override the default list of tag names.
*/
CodeMirror.defineExtension("closeTag", function(cm, ch, indent) {
if (!cm.getOption('closeTagEnabled')) {
throw CodeMirror.Pass;
}
var mode = cm.getOption('mode');
if (mode == 'text/html') {
/*
* Relevant structure of token:
*
* htmlmixed
* className
* state
* htmlState
* type
* context
* tagName
* mode
*
* xml
* className
* state
* tagName
* type
*/
var pos = cm.getCursor();
var tok = cm.getTokenAt(pos);
var state = tok.state;
if (state.mode && state.mode != 'html') {
throw CodeMirror.Pass; // With htmlmixed, we only care about the html sub-mode.
}
if (ch == '>') {
var type = state.htmlState ? state.htmlState.type : state.type; // htmlmixed : xml
if (tok.className == 'tag' && type == 'closeTag') {
throw CodeMirror.Pass; // Don't process the '>' at the end of an end-tag.
}
cm.replaceSelection('>'); // Mode state won't update until we finish the tag.
pos = {line: pos.line, ch: pos.ch + 1};
cm.setCursor(pos);
tok = cm.getTokenAt(cm.getCursor());
state = tok.state;
type = state.htmlState ? state.htmlState.type : state.type; // htmlmixed : xml
if (tok.className == 'tag' && type != 'selfcloseTag') {
var tagName = state.htmlState ? state.htmlState.context.tagName : state.tagName; // htmlmixed : xml
if (tagName.length > 0) {
insertEndTag(cm, indent, pos, tagName);
}
return;
}
// Undo the '>' insert and allow cm to handle the key instead.
cm.setSelection({line: pos.line, ch: pos.ch - 1}, pos);
cm.replaceSelection("");
} else if (ch == '/') {
if (tok.className == 'tag' && tok.string == '<') {
var tagName = state.htmlState ? (state.htmlState.context ? state.htmlState.context.tagName : '') : state.context.tagName; // htmlmixed : xml # extra htmlmized check is for '</' edge case
if (tagName.length > 0) {
completeEndTag(cm, pos, tagName);
return;
}
}
}
} else if (mode == 'xmlpure') {
var pos = cm.getCursor();
var tok = cm.getTokenAt(pos);
var tagName = tok.state.context.tagName;
if (ch == '>') {
// <foo> tagName=foo, string=foo
// <foo /> tagName=foo, string=/ # ignore
// <foo></foo> tagName=foo, string=/foo # ignore
if (tok.string == tagName) {
cm.replaceSelection('>'); // parity w/html modes
pos = {line: pos.line, ch: pos.ch + 1};
cm.setCursor(pos);
insertEndTag(cm, indent, pos, tagName);
return;
}
} else if (ch == '/') {
// <foo / tagName=foo, string= # ignore
// <foo></ tagName=foo, string=<
if (tok.string == '<') {
completeEndTag(cm, pos, tagName);
return;
}
}
}
throw CodeMirror.Pass; // Bubble if not handled
});
function insertEndTag(cm, indent, pos, tagName) {
if (shouldIndent(cm, indent, tagName)) {
cm.replaceSelection('\n\n</' + tagName + '>', 'end');
cm.indentLine(pos.line + 1);
cm.indentLine(pos.line + 2);
cm.setCursor({line: pos.line + 1, ch: cm.getLine(pos.line + 1).length});
} else {
cm.replaceSelection('</' + tagName + '>');
cm.setCursor(pos);
}
}
function shouldIndent(cm, indent, tagName) {
if (typeof indent == 'undefined' || indent == null || indent == true) {
indent = cm.getOption('closeTagIndent');
}
if (!indent) {
indent = [];
}
return indexOf(indent, tagName.toLowerCase()) != -1;
}
// C&P from codemirror.js...would be nice if this were visible to utilities.
function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i;
return -1;
}
function completeEndTag(cm, pos, tagName) {
cm.replaceSelection('/' + tagName + '>');
cm.setCursor({line: pos.line, ch: pos.ch + tagName.length + 2 });
}
})();

View File

@@ -1,7 +1,7 @@
// the tagRangeFinder function is
// Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
// released under the MIT license (../../LICENSE) like the rest of CodeMirror
CodeMirror.tagRangeFinder = function(cm, line) {
CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
var nameChar = nameStartChar + "\-\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
@@ -36,8 +36,10 @@ CodeMirror.tagRangeFinder = function(cm, line) {
var slash = lt.lastIndexOf("/", gt);
if (-1 != slash && slash < gt) {
var str = lineText.substr(slash, gt - slash + 1);
if (!str.match( /\/\s*\>/ )) // yep, that's the end of empty tag
return l+1;
if (!str.match( /\/\s*\>/ )) { // yep, that's the end of empty tag
if (hideEnd === true) l++;
return l;
}
}
}
l++;
@@ -80,7 +82,7 @@ CodeMirror.tagRangeFinder = function(cm, line) {
}
if (found) {
var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\s)|(\\<" + tag + "$)";
var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\\s)|(\\<" + tag + "$)";
var startTagRegExp = new RegExp(startTag, "g");
var endTag = "</" + tag + ">";
var depth = 1;
@@ -95,8 +97,10 @@ CodeMirror.tagRangeFinder = function(cm, line) {
depth--;
else
depth++;
if (!depth)
return l+1;
if (!depth) {
if (hideEnd === true) l++;
return l;
}
}
}
l++;
@@ -105,7 +109,7 @@ CodeMirror.tagRangeFinder = function(cm, line) {
}
};
CodeMirror.braceRangeFinder = function(cm, line) {
CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
var lineText = cm.getLine(line);
var startChar = lineText.lastIndexOf("{");
if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return;
@@ -127,6 +131,7 @@ CodeMirror.braceRangeFinder = function(cm, line) {
}
}
if (end == null || end == line + 1) return;
if (hideEnd === true) end++;
return end;
};
@@ -144,7 +149,7 @@ CodeMirror.indentRangeFinder = function(cm, line) {
return last + 1;
};
CodeMirror.newFoldFunction = function(rangeFinder, markText) {
CodeMirror.newFoldFunction = function(rangeFinder, markText, hideEnd) {
var folded = [];
if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
@@ -169,7 +174,7 @@ CodeMirror.newFoldFunction = function(rangeFinder, markText) {
folded.splice(known.pos, 1);
expand(cm, known.region);
} else {
var end = rangeFinder(cm, line);
var end = rangeFinder(cm, line, hideEnd);
if (end == null) return;
var hidden = [];
for (var i = line + 1; i < end; ++i) {

View File

@@ -1,4 +1,4 @@
// ============== Formatting extensions ============================
// ============== Formatting extensions ============================
// A common storage for all mode-specific formatting features
if (!CodeMirror.modeExtensions) CodeMirror.modeExtensions = {};

View File

@@ -113,8 +113,10 @@
base = 1;
else if (obj.className == "function") {
if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
(typeof jQuery == 'function')) base = jQuery();
else if (window._ != null && (obj.string == '_') && (typeof _ == 'function')) base = _();
(typeof window.jQuery == 'function'))
base = window.jQuery();
else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function'))
base = window._();
}
while (base != null && context.length)
base = base[context.pop().string];

View File

@@ -0,0 +1,50 @@
(function() {
if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
var loading = {};
function splitCallback(cont, n) {
var countDown = n;
return function() { if (--countDown == 0) cont(); }
}
function ensureDeps(mode, cont) {
var deps = CodeMirror.modes[mode].dependencies;
if (!deps) return cont();
var missing = [];
for (var i = 0; i < deps.length; ++i) {
if (!CodeMirror.modes.hasOwnProperty(deps[i]))
missing.push(deps[i]);
}
if (!missing.length) return cont();
var split = splitCallback(cont, missing.length);
for (var i = 0; i < missing.length; ++i)
CodeMirror.requireMode(missing[i], split);
}
CodeMirror.requireMode = function(mode, cont) {
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont());
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
var script = document.createElement("script");
script.src = CodeMirror.modeURL.replace(/%N/g, mode);
var others = document.getElementsByTagName("script")[0];
others.parentNode.insertBefore(script, others);
var list = loading[mode] = [cont];
var count = 0, poll = setInterval(function() {
if (++count > 100) return clearInterval(poll);
if (CodeMirror.modes.hasOwnProperty(mode)) {
clearInterval(poll);
loading[mode] = null;
ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i]();
});
}
}, 200);
};
CodeMirror.autoLoadMode = function(instance, mode) {
if (!CodeMirror.modes.hasOwnProperty(mode))
CodeMirror.requireMode(mode, function() {
instance.setOption("mode", instance.getOption("mode"));
});
};
}());

View File

@@ -43,7 +43,7 @@ CodeMirror.overlayParser = function(base, overlay, combine) {
else return state.overlayCur;
},
indent: function(state, textAfter) {
indent: base.indent && function(state, textAfter) {
return base.indent(state.base, textAfter);
},
electricChars: base.electricChars

View File

@@ -72,14 +72,14 @@
query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
if (all) {
cm.operation(function() {
cm.compoundChange(function() { cm.operation(function() {
for (var cursor = cm.getSearchCursor(query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];}));
} else cursor.replace(text);
}
});
})});
} else {
clearSearch(cm);
var cursor = cm.getSearchCursor(query, cm.getCursor());

View File

@@ -29,6 +29,10 @@
complete.style.left = pos.x + "px";
complete.style.top = pos.yBot + "px";
document.body.appendChild(complete);
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
if(winW - pos.x < sel.clientWidth)
complete.style.left = (pos.x - sel.clientWidth) + "px";
// Hack to hide the scrollbar.
if (completions.length <= 10)
complete.style.width = (sel.clientWidth - 1) + "px";
@@ -53,6 +57,8 @@
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
else if (code != 38 && code != 40) {
close(); editor.focus();
// Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
editor.triggerOnKeyDown(event);
setTimeout(function(){CodeMirror.simpleHint(editor, getHints);}, 50);
}
});

View File

@@ -21,7 +21,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null
return null;
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);

View File

@@ -96,6 +96,6 @@ void* zmq_thread_init(void* zmq_context, int signal_fd) {
<p><strong>MIME types defined:</strong> <code>text/x-csrc</code>
(C code), <code>text/x-c++src</code> (C++
code), <code>text/x-java</code> (Java
code).</p>
code), <code>text/x-csharp</code> (C#).</p>
</body>
</html>

View File

@@ -92,7 +92,7 @@ CodeMirror.defineMode("css", function(config) {
var style = state.tokenize(stream, state);
var context = state.stack[state.stack.length-1];
if (type == "hash" && context == "rule") style = "atom";
if (type == "hash" && context != "rule") style = "string-2";
else if (style == "variable") {
if (context == "rule") style = "number";
else if (!context || context == "@media{") style = "tag";

View File

@@ -243,7 +243,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeoperator(type, value) {
if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
if (type == "operator") return cont(expression);
if (type == "operator" || type == ":") return cont(expression);
if (type == ";") return;
if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
if (type == ".") return cont(property, maybeoperator);
@@ -319,8 +319,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
kwAllowed: true,
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: null,
context: null,
localVars: parserConfig.localVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: 0
};
},
@@ -334,15 +334,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
state.kwAllowed = type != '.';
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
if (state.tokenize != jsTokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
type = lexical.type, closing = firstChar == type;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
if (type == "vardef") return lexical.indented + 4;
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "stat" || type == "form") return lexical.indented + indentUnit;

View File

@@ -143,7 +143,7 @@
electricChars: "/{}:"
}
});
}, "xml", "clike", "javascript", "css");
CodeMirror.defineMIME("application/x-httpd-php", "php");
CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
CodeMirror.defineMIME("text/x-php", phpConfig);

View File

@@ -0,0 +1,24 @@
Copyright (c) 2011, Ubalo, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Ubalo, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL UBALO, INC BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,171 @@
<!doctype html>
<html>
<head>
<title>CodeMirror: Ruby mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="ruby.js"></script>
<style>
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default span.cm-arrow { color: red; }
</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Ruby mode</h1>
<form><textarea id="code" name="code">
# Code from http://sandbox.mc.edu/~bennet/ruby/code/poly_rb.html
#
# This program evaluates polynomials. It first asks for the coefficients
# of a polynomial, which must be entered on one line, highest-order first.
# It then requests values of x and will compute the value of the poly for
# each x. It will repeatly ask for x values, unless you the user enters
# a blank line. It that case, it will ask for another polynomial. If the
# user types quit for either input, the program immediately exits.
#
#
# Function to evaluate a polynomial at x. The polynomial is given
# as a list of coefficients, from the greatest to the least.
def polyval(x, coef)
sum = 0
coef = coef.clone # Don't want to destroy the original
while true
sum += coef.shift # Add and remove the next coef
break if coef.empty? # If no more, done entirely.
sum *= x # This happens the right number of times.
end
return sum
end
#
# Function to read a line containing a list of integers and return
# them as an array of integers. If the string conversion fails, it
# throws TypeError. If the input line is the word 'quit', then it
# converts it to an end-of-file exception
def readints(prompt)
# Read a line
print prompt
line = readline.chomp
raise EOFError.new if line == 'quit' # You can also use a real EOF.
# Go through each item on the line, converting each one and adding it
# to retval.
retval = [ ]
for str in line.split(/\s+/)
if str =~ /^\-?\d+$/
retval.push(str.to_i)
else
raise TypeError.new
end
end
return retval
end
#
# Take a coeff and an exponent and return the string representation, ignoring
# the sign of the coefficient.
def term_to_str(coef, exp)
ret = ""
# Show coeff, unless it's 1 or at the right
coef = coef.abs
ret = coef.to_s unless coef == 1 && exp > 0
ret += "x" if exp > 0 # x if exponent not 0
ret += "^" + exp.to_s if exp > 1 # ^exponent, if > 1.
return ret
end
#
# Create a string of the polynomial in sort-of-readable form.
def polystr(p)
# Get the exponent of first coefficient, plus 1.
exp = p.length
# Assign exponents to each term, making pairs of coeff and exponent,
# Then get rid of the zero terms.
p = (p.map { |c| exp -= 1; [ c, exp ] }).select { |p| p[0] != 0 }
# If there's nothing left, it's a zero
return "0" if p.empty?
# *** Now p is a non-empty list of [ coef, exponent ] pairs. ***
# Convert the first term, preceded by a "-" if it's negative.
result = (if p[0][0] < 0 then "-" else "" end) + term_to_str(*p[0])
# Convert the rest of the terms, in each case adding the appropriate
# + or - separating them.
for term in p[1...p.length]
# Add the separator then the rep. of the term.
result += (if term[0] < 0 then " - " else " + " end) +
term_to_str(*term)
end
return result
end
#
# Run until some kind of endfile.
begin
# Repeat until an exception or quit gets us out.
while true
# Read a poly until it works. An EOF will except out of the
# program.
print "\n"
begin
poly = readints("Enter a polynomial coefficients: ")
rescue TypeError
print "Try again.\n"
retry
end
break if poly.empty?
# Read and evaluate x values until the user types a blank line.
# Again, an EOF will except out of the pgm.
while true
# Request an integer.
print "Enter x value or blank line: "
x = readline.chomp
break if x == ''
raise EOFError.new if x == 'quit'
# If it looks bad, let's try again.
if x !~ /^\-?\d+$/
print "That doesn't look like an integer. Please try again.\n"
next
end
# Convert to an integer and print the result.
x = x.to_i
print "p(x) = ", polystr(poly), "\n"
print "p(", x, ") = ", polyval(x, poly), "\n"
end
end
rescue EOFError
print "\n=== EOF ===\n"
rescue Interrupt, SignalException
print "\n=== Interrupted ===\n"
else
print "--- Bye ---\n"
end
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/x-ruby",
tabMode: "indent",
matchBrackets: true,
indentUnit: 4
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-ruby</code>.</p>
<p>Development of the CodeMirror Ruby mode was kindly sponsored
by <a href="http://ubalo.com/">Ubalo</a>, who hold
the <a href="LICENSE">license</a>.</p>
</body>
</html>

View File

@@ -0,0 +1,200 @@
CodeMirror.defineMode("ruby", function(config, parserConfig) {
function wordObj(words) {
var o = {};
for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
return o;
}
var keywords = wordObj([
"alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
"elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
"redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
"until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
"caller", "lambda", "proc", "public", "protected", "private", "require", "load",
"require_relative", "extend", "autoload"
]);
var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then",
"catch", "loop", "proc", "begin"]);
var dedentWords = wordObj(["end", "until"]);
var matching = {"[": "]", "{": "}", "(": ")"};
var curPunc;
function chain(newtok, stream, state) {
state.tokenize.push(newtok);
return newtok(stream, state);
}
function tokenBase(stream, state) {
curPunc = null;
if (stream.sol() && stream.match("=begin") && stream.eol()) {
state.tokenize.push(readBlockComment);
return "comment";
}
if (stream.eatSpace()) return null;
var ch = stream.next();
if (ch == "`" || ch == "'" || ch == '"' ||
(ch == "/" && !stream.eol() && stream.peek() != " ")) {
return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
} else if (ch == "%") {
var style, embed = false;
if (stream.eat("s")) style = "atom";
else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; }
else if (stream.eat(/[wxqr]/)) style = "string";
var delim = stream.eat(/[^\w\s]/);
if (!delim) return "operator";
if (matching.propertyIsEnumerable(delim)) delim = matching[delim];
return chain(readQuoted(delim, style, embed, true), stream, state);
} else if (ch == "#") {
stream.skipToEnd();
return "comment";
} else if (ch == "<" && stream.eat("<")) {
stream.eat("-");
stream.eat(/[\'\"\`]/);
var match = stream.match(/^\w+/);
stream.eat(/[\'\"\`]/);
if (match) return chain(readHereDoc(match[0]), stream, state);
return null;
} else if (ch == "0") {
if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/);
else if (stream.eat("b")) stream.eatWhile(/[01]/);
else stream.eatWhile(/[0-7]/);
return "number";
} else if (/\d/.test(ch)) {
stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/);
return "number";
} else if (ch == "?") {
while (stream.match(/^\\[CM]-/)) {}
if (stream.eat("\\")) stream.eatWhile(/\w/);
else stream.next();
return "string";
} else if (ch == ":") {
if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state);
if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state);
stream.eatWhile(/[\w\?]/);
return "atom";
} else if (ch == "@") {
stream.eat("@");
stream.eatWhile(/[\w\?]/);
return "variable-2";
} else if (ch == "$") {
stream.next();
stream.eatWhile(/[\w\?]/);
return "variable-3";
} else if (/\w/.test(ch)) {
stream.eatWhile(/[\w\?]/);
if (stream.eat(":")) return "atom";
return "ident";
} else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) {
curPunc = "|";
return null;
} else if (/[\(\)\[\]{}\\;]/.test(ch)) {
curPunc = ch;
return null;
} else if (ch == "-" && stream.eat(">")) {
return "arrow";
} else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) {
stream.eatWhile(/[=+\-\/*:\.^%<>~|]/);
return "operator";
} else {
return null;
}
}
function tokenBaseUntilBrace() {
var depth = 1;
return function(stream, state) {
if (stream.peek() == "}") {
depth--;
if (depth == 0) {
state.tokenize.pop();
return state.tokenize[state.tokenize.length-1](stream, state);
}
} else if (stream.peek() == "{") {
depth++;
}
return tokenBase(stream, state);
};
}
function readQuoted(quote, style, embed, unescaped) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && (unescaped || !escaped)) {
state.tokenize.pop();
break;
}
if (embed && ch == "#" && !escaped && stream.eat("{")) {
state.tokenize.push(tokenBaseUntilBrace(arguments.callee));
break;
}
escaped = !escaped && ch == "\\";
}
return style;
};
}
function readHereDoc(phrase) {
return function(stream, state) {
if (stream.match(phrase)) state.tokenize.pop();
else stream.skipToEnd();
return "string";
};
}
function readBlockComment(stream, state) {
if (stream.sol() && stream.match("=end") && stream.eol())
state.tokenize.pop();
stream.skipToEnd();
return "comment";
}
return {
startState: function() {
return {tokenize: [tokenBase],
indented: 0,
context: {type: "top", indented: -config.indentUnit},
continuedLine: false,
lastTok: null,
varList: false};
},
token: function(stream, state) {
if (stream.sol()) state.indented = stream.indentation();
var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
if (style == "ident") {
var word = stream.current();
style = keywords.propertyIsEnumerable(stream.current()) ? "keyword"
: /^[A-Z]/.test(word) ? "tag"
: (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def"
: "variable";
if (indentWords.propertyIsEnumerable(word)) kwtype = "indent";
else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent";
else if ((word == "if" || word == "unless") && stream.column() == stream.indentation())
kwtype = "indent";
}
if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style;
if (curPunc == "|") state.varList = !state.varList;
if (kwtype == "indent" || /[\(\[\{]/.test(curPunc))
state.context = {prev: state.context, type: curPunc || style, indented: state.indented};
else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev)
state.context = state.context.prev;
if (stream.eol())
state.continuedLine = (curPunc == "\\" || style == "operator");
return style;
},
indent: function(state, textAfter) {
if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0);
var ct = state.context;
var closing = ct.type == matching[firstChar] ||
ct.type == "keyword" && /^(?:end|until|else|elsif|when|rescue)\b/.test(textAfter);
return ct.indented + (closing ? 0 : config.indentUnit) +
(state.continuedLine ? config.indentUnit : 0);
},
electricChars: "}de" // enD and rescuE
};
});
CodeMirror.defineMIME("text/x-ruby", "ruby");

View File

@@ -1,12 +1,44 @@
CodeMirror.defineMode("xml", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var Kludges = parserConfig.htmlMode ? {
autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
"meta": true, "col": true, "frame": true, "base": true, "area": true},
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: false
} : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false, allowMissing: false};
} : {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false
};
var alignCDATA = parserConfig.alignCDATA;
// Return variables for tokenizers
@@ -162,7 +194,12 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
} else if (type == "closeTag") {
var err = false;
if (curState.context) {
err = curState.context.tagName != tagName;
if (curState.context.tagName != tagName) {
if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
popContext();
}
err = !curState.context || curState.context.tagName != tagName;
}
} else {
err = true;
}
@@ -174,9 +211,15 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
function endtag(startOfLine) {
return function(type) {
if (type == "selfcloseTag" ||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) {
maybePopContext(curState.tagName.toLowerCase());
return cont();
if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
}
if (type == "endTag") {
maybePopContext(curState.tagName.toLowerCase());
pushContext(curState.tagName, startOfLine);
return cont();
}
return cont();
};
}
@@ -188,6 +231,20 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
return cont(arguments.callee);
}
}
function maybePopContext(nextTagName) {
var parentTagName;
while (true) {
if (!curState.context) {
return;
}
parentTagName = curState.context.tagName.toLowerCase();
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
return;
}
popContext();
}
}
function attributes(type) {
if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
@@ -264,4 +321,5 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
});
CodeMirror.defineMIME("application/xml", "xml");
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
/* Port of TextMate's Blackboard theme */
.cm-s-blackboard { background: #0C1021; color: #F8F8F8; }
.cm-s-blackboard .CodeMirror-selected { background: #253B76 !important; }
.cm-s-blackboard .CodeMirror-gutter { background: #0C1021; border-right: 0; }
.cm-s-blackboard .CodeMirror-gutter-text { color: #888; }
.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7 !important; }
.cm-s-blackboard .cm-keyword { color: #FBDE2D; }
.cm-s-blackboard .cm-atom { color: #D8FA3C; }
.cm-s-blackboard .cm-number { color: #D8FA3C; }
.cm-s-blackboard .cm-def { color: #8DA6CE; }
.cm-s-blackboard .cm-variable { color: #FF6400; }
.cm-s-blackboard .cm-operator { color: #FBDE2D;}
.cm-s-blackboard .cm-comment { color: #AEAEAE; }
.cm-s-blackboard .cm-string { color: #61CE3C; }
.cm-s-blackboard .cm-string-2 { color: #61CE3C; }
.cm-s-blackboard .cm-meta { color: #D8FA3C; }
.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
.cm-s-blackboard .cm-builtin { color: #8DA6CE; }
.cm-s-blackboard .cm-tag { color: #8DA6CE; }
.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
.cm-s-blackboard .cm-header { color: #FF6400; }
.cm-s-blackboard .cm-hr { color: #AEAEAE; }
.cm-s-blackboard .cm-link { color: #8DA6CE; }

View File

@@ -0,0 +1,18 @@
.cm-s-cobalt { background: #002240; color: white; }
.cm-s-cobalt div.CodeMirror-selected { background: #b36539 !important; }
.cm-s-cobalt .CodeMirror-gutter { background: #002240; border-right: 1px solid #aaa; }
.cm-s-cobalt .CodeMirror-gutter-text { color: #d0d0d0; }
.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white !important; }
.cm-s-cobalt span.cm-comment { color: #08f; }
.cm-s-cobalt span.cm-atom { color: #845dc4; }
.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
.cm-s-cobalt span.cm-keyword { color: #ffee80; }
.cm-s-cobalt span.cm-string { color: #3ad900; }
.cm-s-cobalt span.cm-meta { color: #ff9d00; }
.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
.cm-s-cobalt span.cm-error { color: #9d1e15; }
.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
.cm-s-cobalt span.cm-link { color: #845dc4; }

View File

@@ -0,0 +1,25 @@
.cm-s-eclipse span.cm-meta {color: #FF1717;}
.cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; }
.cm-s-eclipse span.cm-atom {color: #219;}
.cm-s-eclipse span.cm-number {color: #164;}
.cm-s-eclipse span.cm-def {color: #00f;}
.cm-s-eclipse span.cm-variable {color: black;}
.cm-s-eclipse span.cm-variable-2 {color: #0000C0;}
.cm-s-eclipse span.cm-variable-3 {color: #0000C0;}
.cm-s-eclipse span.cm-property {color: black;}
.cm-s-eclipse span.cm-operator {color: black;}
.cm-s-eclipse span.cm-comment {color: #3F7F5F;}
.cm-s-eclipse span.cm-string {color: #2A00FF;}
.cm-s-eclipse span.cm-string-2 {color: #f50;}
.cm-s-eclipse span.cm-error {color: #f00;}
.cm-s-eclipse span.cm-qualifier {color: #555;}
.cm-s-eclipse span.cm-builtin {color: #30a;}
.cm-s-eclipse span.cm-bracket {color: #cc7;}
.cm-s-eclipse span.cm-tag {color: #170;}
.cm-s-eclipse span.cm-attribute {color: #00c;}
.cm-s-eclipse span.cm-link {color: #219;}
.cm-s-eclipse .CodeMirror-matchingbracket {
border:1px solid grey;
color:black !important;;
}

View File

@@ -0,0 +1,10 @@
.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;}
.cm-s-elegant span.cm-comment {color: #262; font-style: italic; line-height: 1em;}
.cm-s-elegant span.cm-meta {color: #555; font-style: italic; line-height: 1em;}
.cm-s-elegant span.cm-variable {color: black;}
.cm-s-elegant span.cm-variable-2 {color: #b11;}
.cm-s-elegant span.cm-qualifier {color: #555;}
.cm-s-elegant span.cm-keyword {color: #730;}
.cm-s-elegant span.cm-builtin {color: #30a;}
.cm-s-elegant span.cm-error {background-color: #fdd;}
.cm-s-elegant span.cm-link {color: #762;}

View File

@@ -0,0 +1,45 @@
/*
http://lesscss.org/ dark theme
Ported to CodeMirror by Peter Kroon
*/
.CodeMirror{
line-height: 15px;
}
.cm-s-lesser-dark {
font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Monaco', Courier, monospace !important;
font-size:12px;
}
.cm-s-lesser-dark { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; }
.cm-s-lesser-dark div.CodeMirror-selected {background: #45443B !important;} /* 33322B*/
.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
.cm-s-lesser-dark .CodeMirror-lines { margin-left:3px; margin-right:3px; }/*editable code holder*/
div.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/
.cm-s-lesser-dark .CodeMirror-gutter { background: #262626; border-right:1px solid #aaa; padding-right:3px; min-width:2.5em; }
.cm-s-lesser-dark .CodeMirror-gutter-text { color: #777; }
.cm-s-lesser-dark span.cm-keyword { color: #599eff; }
.cm-s-lesser-dark span.cm-atom { color: #C2B470; }
.cm-s-lesser-dark span.cm-number { color: #B35E4D; }
.cm-s-lesser-dark span.cm-def {color: white;}
.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; }
.cm-s-lesser-dark span.cm-variable-2 { color: #669199; }
.cm-s-lesser-dark span.cm-variable-3 { color: white; }
.cm-s-lesser-dark span.cm-property {color: #92A75C;}
.cm-s-lesser-dark span.cm-operator {color: #92A75C;}
.cm-s-lesser-dark span.cm-comment { color: #666; }
.cm-s-lesser-dark span.cm-string { color: #BCD279; }
.cm-s-lesser-dark span.cm-string-2 {color: #f50;}
.cm-s-lesser-dark span.cm-meta { color: #738C73; }
.cm-s-lesser-dark span.cm-error { color: #9d1e15; }
.cm-s-lesser-dark span.cm-qualifier {color: #555;}
.cm-s-lesser-dark span.cm-builtin { color: #ff9e59; }
.cm-s-lesser-dark span.cm-bracket { color: #EBEFE7; }
.cm-s-lesser-dark span.cm-tag { color: #669199; }
.cm-s-lesser-dark span.cm-attribute {color: #00c;}
.cm-s-lesser-dark span.cm-header {color: #a0a;}
.cm-s-lesser-dark span.cm-quote {color: #090;}
.cm-s-lesser-dark span.cm-hr {color: #999;}
.cm-s-lesser-dark span.cm-link {color: #00c;}

View File

@@ -0,0 +1,28 @@
/* Based on Sublime Text's Monokai theme */
.cm-s-monokai {background: #272822; color: #f8f8f2;}
.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;}
.cm-s-monokai .CodeMirror-gutter {background: #272822; border-right: 0px;}
.cm-s-monokai .CodeMirror-gutter-text {color: #d0d0d0;}
.cm-s-monokai .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;}
.cm-s-monokai span.cm-comment {color: #75715e;}
.cm-s-monokai span.cm-atom {color: #ae81ff;}
.cm-s-monokai span.cm-number {color: #ae81ff;}
.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {color: #a6e22e;}
.cm-s-monokai span.cm-keyword {color: #f92672;}
.cm-s-monokai span.cm-string {color: #e6db74;}
.cm-s-monokai span.cm-variable {color: #a6e22e;}
.cm-s-monokai span.cm-variable-2 {color: #9effff;}
.cm-s-monokai span.cm-def {color: #fd971f;}
.cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;}
.cm-s-monokai span.cm-bracket {color: #f8f8f2;}
.cm-s-monokai span.cm-tag {color: #f92672;}
.cm-s-monokai span.cm-link {color: #ae81ff;}
.cm-s-monokai .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}

View File

@@ -0,0 +1,9 @@
.cm-s-neat span.cm-comment { color: #a86; }
.cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; }
.cm-s-neat span.cm-string { color: #a22; }
.cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; }
.cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; }
.cm-s-neat span.cm-variable { color: black; }
.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
.cm-s-neat span.cm-meta {color: #555;}
.cm-s-neat span.cm-link { color: #3a3; }

View File

@@ -0,0 +1,21 @@
/* Loosely based on the Midnight Textmate theme */
.cm-s-night { background: #0a001f; color: #f8f8f8; }
.cm-s-night div.CodeMirror-selected { background: #a8f !important; }
.cm-s-night .CodeMirror-gutter { background: #0a001f; border-right: 1px solid #aaa; }
.cm-s-night .CodeMirror-gutter-text { color: #f8f8f8; }
.cm-s-night .CodeMirror-cursor { border-left: 1px solid white !important; }
.cm-s-night span.cm-comment { color: #6900a1; }
.cm-s-night span.cm-atom { color: #845dc4; }
.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; }
.cm-s-night span.cm-keyword { color: #599eff; }
.cm-s-night span.cm-string { color: #37f14a; }
.cm-s-night span.cm-meta { color: #7678e2; }
.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; }
.cm-s-night span.cm-error { color: #9d1e15; }
.cm-s-night span.cm-bracket { color: #8da6ce; }
.cm-s-night span.cm-comment { color: #6900a1; }
.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
.cm-s-night span.cm-link { color: #845dc4; }

View File

@@ -0,0 +1,21 @@
.cm-s-rubyblue { font:13px/1.4em Trebuchet, Verdana, sans-serif; } /* - customized editor font - */
.cm-s-rubyblue { background: #112435; color: white; }
.cm-s-rubyblue div.CodeMirror-selected { background: #38566F !important; }
.cm-s-rubyblue .CodeMirror-gutter { background: #1F4661; border-right: 7px solid #3E7087; min-width:2.5em; }
.cm-s-rubyblue .CodeMirror-gutter-text { color: white; }
.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white !important; }
.cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; }
.cm-s-rubyblue span.cm-atom { color: #F4C20B; }
.cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; }
.cm-s-rubyblue span.cm-keyword { color: #F0F; }
.cm-s-rubyblue span.cm-string { color: #F08047; }
.cm-s-rubyblue span.cm-meta { color: #F0F; }
.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def { color: white; }
.cm-s-rubyblue span.cm-error { color: #AF2018; }
.cm-s-rubyblue span.cm-bracket { color: #F0F; }
.cm-s-rubyblue span.cm-link { color: #F4C20B; }
.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
.cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; }

View File

@@ -0,0 +1,46 @@
/*
Copyright (C) 2011 by MarkLogic Corporation
Author: Mike Brevoort <mike@brevoort.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
.cm-s-xq-dark { background: #0a001f; color: #f8f8f8; }
.cm-s-xq-dark span.CodeMirror-selected { background: #a8f !important; }
.cm-s-xq-dark .CodeMirror-gutter { background: #0a001f; border-right: 1px solid #aaa; }
.cm-s-xq-dark .CodeMirror-gutter-text { color: #f8f8f8; }
.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white !important; }
.cm-s-xq-dark span.cm-keyword {color: #FFBD40;}
.cm-s-xq-dark span.cm-atom {color: #6C8CD5;}
.cm-s-xq-dark span.cm-number {color: #164;}
.cm-s-xq-dark span.cm-def {color: #FFF; text-decoration:underline;}
.cm-s-xq-dark span.cm-variable {color: #FFF;}
.cm-s-xq-dark span.cm-variable-2 {color: #EEE;}
.cm-s-xq-dark span.cm-variable-3 {color: #DDD;}
.cm-s-xq-dark span.cm-property {}
.cm-s-xq-dark span.cm-operator {}
.cm-s-xq-dark span.cm-comment {color: gray;}
.cm-s-xq-dark span.cm-string {color: #9FEE00;}
.cm-s-xq-dark span.cm-meta {color: yellow;}
.cm-s-xq-dark span.cm-error {color: #f00;}
.cm-s-xq-dark span.cm-qualifier {color: #FFF700;}
.cm-s-xq-dark span.cm-builtin {color: #30a;}
.cm-s-xq-dark span.cm-bracket {color: #cc7;}
.cm-s-xq-dark span.cm-tag {color: #FFBD40;}
.cm-s-xq-dark span.cm-attribute {color: #FFF700;}

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html>
<html style="margin: 0px">
<head>
<title>CodeMirror 2: ICE Coders Editor of Choice</title>
<?php include("lib/settings.php");?>
@@ -11,24 +11,40 @@
<script src="<?php echo $codeMirrorDir; ?>/mode/css/css.js"></script>
<script src="<?php echo $codeMirrorDir; ?>/mode/clike/clike.js"></script>
<script src="<?php echo $codeMirrorDir; ?>/mode/php/php.js"></script>
<script src="<?php echo $codeMirrorDir; ?>/mode/ruby/ruby.js"></script>
<script src="<?php echo $codeMirrorDir; ?>/lib/util/searchcursor.js"></script>
<script src="<?php echo $codeMirrorDir; ?>/lib/util/match-highlighter.js"></script>
<link rel="stylesheet" href="lib/editor.css">
<script src="<?php echo $codeMirrorDir; ?>/lib/util/foldcode.js"></script>
<?php
if ($theme=="default") {
echo '<link rel="stylesheet" href="lib/editor.css">';
} else {
echo '<link rel="stylesheet" href="'.$codeMirrorDir.'/theme/'.$theme.'.css">';
}
?>
<style type="text/css">
.CodeMirror {position: absolute; width: 0px; background-color: #ffffff}
.CodeMirror-scroll {width: 100px; height: 100px;}
.cm-s-visible {display: block; top: 0px}
.cm-s-hidden {display: none; top: 4000px}
.cm-s-activeLine {background: #002 !important;}
// Make sure this next one remains the 5th item, updated with JS
.cm-tab:after {position: relative; display: inline-block; width: 0px; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if ($visibleTabs) {?>\21e5<?;};?>";}
span.CodeMirror-matchhighlight {background: #555555}
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000000; background: #555555; !important}
</style>
</head>
<body onKeyDown="return top.ICEcoder.interceptKeys('content', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
<body style="margin: 0px" onKeyDown="return top.ICEcoder.interceptKeys('content', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
<script>
function createNewCMInstance(num) {window['cM'+num] = CodeMirror(document.body, {
function createNewCMInstance(num) {
var fileName = top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1];
var codeFold = CodeMirror.newFoldFunction(CodeMirror.tagRangeFinder,'<span style=\"display: inline-block; width: 13px; height: 13px; background-color: #bb0000; color: #ffffff; text-align: center; cursor: pointer\"><span style="position: relative; top: -1px">+</span></span> %N%');
var codeFold_JS_PHP_Ruby = CodeMirror.newFoldFunction(CodeMirror.braceRangeFinder,'<span style=\"display: inline-block; width: 13px; height: 13px; background-color: #bb0000; color: #ffffff; text-align: center; cursor: pointer\"><span style="position: relative; top: -1px">+</span></span> %N%');
window['cM'+num] = CodeMirror(document.body, {
mode: "application/x-httpd-php",
theme: "icecoder",
lineNumbers: true,
lineWrapping: true,
indentUnit: 4,
@@ -52,6 +68,7 @@ function createNewCMInstance(num) {window['cM'+num] = CodeMirror(document.body,
top.ICEcoder.redoTabHighlight(top.ICEcoder.selectedTab);
}
top.ICEcoder.getCaretPosition();
top.ICEcoder.dontUpdateNest = false;
top.ICEcoder.updateCharDisplay();
top.ICEcoder.updateNestingIndicator();
if (top.ICEcoder.findMode) {
@@ -74,7 +91,9 @@ function createNewCMInstance(num) {window['cM'+num] = CodeMirror(document.body,
canDoEndTag=false;
}
}
fileName = top.ICEcoder.openFiles[top.ICEcoder.selectedTab-1];
if(top.ICEcoder.tagString.slice(0,1)=="/"||top.ICEcoder.tagString.slice(0,1)=="?") {
canDoEndTag=false;
}
if (!top.ICEcoder.codeAssist||fileName.indexOf(".js")>0||fileName.indexOf(".css")>0) {
canDoEndTag=false;
}
@@ -86,7 +105,8 @@ function createNewCMInstance(num) {window['cM'+num] = CodeMirror(document.body,
for (i=0;i<numTabs-1;i++) {
tabs += "\t";
}
endTag = "</" + top.ICEcoder.htmlTagArray[top.ICEcoder.htmlTagArray.length-1] + ">";
//endTag = "</" + top.ICEcoder.htmlTagArray[top.ICEcoder.htmlTagArray.length-1] + ">";
endTag = "</" + top.ICEcoder.tagString + ">";
if (top.ICEcoder.tagString=="script") {endTag="</"+"script>"};
if(top.ICEcoder.tagString=="title"||top.ICEcoder.tagString=="a"||top.ICEcoder.tagString=="li"||top.ICEcoder.tagString=="span"||(top.ICEcoder.tagString.slice(0,1)=="h"&&parseInt(top.ICEcoder.tagString.slice(1,2),10)>=1&&parseInt(top.ICEcoder.tagString.slice(1,2),10)<=7)) {
window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].replaceSelection(endTag);
@@ -102,25 +122,17 @@ function createNewCMInstance(num) {window['cM'+num] = CodeMirror(document.body,
};
lastKeyCode = e.keyCode;
},
extraKeys: {"Enter": false}
});
onGutterClick: !fileName || (fileName && fileName.indexOf(".js") == -1 && fileName.indexOf(".php") && fileName.indexOf(".rb") == -1) ? codeFold : codeFold_JS_PHP_Ruby,
extraKeys: {
"Tab": function(cm) {CodeMirror.commands[top.tabsIndent ? "defaultTab" : "insertTab"](cm);},
"Shift-Tab": "indentLess"
}
});
// Now create the active line for this CodeMirror object
top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab] = window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(0, "cm-s-activeLine");
// Now create the active line for this CodeMirror object
top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab] = window['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(0, "cm-s-activeLine");
};
<?php
//for ($i=1;$i<=10;$i++) {
?>
//cM<?php echo $i;?>.getWrapperElement().getElementsByClassName("CodeMirror-lines")[0].addEventListener("click", function(){
// if (top.ICEcoder.results && top.ICEcoder.results.length>0) {
// top.document.getElementById('results').innerHTML = top.ICEcoder.results.length + " results";
// }
// top.ICEcoder.findMode = false;
//}, false);
<?php
//;};
?>
</script>
</body>

View File

@@ -95,7 +95,7 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
$fileManager .= fileManager_dir("$directory/$this_file", $return_link , false);
$fileManager .= "</li>";
} else {
$fileManager .= "<li class=\"pft-directory\" style=\"cursor: default\"><span style=\"position: relative; left:-22px; color: #888888\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [HIDDEN] ".$fileAtts."</span></li>";
$fileManager .= "<li class=\"pft-directory\" style=\"cursor: pointer\"><span style=\"position: relative; left:-22px; color: #888888\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [HIDDEN] ".$fileAtts."</span></li>";
}
} else {
// File
@@ -117,7 +117,7 @@ function fileManager_dir($directory, $return_link, $first_call=true) {
$chmodInfo = substr(sprintf('%o', fileperms($link)), -4);
$fileAtts = '<span style="color: #888888; font-size: 8px">'.$chmodInfo.'</span>';
}
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\"><a nohref onMouseOver=\"top.ICEcoder.overFileFolder('file','$link')\" onMouseOut=\"top.ICEcoder.overFileFolder('file','')\" style=\"position: relative; left:-22px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span id=\"".str_replace("/","|",str_replace($docRoot,"",$link))."\">" . htmlspecialchars($this_file) . "</span> ".$fileAtts."</a></li>";
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\"><a nohref onMouseOver=\"top.ICEcoder.overFileFolder('file','$link')\" onMouseOut=\"top.ICEcoder.overFileFolder('file','')\" style=\"position: relative; left:-22px; cursor: pointer\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span id=\"".str_replace("/","|",str_replace($docRoot,"",$link))."\">" . htmlspecialchars($this_file) . "</span> ".$fileAtts."</a></li>";
} else {
$fileAtts = "<img src=\"images/file-manager-icons/padlock.png\" style=\"cursor: pointer\" onClick=\"alert('Sorry, you need higher admin level rights to view.')\">";
$fileManager .= "<li class=\"pft-file " . strtolower($ext) . "\" style=\"cursor: default\"><span style=\"position: relative; left:-22px; color: #888888\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [HIDDEN] ".$fileAtts."</span></li>";
@@ -142,14 +142,15 @@ function php4_scandir($dir) {
?>
<!DOCTYPE html>
<html onMouseDown="top.ICEcoder.mouseDown=true" onMouseUp="top.ICEcoder.mouseDown=false" onMouseMove="top.ICEcoder.getMouseXY(event);top.ICEcoder.canResizeFilesW()" onContextMenu="top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink; top.ICEcoder.selectFileFolder(); return top.ICEcoder.showMenu()" onClick="top.document.getElementById('fileMenu').style.display='none'">
<html onMouseDown="top.ICEcoder.mouseDown=true" onMouseUp="top.ICEcoder.mouseDown=false" onMouseMove="top.ICEcoder.getMouseXY(event);top.ICEcoder.canResizeFilesW()" onContextMenu="top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink; return top.ICEcoder.showMenu()" onClick="top.ICEcoder.selectFileFolder()">
<head>
<title>ICE Coder File Manager</title>
<link rel="stylesheet" type="text/css" href="lib/files.css">
<script src="lib/coder.js" type="text/javascript"></script>
</head>
<body onLoad="top.ICEcoder.fileManager()" onClick="top.ICEcoder.selectFileFolder()" onDblClick="top.ICEcoder.openFile()" onKeyDown="return top.ICEcoder.interceptKeys('files', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
<body onLoad="top.ICEcoder.fileManager()" onDblClick="top.ICEcoder.openFile()" onKeyDown="return top.ICEcoder.interceptKeys('files', event);" onKeyUp="top.ICEcoder.resetKeys(event);">
<div onClick="top.ICEcoder.refreshFileManager()" class="refresh"><img src="images/file-manager-icons/refresh.png"></div>
<?php
echo fileManager($_SERVER['DOCUMENT_ROOT'], "[link]");
?>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

BIN
images/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
images/new-file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

BIN
images/new-folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
images/open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/rename.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

BIN
images/save.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
images/view.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

View File

@@ -1,8 +1,8 @@
<?php
include("lib/settings.php");
$allowedIP = false;
for($i=0;$i<count($allowedIPs);$i++) {
if ($allowedIPs[$i]==$_SERVER["REMOTE_ADDR"]||$allowedIPs[$i]=="*") {
for($i=0;$i<count($_SESSION['allowedIPs']);$i++) {
if ($_SESSION['allowedIPs'][$i]==$_SERVER["REMOTE_ADDR"]||$_SESSION['allowedIPs'][$i]=="*") {
$allowedIP = true;
}
}
@@ -27,22 +27,35 @@ if ($testcMVersion) {
<link rel="stylesheet" type="text/css" href="lib/coder.css">
<script>
shortURLStarts = "<?php echo $shortURLStarts;?>";
theme = "<?php if ($theme=="default") {echo 'icecoder';} else {echo $theme;};?>";
tabsIndent = <?php if ($tabsIndent) {echo 'true';} else {echo 'false';};?>;
<?
$docRoot = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']);
if (strrpos($docRoot,"/")==strlen($docRoot)-1) {$docRoot = substr($docRoot,0,strlen($docRoot)-1);};
echo 'fullPath = "'.$docRoot.'";'.PHP_EOL;
?>
window.onbeforeunload = function() {
for (var i=0; i<=top.ICEcoder.changedContent.length; i++) {
if (top.ICEcoder.changedContent[i]==1) {
return "You have some unsaved changes.";
}
}
}
lastOpenFiles = [<?php
if ($lastOpenedFiles!="" && $_SESSION['userLevel'] == 10) {
$openFilesArray = explode(",",$lastOpenedFiles);
for ($i=0;$i<count($openFilesArray);$i++) {
echo "'".$openFilesArray[$i]."'";
if ($i<count($openFilesArray)-1) {echo ",";};
}
}
?>];
</script>
<script language="JavaScript" src="lib/coder.js"></script>
</head><?php
$onLoadExtras = "";
for ($i=0;$i<count($plugins);$i++) {
if ($plugins[$i][5]!="") {
$onLoadExtras .= ";ICEcoder.startPluginIntervals('".$plugins[$i][3]."','".$plugins[$i][4]."','".$plugins[$i][5]."')";
};
};
?>
<body onLoad="ICEcoder.init()<?php echo $onLoadExtras;?>" onResize="ICEcoder.setLayout()" onMouseMove="top.ICEcoder.getMouseXY(event);top.ICEcoder.canResizeFilesW()" onMouseDown="top.ICEcoder.mouseDown=true" onMouseUp="top.ICEcoder.mouseDown=false" onKeyDown="return ICEcoder.interceptKeys('coder', event);" onKeyUp="parent.ICEcoder.resetKeys(event);">
</head>
<body onLoad="ICEcoder.init(<?php if ($_SESSION['userLevel'] == 10) {echo "'login'";} ?>)<?php echo $onLoadExtras;?>" onResize="ICEcoder.setLayout()" onMouseMove="top.ICEcoder.getMouseXY(event);top.ICEcoder.canResizeFilesW()" onMouseDown="top.ICEcoder.mouseDown=true" onMouseUp="top.ICEcoder.mouseDown=false" onKeyDown="return ICEcoder.interceptKeys('coder', event);" onKeyUp="parent.ICEcoder.resetKeys(event);">
<div id="blackMask" class="blackMask" onClick="ICEcoder.showHide('hide',this)">
<div class="popupVCenter">
@@ -57,37 +70,50 @@ echo 'fullPath = "'.$docRoot.'";'.PHP_EOL;
<div class="popup">
<div class="circleOutside"></div>
<div class="circleInside"></div>
&nbsp;&nbsp;&nbsp;loading...
&nbsp;&nbsp;&nbsp;working...
</div>
</div>
</div>
<div id="fileMenu" class="fileMenu" onMouseOut="this.style.display='none'" onMouseOver="ICEcoder.changeFilesW('expand')" onMouseOut="ICEcoder.changeFilesW('contract')">
<a href="javascript:top.ICEcoder.newFile()" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">New File</a>
<a href="javascript:top.ICEcoder.newFolder()" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">New Folder</a>
<div id="fileMenu" class="fileMenu" onMouseOver="ICEcoder.changeFilesW('expand')" onMouseOut="ICEcoder.changeFilesW('contract')">
<span id="folderMenuItems">
<a href="javascript:top.ICEcoder.newFile()" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">New File</a>
<a href="javascript:top.ICEcoder.newFolder()" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">New Folder</a>
</span>
<a href="javascript:top.ICEcoder.deleteFile(top.ICEcoder.rightClickedFile)" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">Delete</a>
<a href="javascript:top.ICEcoder.renameFile(top.ICEcoder.rightClickedFile)" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">Rename</a>
<a href="javascript:window.open(top.ICEcoder.rightClickedFile.substr((top.ICEcoder.rightClickedFile.indexOf(shortURLStarts)+top.shortURLStarts.length),top.ICEcoder.rightClickedFile.length))" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">View Webpage</a>
<span id="singleFileMenuItems">
<a href="javascript:top.ICEcoder.renameFile(top.ICEcoder.rightClickedFile)" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">Rename</a>
<a href="javascript:window.open(top.ICEcoder.rightClickedFile.substr((top.ICEcoder.rightClickedFile.indexOf(shortURLStarts)+top.shortURLStarts.length),top.ICEcoder.rightClickedFile.length))" onMouseOver="document.getElementById('fileMenu').style.display='inline-block'">View Webpage</a>
</span>
</div>
<div id="header" class="header" onContextMenu="return false">
<div class="plugins">
<?php
for ($i=0;$i<count($plugins);$i++) {
echo '<a href="'.$plugins[$i][3].'" target="'.$plugins[$i][4].'"><img src="'.$plugins[$i][1].'" style="'.$plugins[$i][2].'" alt="'.$plugins[$i][0].'"></a>';
};
?>
<div class="plugins" id="pluginsContainer">
<?php echo $pluginsDisplay; ?>
</div>
<div class="version"><?php echo $versionNo;?></div>
<img src="images/ice-coder.gif" class="logo">
<img src="images/ice-coder.gif" class="logo" onContextMenu="ICEcoder.settingsScreen('show')">
</div>
<div id="files" class="files" onMouseOver="ICEcoder.changeFilesW('expand')" onMouseOut="ICEcoder.changeFilesW('contract'); top.document.getElementById('fileMenu').style.display='none';">
<div class="account" id="account">
<form name="login" action="index.php" method="POST">
<input type="password" name="loginPassword" class="accountPassword">
<input type="submit" name="submit" value="Login" class="button">
</form>
<div class="accountLoginContainer" id="accountLoginContainer">
<div class="accountLogin" id="accountLogin">
<form name="login" action="lib/settings.php" method="POST" target="ff">
<input type="password" name="loginPassword" class="accountPassword">
<input type="submit" name="submit" value="Login" class="button">
</form>
</div>
</div>
<div class="accountOptions">
<a nohref title="Save" onClick="ICEcoder.fMIcon('save')"><img src="images/save.png" alt="Save" id="fMSave" style="opacity: 0.3"></a>
<a nohref title="Open" onClick="ICEcoder.fMIcon('open')"><img src="images/open.png" alt="Open" id="fMOpen" style="margin-left: 7px; opacity: 0.3"></a>
<a nohref title="New File" onClick="ICEcoder.fMIcon('newFile')"><img src="images/new-file.png" alt="New File" id="fMNewFile" style="margin: 8px 0px 0px 10px; opacity: 0.3"></a>
<a nohref title="New Folder" onClick="ICEcoder.fMIcon('newFolder')"><img src="images/new-folder.png" alt="New Folder" id="fMNewFolder" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
<a nohref title="Delete" onClick="ICEcoder.fMIcon('delete')"><img src="images/delete.png" alt="Delete" id="fMDelete" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
<a nohref title="Rename" onClick="ICEcoder.fMIcon('rename')"><img src="images/rename.png" alt="Rename" id="fMRename" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
<a nohref title="View" onClick="ICEcoder.fMIcon('view')"><img src="images/view.png" alt="View" id="fMView" style="margin: 9px 0px 0px 5px; opacity: 0.3"></a>
</div>
<a nohref style="cursor: pointer" onClick="ICEcoder.lockUnlockNav()"><img src="images/file-manager-icons/padlock.png" id="fmLock" class="lock"></a>
</div>
<iframe id="filesFrame" class="frame" name="ff" src="files.php" style="opacity: 0" onLoad="this.style.opacity='1'"></iframe>
@@ -126,7 +152,7 @@ echo 'fullPath = "'.$docRoot.'";'.PHP_EOL;
</div>
</form>
<form onSubmit="return ICEcoder.goToLine()">
<div class="codeAssist"><input type="checkbox" name="codeAssist" checked onClick="top.ICEcoder.codeAssistToggle()">Code Assist</div>
<div class="codeAssist"><input type="checkbox" name="codeAssist" id="codeAssist" checked onClick="top.ICEcoder.codeAssistToggle()">Code Assist</div>
<div class="goLine">Go to Line<input type="text" name="goToLine" value="" id="goToLineNo" class="textbox goToLine">
</form>
</div>

View File

@@ -24,9 +24,17 @@ body {overflow: hidden;
user-select: none;
}
h1 {font-size: 36px; font-weight: normal; color: #888888; margin-bottom: 20px}
h2 {font-size: 18px; font-weight: normal; color: #ffffff}
.blackMask {position: fixed; display: table; width: 100%; height: 100%; top: 0px; left: 0px; visibility: hidden; background-color: rgba(0,0,0,0.8); text-align: center; z-index: 100}
.blackMask .popupVCenter {#position: absolute; display: table-cell; #top: 50%; vertical-align: middle; text-align: center}
.popupVCenter .popup {#position: relative; #top: -50%; text-align: center; color: #ffffff; font-size: 10px}
.whiteGlow {
-webkit-box-shadow: 0px 0px 8px 2px rgba(255,255,255,0.6);
-moz-box-shadow: 0px 0px 8px 2px rgba(255,255,255,0.6);
box-shadow: 0px 0px 8px 2px rgba(255,255,255,0.6);
}
.circleOutside {background-color: rgba(0,0,0,0); border:5px solid rgba(0,183,229,0.9); opacity:.9; border-top:5px solid rgba(0,0,0,0); border-left:5px solid rgba(0,0,0,0); border-radius:50px; box-shadow: 0 0 35px #2187e7;
width:50px; height:50px; margin:0 auto; -moz-animation:spin .5s infinite linear; -webkit-animation:spin .5s infinite linear;
@@ -64,10 +72,10 @@ body {overflow: hidden;
}
.header {position: absolute; display: inline-block; width: 100%; height: 40px; background-color: #ffffff; text-align: right; z-index: 2}
.header .plugins {position: absolute; display: inline-block; left: 27px; top: 3px}
.header .plugins {position: absolute; display: inline-block; left: 15px; top: 3px}
.header .plugins img {position: relative; display: inline-block; margin-right: 15px}
.header .version {position: relative; display: inline-block; margin-top: 25px; font-size: 10px; color: #bbbbbb}
.header .logo {position: relative; margin: 5px 10px 0px 5px}
.header .logo {position: relative; margin: 5px 10px 0px 5px; cursor: pointer}
.files {position: absolute; display: inline-block; height: 100%; width: 250px; background-color: #e0e0e0; background-image: url('../images/files-arrow.gif'); background-repeat: no-repeat; background-position: 100% 50%; overflow: hidden; z-index: 1;
-webkit-box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.4);
@@ -75,10 +83,25 @@ body {overflow: hidden;
box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.4);
}
.files .account {display: inline-block; height: 50px; width: 250px; margin-top: 40px; background-color: #888888}
.files .accountLoginContainer {position: absolute; width: 250px; height: 50px; z-index: 1}
.files .accountLoginContainer .accountLogin {position: absolute; width: 250px; height: 50px; top: 0px; background-color: #666666;
-webkit-transition: top 0.3s;
-moz-transition: top 0.3s;
-o-transition: top 0.3s;
transition: top 0.3s;
}
.files .accountOptions {position: relative; height: 31px; width: 200px; margin-left: 15px; margin-top: 8px}
.files .accountOptions img {cursor: pointer}
.files .accountPassword {position: relative; border: 1px solid #888888; background-color: #999999; height: 18px; width: 140px; margin-left: 14px; margin-top: 15px}
.files input:focus, .findReplace input:focus, .findReplace select:focus, .accountPassword:focus {
outline: none;
-webkit-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
-moz-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
}
.files .button {position: absolute; border: 0px; background: #999999; color: #555555; height:20px; margin-top: 16px; margin-left: 5px; font-size: 11px; cursor: pointer}
.files .button:hover {background-color: #444444; color: #eeeeee}
.files .lock {margin-left: 225px; margin-top: -20px}
.files .lock {position: relative; margin-left: 225px; margin-top: -20px; z-index: 1}
.files .frame {display: inline-block; width: 250px}
.files .serverMessage {position: absolute; display: inline-block; width: 180px; bottom: 0px; margin-bottom: 30px; background-color: rgba(255,255,255,0.8); font-size: 10px; padding: 7px 12px; opacity: 0;
-webkit-transition: all 0.2s;
@@ -136,4 +159,4 @@ body {overflow: hidden;
.screenVCenter .screenCenter {#position: relative; #top: -50%; text-align: center; display: inline}
.screenCenter .version {position: relative; display: block; margin: 5px 0px 15px 0px; font-size: 10px; color: #bbbbbb}
.screenCenter .accountPassword {border: 1px solid #888888; height: 18px}
.screenCenter .button {border: 0px; background: #666666; color: #ffffff; height: 22px}
.screenCenter .button {border: 0px; background: #666666; color: #ffffff; height: 22px; cursor: pointer}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,4 @@
html, body {margin: 0px}
/* Based VERY loosely on the Monokai theme */
/* ICE coder default theme: Based VERY loosely on Monokai */
.cm-s-icecoder {font-size: 12px; color: #666; background: #1c1c19;}
@@ -35,11 +33,8 @@ html, body {margin: 0px}
.cm-s-icecoder span.cm-hr {color: #999;}
.cm-s-icecoder span.cm-link {color: #ff0;}
.cm-s-icecoder .CodeMirror-selected {background: #037 !important;}
.cm-s-icecoder .CodeMirror-gutter {background: #333; border-right: 1px solid #e8e8e8;}
.cm-s-icecoder .CodeMirror-gutter-text {color: #999; width: 35px;}
.cm-s-icecoder .CodeMirror-cursor {border-left: 1px solid white !important;}
.cm-s-icecoder .CodeMirror-matchingbracket{border: 1px solid grey; color: black !important;}
span.CodeMirror-matchhighlight {background: #555555}
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000000; background: #555555; !important}
.cm-s-icecoder .CodeMirror-selected {background: #037 !important;}
.cm-s-icecoder .CodeMirror-gutter {background: #333; border-right: 1px solid #e8e8e8}
.cm-s-icecoder .CodeMirror-gutter-text {color: #999; width: 35px; cursor: default}
.cm-s-icecoder .CodeMirror-matchingbracket {border: 1px solid grey; color: black !important;}

View File

@@ -28,7 +28,9 @@ if ($_GET['action']=="load") {
}
}
if ($_SESSION['userLevel'] == 10 || ($_SESSION['userLevel'] < 10 && $bannedFile==false)) {
echo '<script>fileType="text";</script>';
echo '<script>fileType="text";top.ICEcoder.rightClickedFile=top.ICEcoder.thisFileFolderLink=\''.$file.'\';';
echo 'shortURL = top.ICEcoder.thisFileFolderLink.replace(/\|/g,"/");';
echo 'top.ICEcoder.shortURL = shortURL.substr((shortURL.indexOf(top.shortURLStarts)+top.shortURLStarts.length),shortURL.length);</script>';
$loadedFile = file_get_contents($file);
echo '<textarea name="loadedFile" id="loadedFile">'.str_replace("</textarea>","<ICEcoder:/:textarea>",$loadedFile).'</textarea>';
} else {
@@ -135,7 +137,7 @@ if ($_GET['action']=="save") {
}
$saveFile = str_replace("\\","/",$_SERVER['DOCUMENT_ROOT']).$file;
$saveFile = str_replace("//","/",$saveFile);
if (is_writable($saveFile)) {
if ((file_exists($saveFile) && is_writable($saveFile)) || $_POST['newFileName']!="") {
$fh = fopen($saveFile, 'w') or die("can't open file");
fwrite($fh, $_POST['contents']);
fclose($fh);
@@ -150,7 +152,7 @@ if ($_GET['action']=="save") {
if (isset($_POST['newFileName'])&&$_POST['newFileName']!="") {
echo '<script>top.ICEcoder.renameTab(top.ICEcoder.selectedTab,\''.$file.'\');</script>';
}
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);action="doneSave";</script>';
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);if (top.ICEcoder.stickyTabWindow.location) {top.ICEcoder.stickyTabWindow.location.reload()};action="doneSave";</script>';
} else {
echo "<script>alert('Sorry, cannot write\\n".$file."');</script>";
echo '<script>top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);action="nothing";</script>';
@@ -191,15 +193,16 @@ if (action=="load") {
top.ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab], null);
top.ICEcoder['cMActiveLine'+top.ICEcoder.selectedTab] = top.ICEcoder.content.contentWindow['cM'+top.ICEcoder.cMInstances[top.ICEcoder.selectedTab-1]].setLineClass(0, "cm-s-activeLine");
top.ICEcoder.nextcMInstance++;
top.ICEcoder.serverMessage();
top.ICEcoder.serverQueue("del",0);
top.ICEcoder.loadingFile = false;
}
if (fileType=="image") {
top.document.getElementById('blackMask').style.visibility = "visible";
top.document.getElementById('mediaContainer').innerHTML = "<img src=\"<?php echo str_replace($docRoot,"",$file);?>\" style=\"border: solid 10px #ffffff; max-width: 700px; max-height: 500px\" onClick=\"return false\"><br><span style=\"border: solid 10px #ffffff; background-color: #ffffff\" onClick=\"return false\"><?php echo str_replace($docRoot,"",$file);?></span>";
top.document.getElementById('mediaContainer').innerHTML = "<img src=\"<?php echo str_replace($docRoot,"",$file);?>\" class=\"whiteGlow\" style=\"border: solid 10px #ffffff; max-width: 700px; max-height: 500px\" onClick=\"return false\"><br><span class=\"whiteGlow\" style=\"border: solid 10px #ffffff; color: #000000; background-color: #ffffff\" onClick=\"return false\"><?php echo str_replace($docRoot,"",$file);?></span>";
}
top.ICEcoder.serverMessage();
top.ICEcoder.serverQueue("del",0);
}
</script>
@@ -219,10 +222,21 @@ if (action=="save") {
} else {
newFileName = prompt('Enter Filename','/');
}
if (newFileName && top.document.getElementById('filesFrame').contentWindow.document.getElementById(newFileName.replace(/\//g,"|"))) {
overwriteOK = confirm('That file exists already, overwrite?');
}
document.saveFile.newFileName.value = newFileName;
<?php ;};?>
document.saveFile.contents.innerHTML = top.document.getElementById('saveTemp1').value;
document.saveFile.submit();
if ("undefined" == typeof newFileName || (newFileName && "undefined" == typeof overwriteOK) || ("undefined" != typeof overwriteOK && overwriteOK)) {
if ("undefined" != typeof newFileName) {
top.ICEcoder.serverMessage('<b>Saving</b><br>'+newFileName);
}
document.saveFile.contents.innerHTML = top.document.getElementById('saveTemp1').value;
document.saveFile.submit();
} else {
top.ICEcoder.serverMessage();top.ICEcoder.serverQueue("del",0);
action=="nothing";
}
}
</script>

View File

@@ -19,6 +19,8 @@ table, caption, tbody, tfoot, thead, tr, th, td {
body {margin: 0px; overflow: auto}
.refresh {float: right; margin-right: 15px; cursor: pointer}
.fileManager {
margin: 15px 0px 15px 22px;
-webkit-user-select: none;
@@ -35,7 +37,7 @@ body {margin: 0px; overflow: auto}
.fileManager li {margin-left: 15px;}
/* Default file */
.fileManager LI.pft-file { list-style-image: url(../images/file-manager-icons/file.png); cursor: pointer;}
.fileManager LI.pft-file { list-style-image: url(../images/file-manager-icons/file.png); }
/* Additional file types */
.fileManager LI.ext-3gp { list-style-image: url(../images/file-manager-icons/film.png); }

45
lib/settings-screen.css Normal file
View File

@@ -0,0 +1,45 @@
/* First, reset everything to a standard */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
border: 0px;
margin: 0px;
padding: 0px;
outline: 0px;
font-size: 12px;
vertical-align: top;
}
body {overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select:none;
user-select: none;
}
h1 {font-size: 36px; font-weight: normal; color: #888888; margin-bottom: 20px}
h2 {font-size: 18px; font-weight: normal; color: #ffffff}
.settings {font-family: arial, verdana, helvetica, sans-serif; background-color: #1c1c19; color: #ffffff}
.settings .infoPane {position: relative; width: 230px; height: 560px; font-size: 10px; color: #bbbbbb; background-color: #ffffff; padding: 20px; float: left}
.settings .infoPane a {color: #888888; text-decoration: none}
.settings .infoPane a:hover {text-decoration: underline}
.settings .logo {position: relative; margin-top: 2px}
.settings .version {position: relative; display: block; margin-top: 5px; margin-bottom: 10px; font-size: 10px; color: #bbbbbb}
.settings .settingsColumn1 {width: 220px; height: 560px; padding: 20px; float: left}
.settings .settingsColumn2 {width: 420px; height: 560px; padding: 20px 20px 20px 0px; float: left}
.settings input, .settings textarea {border: 1px solid #555555; background-color: #444444; color: #ffffff}
.settings input:focus, .settings textarea:focus {
outline: none;
-webkit-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
-moz-box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
box-shadow: 0px 0px 10px 1px rgba(0,198,255,0.7);
}
.settings .plugins {font-family: arial, verdana, helvetica, sans-serif; width: 410px; height: 123px; overflow: hidden}
.settings .update {position: absolute; bottom: 0px; right: 20px; padding: 5px 10px; font-size: 18px; background-color: rgba(0,198,255,0.7); opacity: 0.1; cursor: pointer}

205
lib/settings-screen.php Normal file
View File

@@ -0,0 +1,205 @@
<?php include("settings.php");?>
<!DOCTYPE html>
<html>
<head>
<title>ICE Coder - <?php echo $versionNo;?> :: Settings Screen</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="settings-screen.css">
<link rel="stylesheet" href="../<?php echo $codeMirrorDir; ?>/lib/codemirror.css">
<script src="../<?php echo $codeMirrorDir; ?>/lib/codemirror.js"></script>
<script src="../<?php echo $codeMirrorDir; ?>/mode/javascript/javascript.js"></script>
<style type="text/css">
.CodeMirror {position: absolute; width: 0px; background-color: #ffffff; font-family: monospace}
.CodeMirror-scroll {height: 220px; width: 420px; overflow: hidden}
.cm-s-visible {display: block; top: 0px}
.cm-s-hidden {display: none; top: 4000px}
.cm-s-activeLine {background: #002 !important;}
// Make sure this next one remains the 5th item, updated with JS
.cm-tab:after {position: relative; display: inline-block; width: 0px; left: -1.4em; overflow: visible; color: #aaa; content: "<?php if($visibleTabs) {echo '\21e5';};?>";}
span.CodeMirror-matchhighlight {background: #555555}
.CodeMirror-focused span.CodeMirror-matchhighlight {color: #000000; background: #555555; !important}
</style>
<link rel="stylesheet" href="editor.css">
<?php
$themeArray = array("ambiance","blackboard","cobalt","eclipse","elegant","lesser-dark","monokai","neat","night","rubyblue","xq-dark");
for ($i=0;$i<count($themeArray)-1;$i++) {
echo '<link rel="stylesheet" href="../'.$codeMirrorDir.'/theme/'.$themeArray[$i].'.css">'.PHP_EOL;
}
?>
</head>
<body class="settings">
<div class="infoPane">
<img src="../images/ice-coder.gif" class="logo">
<div class="version"><?php echo $versionNo;?></div>
<p>
git:<br>
<a href="http://github.com/mattpass/ICEcoder" target="_blank">http://github.com/mattpass/ICEcoder</a>
<br><br>
codemirror dir:<br>
<?php echo $codeMirrorDir; ?>
<br><br>
codemirror version:<br>
<?php echo $cMThisVer; ?>
<br><br>
doc root:<br>
<?php if($_SESSION['userLevel']==10) { echo $_SERVER['DOCUMENT_ROOT']; } else { echo '[HIDDEN]'; }; ?>
<br><br><br><br>
<div style="font-size: 10px; line-height: 12px">ICE coder by Matt Pass (<a href="http://www.twitter.com/mattpass" style="font-size: 10px" target="_blank">@mattpass</a>)<br><br>
Free to use it for your own purposes, commercial or not, just let me know of any cool uses or customisations. :)<br><br>
No warranty or liability accepted for anything, all responsibility of use is your own.<br><br>
Thanks go to the following people who have inspired me to create this and in the odd case, provided feedback or code:<br>
<?php
$peopleArray = array("marijnjh", "maettig", "wimtibackx", "jakubvrana", "davidwalshblog", "kuvos", "paul_irish", "mathias", "rem");
for ($i=0;$i<count($peopleArray)-1;$i++) {
echo '<a href="http://www.twitter.com/'.$peopleArray[$i].'" style="font-size: 10px" target="_blank">@'.$peopleArray[$i].'</a>';
if ($i<count($peopleArray)-2) {
echo ", ";
}
}
?>
</div>
</p>
</div>
<form name="settings" action="settings.php" method="POST">
<div class="settingsColumn1">
<h1>settings</h1>
<h2>functionality</h2>
<input type="checkbox" onclick="showButton()" name="tabsIndent" value="true"<?php if($tabsIndent) {echo ' checked';};?>> tab indents selection<br>
<input type="checkbox" onclick="showButton()" name="testcMVersion" value="true"<?php if($testcMVersion) {echo ' checked';};?>> test codemirror version on load<br>
<input type="checkbox" onclick="showButton()" name="openLastFiles" value="true"<?php if($openLastFiles) {echo ' checked';};?>> auto open last files on login<br>
<br>
<h2>assisting</h2>
<input type="checkbox" onclick="showButton()" name="codeAssist" value="true"<?php if($codeAssist) {echo ' checked';};?>> code assist<br>
<input type="checkbox" onclick="showButton();showHideTabs()" name="visibleTabs" value="true"<?php if($visibleTabs) {echo ' checked';};?>> visible tabs<br>
<input type="checkbox" onclick="showButton()" name="lockedNav" value="true"<?php if($lockedNav) {echo ' checked';};?>> locked nav<br>
<br>
<h2>security</h2>
new password <span style="font-size: 10px; color: #888888">8 chars</span><br>
<input type="password" name="accountPassword" onkeydown="showButton()"><br>
confirm password<br>
<input type="password" name="confirmPassword" onkeydown="showButton()"><br>
<input type="hidden" name="oldPassword" value="<?php echo $accountPassword; ?>">
<br>
restricted files/folders<br>
<input type="text" onkeydown="document.settings.changedFileSettings.value='true';showButton()" name="restrictedFiles" value="<?php for($i=0;$i<=count($restrictedFiles)-1;$i++) {echo $restrictedFiles[$i]; if ($i<count($restrictedFiles)-1) {echo ', ';};}; ?>"><br>
banned files/folders<br>
<input type="text" onkeydown="document.settings.changedFileSettings.value='true';showButton()" name="bannedFiles" value="<?php for($i=0;$i<=count($bannedFiles)-1;$i++) {echo $bannedFiles[$i]; if ($i<count($bannedFiles)-1) {echo ', ';};}; ?>"><br>
<input type="hidden" name="changedFileSettings" value="false">
<br>
ip addresses<br>
<input type="text" onkeydown="showButton()" name="allowedIPs" value="<?php for($i=0;$i<=count($allowedIPs)-1;$i++) {echo $allowedIPs[$i]; if ($i<count($allowedIPs)-1) {echo ', ';};}; ?>"><br>
</div>
<div class="settingsColumn2">
<h2>plugins</h2>
plugins array <span style="font-size: 10px; color: #888888">name, img src, style, url, target, setInterval (mins)</span><br>
<textarea name="plugins" class="plugins" onkeydown="showButton()"><?php
for($i=0;$i<count($plugins);$i++) {
for($j=0;$j<count($plugins[$i]);$j++) {
echo '"'.$plugins[$i][$j].'"';
if ($j<count($plugins[$i])-1) {
echo ',';
};
if (!($i==count($plugins)-1 && $j==count($plugins[$i])-1)) {
echo PHP_EOL;
}
if (($i<count($plugins)-1 && $j==count($plugins[$i])-1)) {
echo "====================".PHP_EOL;
}
}
}
?></textarea>
<br><br>
<h2>style</h2>
theme<br>
<select onchange="selectTheme();showButton()" id="select" name="theme">
<option<?php if ($theme=="default") {echo ' selected';}; ?>>default</option>
<?php
for ($i=0;$i<count($themeArray)-1;$i++) {
if ($theme==$themeArray[$i]) {$optionSelected = ' selected';} else {$optionSelected = '';};
echo '<option'.$optionSelected.'>'.$themeArray[$i].'</option>'.PHP_EOL;
}
?>
</select>
<br><br>
<textarea id="code" name="code">
function findSequence(goal) {
function find(start,history) {
if (start==goal)
return history;
else if (start>goal)
return null;
else
return find(start+5,"("+history+"+5)") ||
find(start*3,"("+history+"*3)");
}
return find(1,"1");
}</textarea>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
readOnly: "nocursor",
theme: "<?php if ($theme=="default") {echo 'icecoder';} else {echo $theme;}; ?>"
});
var input = document.getElementById("select");
function selectTheme() {
var theme = input.options[input.selectedIndex].innerHTML;
if (theme=="default") {theme = "icecoder"};
editor.setOption("theme", theme);
}
var showButton = function() {
document.getElementById('updateButton').style.opacity = 1;
}
var showHideTabs = function() {
document.all ? strCSS = 'rules' : strCSS = 'cssRules';
document.settings.visibleTabs.checked ? document.styleSheets[2][strCSS][5].style['content'] = '"\\21e5"' : document.styleSheets[2][strCSS][5].style['content'] = '" "';
}
var validatePasswords = function() {
<?php if($_SESSION['userLevel']==10) { ?>
if (document.settings.accountPassword.value != 0 && document.settings.accountPassword.value.length<8) {
alert('Please use at least 8 chars in the password');
} else {
if (document.settings.accountPassword.value != document.settings.confirmPassword.value) {
alert('Sorry, your passwords don\'t match')
} else {
document.settings.submit();
}
}
<?php } else { ?>
alert('Sorry, you need to be logged in to change settings');
<?php ;}; ?>
}
</script>
<div class="update" id="updateButton" onClick="validatePasswords()">update</div>
</div>
</form>
</body>
</html>

View File

@@ -1,22 +1,5 @@
<?php
$versionNo = "v 0.5.9";
$codeMirrorDir = "CodeMirror-2.22";
$cMThisVer = 2.22;
$testcMVersion = false; // test if we're using the latest CodeMirror version
$restrictedFiles = array("wp-",".php",".asp",".aspx");
$bannedFiles = array("_coder","wp-",".exe");
$allowedIPs = array("*"); // allowed IPs, * for any
$plugins = array(
array("Database Admin","images/database.png","margin-top: 3px","plugins/adminer/adminer-3.3.3-mysql-en.php","_blank",""),
array("Batch Image Processor","images/images.png","margin-top: 5px","http://birme.net","_blank",""),
array("Backup","images/backup-open-files.png","margin-top: 3px","plugins/backupOpenFiles/index.php","fileControl:<b>Zipping Open Files</b>","10"),
array("Clipboard","images/clipboard.png","","javascript:alert('Doesn\'t do anything yet but will be a clipboard for copied text items, up to 100 levels')","_self","")
);
$accountPassword = "";
// ---------------
// End of settings
// ---------------
session_start();
// Function to handle salted hashing
define('SALT_LENGTH',9);
@@ -29,7 +12,107 @@ function generateHash($plainText,$salt=null) {
return $salt.sha1($salt.$plainText);
}
session_start();
// -----------------
// Start of settings
// -----------------
$versionNo = "v 0.6.5";
$codeMirrorDir = "CodeMirror-2.24";
$cMThisVer = 2.24;
$tabsIndent = true;
$testcMVersion = false;
$openLastFiles = true;
$codeAssist = true;
$visibleTabs = false;
$lockedNav = true;
$accountPassword = "";
$restrictedFiles = array("wp-",".php",".asp",".aspx");
$bannedFiles = array("_coder","wp-",".exe",".sql");
$allowedIPs = array("*");
$plugins = array(
array("Database Admin","images/database.png","margin-top: 3px","plugins/adminer/adminer-3.3.3-mysql-en.php","_blank",""),
array("Batch Image Processor","images/images.png","margin-top: 5px","http://birme.net","_blank",""),
array("Backup","images/backup-open-files.png","margin-top: 3px","plugins/backupOpenFiles/index.php","fileControl:<b>Zipping Open Files</b>","10")
);
$theme = "default";
$lastOpenedFiles = "";
// ---------------
// End of settings
// ---------------
// Update this settings file?
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
$settingsFile = 'settings.php';
$settingsContents = file_get_contents($settingsFile);
// Replace our lastOpenedFiles var with the the current
$repPosStart = strpos($settingsContents,'$tabsIndent');
$repPosEnd = strpos($settingsContents,'$lastOpenedFiles');
// Prepare all our vars
if ($_POST['tabsIndent']) {$tabsIndent = "true";} else {$tabsIndent = "false";};
if ($_POST['testcMVersion']) {$testcMVersion = "true";} else {$testcMVersion = "false";};
if ($_POST['openLastFiles']) {$openLastFiles = "true";} else {$openLastFiles = "false";};
if ($_POST['codeAssist']) {$codeAssist = "true";} else {$codeAssist = "false";};
if ($_POST['visibleTabs']) {$visibleTabs = "true";} else {$visibleTabs = "false";};
if ($_POST['lockedNav']) {$lockedNav = "true";} else {$lockedNav = "false";};
if ($_POST['accountPassword']!="") {$accountPassword = generateHash($_POST['accountPassword']);} else {$accountPassword = $_POST['oldPassword'];};
$restrictedFiles = 'array("'.str_replace(', ','","',$_POST['restrictedFiles']).'")';
$bannedFiles = 'array("'.str_replace(', ','","',$_POST['bannedFiles']).'")';
$allowedIPs = 'array("'.str_replace(', ','","',$_POST['allowedIPs']).'")';
$plugins = 'array('.PHP_EOL.' array('.PHP_EOL.' '.str_replace('====================','),'.PHP_EOL.' array(',$_POST['plugins']).'))';
$theme = $_POST['theme'];
$settingsNew = '$tabsIndent = '.$tabsIndent.';'.PHP_EOL;
$settingsNew .= '$testcMVersion = '.$testcMVersion.';'.PHP_EOL;
$settingsNew .= '$openLastFiles = '.$openLastFiles.';'.PHP_EOL;
$settingsNew .= '$codeAssist = '.$codeAssist.';'.PHP_EOL;
$settingsNew .= '$visibleTabs = '.$visibleTabs.';'.PHP_EOL;
$settingsNew .= '$lockedNav = '.$lockedNav.';'.PHP_EOL;
$settingsNew .= '$accountPassword = "'.$accountPassword.'";'.PHP_EOL;
$settingsNew .= '$restrictedFiles = '.$restrictedFiles.';'.PHP_EOL;
$settingsNew .= '$bannedFiles = '.$bannedFiles.';'.PHP_EOL;
$settingsNew .= '$allowedIPs = '.$allowedIPs.';'.PHP_EOL;
$settingsNew .= '$plugins = '.$plugins.';'.PHP_EOL;
$settingsNew .= '$theme = "'.$theme.'";'.PHP_EOL;
// Compile our new settings
$settingsContents = substr($settingsContents,0,$repPosStart).$settingsNew.substr($settingsContents,($repPosEnd),strlen($settingsContents));
// Now update this file
$fh = fopen($settingsFile, 'w') or die("can't update settings file");
fwrite($fh, $settingsContents);
fclose($fh);
// OK, now this file is updated, update our current session with new arrays
$_SESSION['restrictedFiles'] = $restrictedFiles = explode(", ",$_POST['restrictedFiles']);
$_SESSION['bannedFiles'] = $bannedFiles = explode(", ",$_POST['bannedFiles']);
$_SESSION['allowedIPs'] = $allowedIPs = explode(", ",$_POST['allowedIPs']);
// Work out the theme to use now
if ($theme=="default") {$themeURL="lib/editor.css";} else {$themeURL=$codeMirrorDir."/theme/".$theme.".css";};
// Do we need a file manager refresh?
if ($_POST['changedFileSettings']=="true") {$refreshFM="true";} else {$refreshFM="false";};
// With all that worked out, we can now hide the settings screen and apply the new settings
echo "<script>top.ICEcoder.settingsScreen('hide');top.ICEcoder.useNewSettings('".$themeURL."',".$tabsIndent.",".$codeAssist.",".$lockedNav.",".$visibleTabs.",".$refreshFM.");</script>";
}
// Save the currently opened files for next time
if ($_GET['saveFiles']) {
if ($_SESSION['userLevel'] == 10) {
$settingsFile = 'settings.php';
$settingsContents = file_get_contents($settingsFile);
// Replace our lastOpenedFiles var with the the current
$repPosStart = strpos($settingsContents,'lastOpenedFiles = "')+19;
$repPosEnd = strpos($settingsContents,'";',$repPosStart)-$repPosStart;
$settingsContents = substr($settingsContents,0,$repPosStart).$_GET['saveFiles'].substr($settingsContents,($repPosStart+$repPosEnd),strlen($settingsContents));
// Now update this file
$fh = fopen($settingsFile, 'w') or die("can't update settings file");
fwrite($fh, $settingsContents);
fclose($fh);
}
echo '<script>top.ICEcoder.serverQueue("del",0);</script>';
}
// Establish our user level
if (!isset($_SESSION['userLevel'])) {$_SESSION['userLevel'] = 0;};
if(isset($_POST['loginPassword']) && generateHash($_POST['loginPassword'],$accountPassword)==$accountPassword) {$_SESSION['userLevel'] = 10;};
@@ -37,6 +120,19 @@ $_SESSION['userLevel'] = $_SESSION['userLevel'];
if (!isset($_SESSION['restrictedFiles'])) {$_SESSION['restrictedFiles'] = $restrictedFiles;}
if (!isset($_SESSION['bannedFiles'])) {$_SESSION['bannedFiles'] = $bannedFiles;}
if (!isset($_SESSION['allowedIPs'])) {$_SESSION['allowedIPs'] = $allowedIPs;}
// Determin our allowed IP addresses
$allowedIP = false;
for($i=0;$i<count($_SESSION['allowedIPs']);$i++) {
if ($_SESSION['allowedIPs'][$i]==$_SERVER["REMOTE_ADDR"]||$_SESSION['allowedIPs'][$i]=="*") {
$allowedIP = true;
}
}
// If user not allowed to view, boot to site root
if (!$allowedIP) {
echo '<script>top.window.location="/";</script>';
};
// Establish our shortened URL, explode the path based on server type (Linux or Windows)
if (strpos($_SERVER['DOCUMENT_ROOT'],"/")>-1) {$slashType = "/";} else {$slashType = "\\";};
@@ -47,6 +143,56 @@ $shortURLStarts = explode($slashType,$_SERVER['DOCUMENT_ROOT']);
if ($shortURLStarts[count($shortURLStarts)-1]!="") {$trimArray=1;} else {$trimArray=2;}
$shortURLStarts = $shortURLStarts[count($shortURLStarts)-$trimArray];
// If we're updating or calling from the index.php page, do/redo plugins & last opened files
if (($_POST["theme"] && $_SESSION['userLevel'] == 10) || strpos($_SERVER['PHP_SELF'],"index.php")>0) {
// If we're updating, we need to recreate the plugins array
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
$plugins = array();
$pluginsArray = explode("====================",str_replace("\"","",str_replace("\r","",str_replace("\n","",$_POST['plugins']))));
for ($i=0;$i<count($pluginsArray);$i++) {
array_push($plugins, explode(",",$pluginsArray[$i]));
}
}
// Work out the plugins to display to the user
$pluginsDisplay = "";
for ($i=0;$i<count($plugins);$i++) {
$target = explode(":",$plugins[$i][4]);
$pluginsDisplay .= '<a href="'.$plugins[$i][3].'" target="'.$target[0].'"><img src="'.$plugins[$i][1].'" style="'.$plugins[$i][2].'" alt="'.$plugins[$i][0].'"></a>';
};
// If we're updating, replace the plugin display with our newly established one
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
echo "<script>top.document.getElementById('pluginsContainer').innerHTML = '".$pluginsDisplay."';</script>";
}
// Work out what plugins we'll need to set on a setInterval
$onLoadExtras = "";
for ($i=0;$i<count($plugins);$i++) {
if ($plugins[$i][5]!="") {
$onLoadExtras .= ";top.ICEcoder.startPluginIntervals(".$i.",'".$plugins[$i][3]."','".$plugins[$i][4]."','".$plugins[$i][5]."')";
};
};
// If we're updating our settings, clear existing setIntervals & the array refs, then start new ones
if ($_POST["theme"] && $_SESSION['userLevel'] == 10) {
?>
<script>
for (i=0;i<=top.ICEcoder.pluginIntervalRefs.length-1;i++) {
clearInterval(top.ICEcoder['plugTimer'+top.ICEcoder.pluginIntervalRefs[i]]);
}
top.ICEcoder.pluginIntervalRefs = [];
<?php echo $onLoadExtras.PHP_EOL; ?>
</script>
<?php
}
// Finally, open last opened files if we need to (applies to index.php only)
if ($openLastFiles) {
$onLoadExtras .= ";top.ICEcoder.autoOpenFiles()";
}
}
// If we're due to show the settings screen
if ($accountPassword == "" && isset($_GET['settings'])) {
?>
@@ -101,5 +247,15 @@ if ($accountPassword == "" && isset($_GET['settings'])) {
header('Location: lib/settings.php?settings=set');
}
}
// If we're logging in, refresh the file manager and show icons if login is correct
if(isset($_POST['loginPassword'])) {
if(isset($_POST['loginPassword']) && generateHash($_POST['loginPassword'],$accountPassword)==$accountPassword) {
$loginAttempt = 'loginOK';
} else {
$loginAttempt = 'loginFailed';
}
echo "<script>top.ICEcoder.refreshFileManager('".$loginAttempt."');</script>";
}
}
?>

View File

@@ -1,6 +1,9 @@
<!DOCTYPE html>
<body>
<script>
top.ICEcoder.serverMessage("<b>Zipping Open Files</b>");
</script>
<?php
// ------------------------------------
// backupOpenFiles by Matt Pass