diff --git a/.gitignore b/.gitignore index f846571..b04d1df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,16 @@ -# Logs -logs -*.log - -#Ignore our built files -build/* -architecture.json - -# Ignore sensitive stuff -/config/* -!/config/default.json - -node_modules -storage -.idea -*.swp +# Logs +logs +*.log + +#Ignore our built files +build/* +architecture.json + +# Ignore sensitive stuff +/config/* +!/config/default.json + +node_modules +storage +.idea +*.swp diff --git a/Dockerfile b/Dockerfile index 840cbd3..a29b5db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,29 @@ -FROM node:latest - -MAINTAINER David Hudson - -# System update -RUN apt-get -q -y update - -RUN apt-get -q -y install npm -RUN apt-get -q -y install mongodb - -RUN apt-get clean && rm -r /var/lib/apt/lists/* - -EXPOSE 22 -EXPOSE 8000 - -ADD start.sh /start.sh -RUN chmod +x /start.sh - -VOLUME ["/opt/apps"] -COPY . /opt/apps/naturalcrit/ -WORKDIR /opt/apps/naturalcrit/ - -RUN npm install -RUN npm install -g gulp-cli -RUN npm install gulp -RUN gulp fresh - -CMD ["/start.sh"] - +FROM node:latest + +MAINTAINER David Hudson + +# System update +RUN apt-get -q -y update + +RUN apt-get -q -y install npm +RUN apt-get -q -y install mongodb + +RUN apt-get clean && rm -r /var/lib/apt/lists/* + +EXPOSE 22 +EXPOSE 8000 + +ADD start.sh /start.sh +RUN chmod +x /start.sh + +VOLUME ["/opt/apps"] +COPY . /opt/apps/naturalcrit/ +WORKDIR /opt/apps/naturalcrit/ + +RUN npm install +RUN npm install -g gulp-cli +RUN npm install gulp +RUN gulp fresh + +CMD ["/start.sh"] + diff --git a/README.md b/README.md index f4d9caa..24f7324 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,33 @@ -# NaturalCrit -A tool suite for DMs to use for D&D. Check it out [here](http://www.naturalcrit.com). - - -### Getting started -1. Make sure you have [node](https://nodejs.org/en/) -1. Clone down the repo -1. In your terminal, head to the repo -1. Run `npm install` to get all the dependacies -2. Run `npm install -g gulp` to install the gulp build tool -1. Run `gulp fresh`, this will compile and build all the needed libraries (this only has to be done once, unless you add more libs) -1. Run `gulp` to run the project locally. Should be accessible at `localhost:8000` -2. Any changes to files within the proejct will be detected and the propject will automatically re-build - -**Notes:** If you'd like to create and edit homebrews, you'll need to have MongoDB installed and running. - -Have fun! - -### Docker Image -You can use [Docker](https://docs.docker.com) to get up and running with NaturalCrit. - -1. Install Docker -1. Clone the repo -1. In the terminal, go to the repo -1. Build the docker image `docker build -t naturalcrit .` -1. Run the docker container `docker run -dit -p 8000:8000 naturalcrit` -1. You can check out the website on your computer on port 8000 - 1. You may have to use `docker-machine env` to get the IP address of your docker instance - - -### changelog - -You can check out the changelog [here](https://github.com/stolksdorf/NaturalCrit/blob/master/changelog.md) +# NaturalCrit +A tool suite for DMs to use for D&D. Check it out [here](http://www.naturalcrit.com). + + +### Getting started +1. Make sure you have [node](https://nodejs.org/en/) +1. Clone down the repo +1. In your terminal, head to the repo +1. Run `npm install` to get all the dependacies +2. Run `npm install -g gulp` to install the gulp build tool +1. Run `gulp fresh`, this will compile and build all the needed libraries (this only has to be done once, unless you add more libs) +1. Run `gulp` to run the project locally. Should be accessible at `localhost:8000` +2. Any changes to files within the proejct will be detected and the propject will automatically re-build + +**Notes:** If you'd like to create and edit homebrews, you'll need to have MongoDB installed and running. + +Have fun! + +### Docker Image +You can use [Docker](https://docs.docker.com) to get up and running with NaturalCrit. + +1. Install Docker +1. Clone the repo +1. In the terminal, go to the repo +1. Build the docker image `docker build -t naturalcrit .` +1. Run the docker container `docker run -dit -p 8000:8000 naturalcrit` +1. You can check out the website on your computer on port 8000 + 1. You may have to use `docker-machine env` to get the IP address of your docker instance + + +### changelog + +You can check out the changelog [here](https://github.com/stolksdorf/NaturalCrit/blob/master/changelog.md) diff --git a/changelog.md b/changelog.md index 020cd61..4ea135f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # changelog +### Sunday, 29/05/2016 - v2.1.0 +- Finally added a syntax for doing spell lists. A bit in-depth about why this took so long. Essentially I'm running out of syntax to use in stardard Markdown. There are too many unique elements in the PHB-style to be mapped. I solved this earlier by stacking certain elements together (eg. an `
` before a `blockquote` turns it into moster state block), but those are getting unweildly. I would like to simply wrap these in `div`s with classes, but unfortunately Markdown stops processing when within HTML blocks. To get around this I wrote my own override to the Markdown parser and lexer to process Markdown within a simple div class wrapper. This should open the door for more unique syntaxes in the future. Big step! +- Override Ctrl+P (and cmd+P) to launch to the print page. Many people try to just print either the editing or share page to get a PDF. While this dones;t make much sense, I do get a ton of issues about it. So now if you try to do this, it'll just bring you imediately to the print page. Everybody wins! +- The onboarding flow has also been confusing a few users (Homepage -> new -> save -> edit page). If you edit the Homepage text now, a Call to Action to save your work will pop-up. +- Added a 'Recently Edited' and 'Recently Viewed' nav item to the edit and share page respectively. Each will remember the last 8 items you edited or viewed and when you viewed it. Makes use of the new title attribute of brews to easy navigatation. +- Paragraphs now indent properly after lists (thanks u/slitjen!) + ### Friday, 27/05/2016 - v2.0.6 - Updated the issue template for (hopefully) better reporting - Added suggestion to use chrome while PDF printing @@ -17,7 +24,7 @@ - Bumped up the allowed entity size for extra-large brew (Thanks for reporting it dickboner93) - Added a little error box when a save fails with a custom link to reporting the issue on github. -/page +\page ### Saturday, 14/05/2016 - v2.0.0 (finally!) diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index 2671011..1ee3181 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -1,41 +1,41 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var HomebrewAdmin = require('./homebrewAdmin/homebrewAdmin.jsx'); - -var Admin = React.createClass({ - getDefaultProps: function() { - return { - url : "", - admin_key : "", - homebrews : [], - }; - }, - - render : function(){ - var self = this; - return( -
- -
-
- - naturalcrit admin -
-
- -
- - Link to Google Analytics - - -
- - -
- ); - } -}); - -module.exports = Admin; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +var HomebrewAdmin = require('./homebrewAdmin/homebrewAdmin.jsx'); + +var Admin = React.createClass({ + getDefaultProps: function() { + return { + url : "", + admin_key : "", + homebrews : [], + }; + }, + + render : function(){ + var self = this; + return( +
+ +
+
+ + naturalcrit admin +
+
+ + + + +
+ ); + } +}); + +module.exports = Admin; diff --git a/client/admin/admin.less b/client/admin/admin.less index 3863b63..c13063a 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -1,39 +1,39 @@ -@import 'naturalcrit/styles/reset.less'; -@import 'naturalcrit/styles/elements.less'; -@import 'naturalcrit/styles/animations.less'; -@import 'naturalcrit/styles/colors.less'; -@import 'naturalcrit/styles/tooltip.less'; - -@import 'font-awesome/css/font-awesome.css'; - -html,body, #reactContainer, .naturalCrit{ - min-height : 100%; -} - -@sidebarWidth : 250px; - -body{ - background-color : #eee; - font-family : 'Open Sans', sans-serif; - color : #4b5055; - font-weight : 100; - text-rendering : optimizeLegibility; - margin : 0; - padding : 0; - height : 100%; -} - -.admin{ - - header{ - background-color : @red; - font-size: 2em; - padding : 20px 0px; - color : white; - margin-bottom: 30px; - i{ - margin-right: 30px; - } - } - +@import 'naturalcrit/styles/reset.less'; +@import 'naturalcrit/styles/elements.less'; +@import 'naturalcrit/styles/animations.less'; +@import 'naturalcrit/styles/colors.less'; +@import 'naturalcrit/styles/tooltip.less'; + +@import 'font-awesome/css/font-awesome.css'; + +html,body, #reactContainer, .naturalCrit{ + min-height : 100%; +} + +@sidebarWidth : 250px; + +body{ + background-color : #eee; + font-family : 'Open Sans', sans-serif; + color : #4b5055; + font-weight : 100; + text-rendering : optimizeLegibility; + margin : 0; + padding : 0; + height : 100%; +} + +.admin{ + + header{ + background-color : @red; + font-size: 2em; + padding : 20px 0px; + color : white; + margin-bottom: 30px; + i{ + margin-right: 30px; + } + } + } \ No newline at end of file diff --git a/client/admin/homebrewAdmin/brewSearch.jsx b/client/admin/homebrewAdmin/brewSearch.jsx index 09ca881..f2334d7 100644 --- a/client/admin/homebrewAdmin/brewSearch.jsx +++ b/client/admin/homebrewAdmin/brewSearch.jsx @@ -1,72 +1,72 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var request = require('superagent'); - -var BrewSearch = React.createClass({ - - getDefaultProps: function() { - return { - admin_key : '' - }; - }, - - getInitialState: function() { - return { - searchTerm: '', - brew : null, - searching : false - }; - }, - - - search : function(){ - this.setState({ - searching : true - }); - - request.get('/homebrew/api/search?id=' + this.state.searchTerm) - .query({ - admin_key : this.props.admin_key, - }) - .end((err, res)=>{ - console.log(err, res, res.body.brews[0]); - this.setState({ - brew : res.body.brews[0], - - searching : false - }) - }); - }, - - handleChange : function(e){ - this.setState({ - searchTerm : e.target.value - }); - }, - handleSearchClick : function(){ - this.search(); - }, - - renderBrew : function(){ - if(!this.state.brew) return null; - return
-
Edit id : {this.state.brew.editId}
-
Share id : {this.state.brew.shareId}
-
- }, - - render : function(){ - return
- - - - - {this.renderBrew()} -
- }, - -}); - +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +var request = require('superagent'); + +var BrewSearch = React.createClass({ + + getDefaultProps: function() { + return { + admin_key : '' + }; + }, + + getInitialState: function() { + return { + searchTerm: '', + brew : null, + searching : false + }; + }, + + + search : function(){ + this.setState({ + searching : true + }); + + request.get('/homebrew/api/search?id=' + this.state.searchTerm) + .query({ + admin_key : this.props.admin_key, + }) + .end((err, res)=>{ + console.log(err, res, res.body.brews[0]); + this.setState({ + brew : res.body.brews[0], + + searching : false + }) + }); + }, + + handleChange : function(e){ + this.setState({ + searchTerm : e.target.value + }); + }, + handleSearchClick : function(){ + this.search(); + }, + + renderBrew : function(){ + if(!this.state.brew) return null; + return
+
Edit id : {this.state.brew.editId}
+
Share id : {this.state.brew.shareId}
+
+ }, + + render : function(){ + return
+ + + + + {this.renderBrew()} +
+ }, + +}); + module.exports = BrewSearch; \ No newline at end of file diff --git a/client/admin/homebrewAdmin/homebrewAdmin.jsx b/client/admin/homebrewAdmin/homebrewAdmin.jsx index 807f584..c6a7ddb 100644 --- a/client/admin/homebrewAdmin/homebrewAdmin.jsx +++ b/client/admin/homebrewAdmin/homebrewAdmin.jsx @@ -1,159 +1,159 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); -var request = require('superagent'); - -var Moment = require('moment'); - -var BrewSearch = require('./brewSearch.jsx'); - - -var HomebrewAdmin = React.createClass({ - getDefaultProps: function() { - return { - admin_key : '' - }; - }, - - getInitialState: function() { - return { - page: 0, - count : 20, - brewCache : {}, - total : 0, - - processingOldBrews : false - }; - }, - - - fetchBrews : function(page){ - request.get('/homebrew/api/search') - .query({ - admin_key : this.props.admin_key, - count : this.state.count, - page : page - }) - .end((err, res)=>{ - this.state.brewCache[page] = res.body.brews; - this.setState({ - brewCache : this.state.brewCache, - total : res.body.total, - count : res.body.count - }) - }) - }, - - componentDidMount: function() { - this.fetchBrews(this.state.page); - }, - - changePageTo : function(page){ - if(!this.state.brewCache[page]){ - this.fetchBrews(page); - } - this.setState({ - page : page - }) - }, - - - clearInvalidBrews : function(){ - request.get('/homebrew/api/invalid') - .query({admin_key : this.props.admin_key}) - .end((err, res)=>{ - if(!confirm("This will remove " + res.body.count + " brews. Are you sure?")) return; - request.get('/homebrew/api/invalid') - .query({admin_key : this.props.admin_key, do_it : true}) - .end((err, res)=>{ - alert("Done!") - }); - }); - }, - - - deleteBrew : function(brewId){ - if(!confirm("Are you sure you want to delete '" + brewId + "'?")) return; - request.get('/homebrew/api/remove/' + brewId) - .query({admin_key : this.props.admin_key}) - .end(function(err, res){ - window.location.reload(); - }) - }, - - handlePageChange : function(dir){ - this.changePageTo(this.state.page + dir); - }, - - - renderPagnination : function(){ - var outOf; - if(this.state.total){ - outOf = this.state.page + ' / ' + Math.round(this.state.total/this.state.count); - } - return
- - {outOf} - -
- }, - - - renderBrews : function(){ - var brews = this.state.brewCache[this.state.page] || _.times(this.state.count); - return _.map(brews, (brew)=>{ - return - {brew.editId} - {brew.shareId} - {Moment(brew.createdAt).fromNow()} - {Moment(brew.updatedAt).fromNow()} - {Moment(brew.lastViewed).fromNow()} - {brew.views} - -
- -
- - - }); - }, - - renderBrewTable : function(){ - return
- - - - - - - - - - - - - {this.renderBrews()} - -
Edit IdShare IdCreated AtLast UpdatedLast ViewedViews
-
- }, - - render : function(){ - var self = this; - return
-

- Homebrews - {this.state.total} -

- {this.renderPagnination()} - {this.renderBrewTable()} - - - - -
- } -}); - -module.exports = HomebrewAdmin; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); +var request = require('superagent'); + +var Moment = require('moment'); + +var BrewSearch = require('./brewSearch.jsx'); + + +var HomebrewAdmin = React.createClass({ + getDefaultProps: function() { + return { + admin_key : '' + }; + }, + + getInitialState: function() { + return { + page: 0, + count : 20, + brewCache : {}, + total : 0, + + processingOldBrews : false + }; + }, + + + fetchBrews : function(page){ + request.get('/homebrew/api/search') + .query({ + admin_key : this.props.admin_key, + count : this.state.count, + page : page + }) + .end((err, res)=>{ + this.state.brewCache[page] = res.body.brews; + this.setState({ + brewCache : this.state.brewCache, + total : res.body.total, + count : res.body.count + }) + }) + }, + + componentDidMount: function() { + this.fetchBrews(this.state.page); + }, + + changePageTo : function(page){ + if(!this.state.brewCache[page]){ + this.fetchBrews(page); + } + this.setState({ + page : page + }) + }, + + + clearInvalidBrews : function(){ + request.get('/homebrew/api/invalid') + .query({admin_key : this.props.admin_key}) + .end((err, res)=>{ + if(!confirm("This will remove " + res.body.count + " brews. Are you sure?")) return; + request.get('/homebrew/api/invalid') + .query({admin_key : this.props.admin_key, do_it : true}) + .end((err, res)=>{ + alert("Done!") + }); + }); + }, + + + deleteBrew : function(brewId){ + if(!confirm("Are you sure you want to delete '" + brewId + "'?")) return; + request.get('/homebrew/api/remove/' + brewId) + .query({admin_key : this.props.admin_key}) + .end(function(err, res){ + window.location.reload(); + }) + }, + + handlePageChange : function(dir){ + this.changePageTo(this.state.page + dir); + }, + + + renderPagnination : function(){ + var outOf; + if(this.state.total){ + outOf = this.state.page + ' / ' + Math.round(this.state.total/this.state.count); + } + return
+ + {outOf} + +
+ }, + + + renderBrews : function(){ + var brews = this.state.brewCache[this.state.page] || _.times(this.state.count); + return _.map(brews, (brew)=>{ + return + {brew.editId} + {brew.shareId} + {Moment(brew.createdAt).fromNow()} + {Moment(brew.updatedAt).fromNow()} + {Moment(brew.lastViewed).fromNow()} + {brew.views} + +
+ +
+ + + }); + }, + + renderBrewTable : function(){ + return
+ + + + + + + + + + + + + {this.renderBrews()} + +
Edit IdShare IdCreated AtLast UpdatedLast ViewedViews
+
+ }, + + render : function(){ + var self = this; + return
+

+ Homebrews - {this.state.total} +

+ {this.renderPagnination()} + {this.renderBrewTable()} + + + + +
+ } +}); + +module.exports = HomebrewAdmin; diff --git a/client/admin/homebrewAdmin/homebrewAdmin.less b/client/admin/homebrewAdmin/homebrewAdmin.less index 96475f1..6cfc3d5 100644 --- a/client/admin/homebrewAdmin/homebrewAdmin.less +++ b/client/admin/homebrewAdmin/homebrewAdmin.less @@ -1,53 +1,53 @@ - -.homebrewAdmin{ - margin-bottom: 80px; - .brewTable{ - table{ - - th{ - padding : 10px; - font-weight : 800; - } - tr:nth-child(even){ - background-color : fade(@green, 10%); - } - tr.isEmpty{ - background-color : fade(@red, 30%); - } - td{ - min-width : 100px; - padding : 10px; - text-align : center; - - &.preview{ - position : relative; - &:hover{ - .content{ - display : block; - } - } - .content{ - position : absolute; - display : none; - top : 100%; - left : 0px; - z-index : 1000; - max-height : 500px; - width : 300px; - padding : 30px; - background-color : white; - font-family : monospace; - text-align : left; - pointer-events : none; - } - } - } - } - } - .deleteButton{ - cursor: pointer; - } - button.clearOldButton{ - float : right; - } + +.homebrewAdmin{ + margin-bottom: 80px; + .brewTable{ + table{ + + th{ + padding : 10px; + font-weight : 800; + } + tr:nth-child(even){ + background-color : fade(@green, 10%); + } + tr.isEmpty{ + background-color : fade(@red, 30%); + } + td{ + min-width : 100px; + padding : 10px; + text-align : center; + + &.preview{ + position : relative; + &:hover{ + .content{ + display : block; + } + } + .content{ + position : absolute; + display : none; + top : 100%; + left : 0px; + z-index : 1000; + max-height : 500px; + width : 300px; + padding : 30px; + background-color : white; + font-family : monospace; + text-align : left; + pointer-events : none; + } + } + } + } + } + .deleteButton{ + cursor: pointer; + } + button.clearOldButton{ + float : right; + } } \ No newline at end of file diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 591e593..121e68a 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -3,6 +3,19 @@ var _ = require('lodash'); var cx = require('classnames'); var Markdown = require('marked'); +var renderer = new Markdown.Renderer(); + +//Processes the markdown within an HTML block if it's just a class-wrapper +renderer.html = function (html) { + if(_.startsWith(html, '
')){ + var openTag = html.substring(0, html.indexOf('>')+1); + html = html.substring(html.indexOf('>')+1); + html = html.substring(0, html.lastIndexOf('
')); + return `${openTag} ${Markdown(html)} `; + } + return html; +} + var PAGE_HEIGHT = 1056 + 30; @@ -64,7 +77,7 @@ var BrewRenderer = React.createClass({ }, renderPage : function(pageText, index){ - return
+ return
}, renderPages : function(){ diff --git a/client/homebrew/brewRenderer/brewRenderer.less b/client/homebrew/brewRenderer/brewRenderer.less index 1608751..8a854dd 100644 --- a/client/homebrew/brewRenderer/brewRenderer.less +++ b/client/homebrew/brewRenderer/brewRenderer.less @@ -1,28 +1,28 @@ - -@import (less) './client/homebrew/phbStyle/phb.style.less'; -.pane{ - position : relative; -} -.brewRenderer{ - overflow-y : scroll; - .pageInfo{ - position : absolute; - right : 17px; - bottom : 0; - z-index : 1000; - padding : 8px 10px; - background-color : #333; - font-size : 10px; - font-weight : 800; - color : white; - } - .pages{ - margin : 30px 0px; - &>.phb{ - margin-right : auto; - margin-bottom : 30px; - margin-left : auto; - box-shadow : 1px 4px 14px #000; - } - } + +@import (less) './client/homebrew/phbStyle/phb.style.less'; +.pane{ + position : relative; +} +.brewRenderer{ + overflow-y : scroll; + .pageInfo{ + position : absolute; + right : 17px; + bottom : 0; + z-index : 1000; + padding : 8px 10px; + background-color : #333; + font-size : 10px; + font-weight : 800; + color : white; + } + .pages{ + margin : 30px 0px; + &>.phb{ + margin-right : auto; + margin-bottom : 30px; + margin-left : auto; + box-shadow : 1px 4px 14px #000; + } + } } \ No newline at end of file diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 43259a5..dda0dce 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -1,129 +1,129 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx'); -var Snippets = require('./snippets/snippets.js'); - - -var splice = function(str, index, inject){ - return str.slice(0, index) + inject + str.slice(index); -}; -var execute = function(val){ - if(_.isFunction(val)) return val(); - return val; -} - - -var Editor = React.createClass({ - getDefaultProps: function() { - return { - value : "", - onChange : function(){} - }; - }, - cursorPosition : { - line : 0, - ch : 0 - }, - - componentDidMount: function() { - var paneHeight = this.refs.main.parentNode.clientHeight; - paneHeight -= this.refs.snippetBar.clientHeight + 1; - this.refs.codeEditor.codeMirror.setSize(null, paneHeight); - }, - - handleTextChange : function(text){ - this.props.onChange(text); - }, - handleCursorActivty : function(curpos){ - this.cursorPosition = curpos; - }, - - handleSnippetClick : function(injectText){ - var lines = this.props.value.split('\n'); - lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText); - - this.handleTextChange(lines.join('\n')); - this.refs.codeEditor.setCursorPosition(this.cursorPosition.line, this.cursorPosition.ch + injectText.length); - }, - - //Called when there are changes to the editor's dimensions - update : function(){ - this.refs.codeEditor.updateSize(); - }, - - renderSnippetGroups : function(){ - return _.map(Snippets, (snippetGroup)=>{ - return - }) - }, - - render : function(){ - return( -
-
- {this.renderSnippetGroups()} -
- -
- ); - } -}); - -module.exports = Editor; - - - - - - - - - -var SnippetGroup = React.createClass({ - getDefaultProps: function() { - return { - groupName : '', - icon : 'fa-rocket', - snippets : [], - onSnippetClick : function(){}, - }; - }, - handleSnippetClick : function(snippet){ - this.props.onSnippetClick(execute(snippet.gen)); - }, - renderSnippets : function(){ - return _.map(this.props.snippets, (snippet)=>{ - return
- - {snippet.name} -
- }) - }, - - render : function(){ - return
-
- - {this.props.groupName} -
-
- {this.renderSnippets()} -
-
- }, - +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +var CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx'); +var Snippets = require('./snippets/snippets.js'); + + +var splice = function(str, index, inject){ + return str.slice(0, index) + inject + str.slice(index); +}; +var execute = function(val){ + if(_.isFunction(val)) return val(); + return val; +} + + +var Editor = React.createClass({ + getDefaultProps: function() { + return { + value : "", + onChange : function(){} + }; + }, + cursorPosition : { + line : 0, + ch : 0 + }, + + componentDidMount: function() { + var paneHeight = this.refs.main.parentNode.clientHeight; + paneHeight -= this.refs.snippetBar.clientHeight + 1; + this.refs.codeEditor.codeMirror.setSize(null, paneHeight); + }, + + handleTextChange : function(text){ + this.props.onChange(text); + }, + handleCursorActivty : function(curpos){ + this.cursorPosition = curpos; + }, + + handleSnippetClick : function(injectText){ + var lines = this.props.value.split('\n'); + lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText); + + this.handleTextChange(lines.join('\n')); + this.refs.codeEditor.setCursorPosition(this.cursorPosition.line, this.cursorPosition.ch + injectText.length); + }, + + //Called when there are changes to the editor's dimensions + update : function(){ + this.refs.codeEditor.updateSize(); + }, + + renderSnippetGroups : function(){ + return _.map(Snippets, (snippetGroup)=>{ + return + }) + }, + + render : function(){ + return( +
+
+ {this.renderSnippetGroups()} +
+ +
+ ); + } +}); + +module.exports = Editor; + + + + + + + + + +var SnippetGroup = React.createClass({ + getDefaultProps: function() { + return { + groupName : '', + icon : 'fa-rocket', + snippets : [], + onSnippetClick : function(){}, + }; + }, + handleSnippetClick : function(snippet){ + this.props.onSnippetClick(execute(snippet.gen)); + }, + renderSnippets : function(){ + return _.map(this.props.snippets, (snippet)=>{ + return
+ + {snippet.name} +
+ }) + }, + + render : function(){ + return
+
+ + {this.props.groupName} +
+
+ {this.renderSnippets()} +
+
+ }, + }); \ No newline at end of file diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index b924076..377c716 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -1,56 +1,56 @@ - -.editor{ - position : relative; - width : 100%; - .snippetBar{ - display : flex; - padding : 5px; - background-color : #ddd; - align-items : center; - .snippetGroup{ - .animate(background-color); - margin : 0px 8px; - padding : 3px; - font-size : 13px; - border-radius : 5px; - &:hover, &.selected{ - background-color : #999; - } - .text{ - line-height : 20px; - .groupName{ - margin-left : 6px; - font-size : 10px; - } - } - &:hover{ - .dropdown{ - visibility : visible; - } - } - .dropdown{ - position : absolute; - visibility : hidden; - z-index : 1000; - padding : 5px; - background-color : #ddd; - .snippet{ - .animate(background-color); - padding : 10px; - cursor : pointer; - font-size : 10px; - i{ - margin-right: 8px; - font-size : 13px; - } - &:hover{ - background-color : #999; - } - } - } - } - } - .codeEditor{ - height : 100%; - } + +.editor{ + position : relative; + width : 100%; + .snippetBar{ + display : flex; + padding : 5px; + background-color : #ddd; + align-items : center; + .snippetGroup{ + .animate(background-color); + margin : 0px 8px; + padding : 3px; + font-size : 13px; + border-radius : 5px; + &:hover, &.selected{ + background-color : #999; + } + .text{ + line-height : 20px; + .groupName{ + margin-left : 6px; + font-size : 10px; + } + } + &:hover{ + .dropdown{ + visibility : visible; + } + } + .dropdown{ + position : absolute; + visibility : hidden; + z-index : 1000; + padding : 5px; + background-color : #ddd; + .snippet{ + .animate(background-color); + padding : 10px; + cursor : pointer; + font-size : 10px; + i{ + margin-right: 8px; + font-size : 13px; + } + &:hover{ + background-color : #999; + } + } + } + } + } + .codeEditor{ + height : 100%; + } } \ No newline at end of file diff --git a/client/homebrew/editor/snippets/classfeature.gen.js b/client/homebrew/editor/snippets/classfeature.gen.js index a462f5e..e79dc24 100644 --- a/client/homebrew/editor/snippets/classfeature.gen.js +++ b/client/homebrew/editor/snippets/classfeature.gen.js @@ -1,42 +1,42 @@ -var _ = require('lodash'); - -module.exports = function(classname){ - - classname = classname || _.sample(['archivist', 'fancyman', 'linguist', 'fletcher', - 'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']) - - classname = classname.toLowerCase(); - - var hitDie = _.sample([4, 6, 8, 10, 12]); - - var abilityList = ["Strength", "Dexerity", "Constitution", "Wisdom", "Charisma", "Intelligence"]; - var skillList = ["Acrobatics ", "Animal Handling", "Arcana", "Athletics", "Deception", "History", "Insight", "Intimidation", "Investigation", "Medicine", "Nature", "Perception", "Performance", "Persuasion", "Religion", "Sleight of Hand", "Stealth", "Survival"]; - - - return [ - "## Class Features", - "As a " + classname + ", you gain the following class features", - "#### Hit Points", - "___", - "- **Hit Dice:** 1d" + hitDie + " per " + classname + " level", - "- **Hit Points at 1st Level:** " + hitDie + " + your Constituion modifier", - "- **Hit Points at Higher Levels:** 1d" + hitDie + " (or " + (hitDie/2 + 1) + ") + your Constituion modifier per " + classname + " level after 1st", - "", - "#### Proficiencies", - "___", - "- **Armor:** " + (_.sampleSize(["Light armor", "Medium armor", "Heavy armor", "Shields"], _.random(0,3)).join(', ') || "None"), - "- **Weapons:** " + (_.sampleSize(["Squeegee", "Rubber Chicken", "Simple weapons", "Martial weapons"], _.random(0,2)).join(', ') || "None"), - "- **Tools:** " + (_.sampleSize(["Artian's tools", "one musical instrument", "Thieve's tools"], _.random(0,2)).join(', ') || "None"), - "", - "___", - "- **Saving Throws:** " + (_.sampleSize(abilityList, 2).join(', ')), - "- **Skills:** Choose two from " + (_.sampleSize(skillList, _.random(4, 6)).join(', ')), - "", - "#### Equipment", - "You start with the following equipment, in addition to the equipment granted by your background:", - "- *(a)* a martial weapon and a shield or *(b)* two martial weapons", - "- *(a)* five javelins or *(b)* any simple melee weapon", - "- " + (_.sample(["10 lint fluffs", "1 button", "a cherished lost sock"])), - "\n\n\n" - ].join('\n'); +var _ = require('lodash'); + +module.exports = function(classname){ + + classname = classname || _.sample(['archivist', 'fancyman', 'linguist', 'fletcher', + 'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']) + + classname = classname.toLowerCase(); + + var hitDie = _.sample([4, 6, 8, 10, 12]); + + var abilityList = ["Strength", "Dexerity", "Constitution", "Wisdom", "Charisma", "Intelligence"]; + var skillList = ["Acrobatics ", "Animal Handling", "Arcana", "Athletics", "Deception", "History", "Insight", "Intimidation", "Investigation", "Medicine", "Nature", "Perception", "Performance", "Persuasion", "Religion", "Sleight of Hand", "Stealth", "Survival"]; + + + return [ + "## Class Features", + "As a " + classname + ", you gain the following class features", + "#### Hit Points", + "___", + "- **Hit Dice:** 1d" + hitDie + " per " + classname + " level", + "- **Hit Points at 1st Level:** " + hitDie + " + your Constituion modifier", + "- **Hit Points at Higher Levels:** 1d" + hitDie + " (or " + (hitDie/2 + 1) + ") + your Constituion modifier per " + classname + " level after 1st", + "", + "#### Proficiencies", + "___", + "- **Armor:** " + (_.sampleSize(["Light armor", "Medium armor", "Heavy armor", "Shields"], _.random(0,3)).join(', ') || "None"), + "- **Weapons:** " + (_.sampleSize(["Squeegee", "Rubber Chicken", "Simple weapons", "Martial weapons"], _.random(0,2)).join(', ') || "None"), + "- **Tools:** " + (_.sampleSize(["Artian's tools", "one musical instrument", "Thieve's tools"], _.random(0,2)).join(', ') || "None"), + "", + "___", + "- **Saving Throws:** " + (_.sampleSize(abilityList, 2).join(', ')), + "- **Skills:** Choose two from " + (_.sampleSize(skillList, _.random(4, 6)).join(', ')), + "", + "#### Equipment", + "You start with the following equipment, in addition to the equipment granted by your background:", + "- *(a)* a martial weapon and a shield or *(b)* two martial weapons", + "- *(a)* five javelins or *(b)* any simple melee weapon", + "- " + (_.sample(["10 lint fluffs", "1 button", "a cherished lost sock"])), + "\n\n\n" + ].join('\n'); } \ No newline at end of file diff --git a/client/homebrew/editor/snippets/magic.gen.js b/client/homebrew/editor/snippets/magic.gen.js new file mode 100644 index 0000000..82469cd --- /dev/null +++ b/client/homebrew/editor/snippets/magic.gen.js @@ -0,0 +1,91 @@ +var _ = require('lodash'); + +var spellNames = [ + "Astral Rite of Acne", + "Create Acne", + "Cursed Ramen Erruption", + "Dark Chant of the Dentists", + "Erruption of Immaturity", + "Flaming Disc of Inconvenience", + "Heal Bad Hygene", + "Heavenly Transfiguration of the Cream Devil", + "Hellish Cage of Mucus", + "Irritate Peanut Butter Fairy", + "Luminous Erruption of Tea", + "Mystic Spell of the Poser", + "Sorcerous Enchantment of the Chimneysweep", + "Steak Sauce Ray", + "Talk to Groupie", + "Astonishing Chant of Chocolate", + "Astounding Pasta Puddle", + "Ball of Annoyance", + "Cage of Yarn", + "Control Noodles Elemental", + "Create Nervousness", + "Cure Baldness", + "Cursed Ritual of Bad Hair", + "Dispell Piles in Dentist", + "Eliminate Florists", + "Illusionary Transfiguration of the Babysitter", + "Necromantic Armor of Salad Dressing", + "Occult Transfiguration of Foot Fetish", + "Protection from Mucus Giant", + "Tinsel Blast", + "Alchemical Evocation of the Goths", + "Call Fangirl", + "Divine Spell of Crossdressing", + "Dominate Ramen Giant", + "Eliminate Vindictiveness in Gym Teacher", + "Extra-Planar Spell of Irritation", + "Induce Whining in Babysitter", + "Invoke Complaining", + "Magical Enchantment of Arrogance", + "Occult Globe of Salad Dressing", + "Overwhelming Enchantment of the Chocolate Fairy", + "Sorcerous Dandruff Globe", + "Spiritual Invocation of the Costumers", + "Ultimate Rite of the Confetti Angel", + "Ultimate Ritual of Mouthwash", +]; + +module.exports = { + + spellList : function(){ + var levels = ['Cantrips (0 Level)', '2nd Level', '3rd Level', '4th Level', '5th Level', '6th Level', '7th Level', '8th Level', '9th Level']; + + var content = _.map(levels, (level)=>{ + var spells = _.map(_.sampleSize(spellNames, _.random(5, 15)), (spell)=>{ + return `- ${spell}`; + }).join('\n'); + return `##### ${level} \n${spells} \n`; + }).join('\n'); + + return `
\n${content}\n
`; + }, + + spell : function(){ + var level = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th"]; + var spellSchools = ["abjuration", "conjuration", "divination", "enchantment", "evocation", "illusion", "necromancy", "transmutation"]; + + + var components = _.sampleSize(["V", "S", "M"], _.random(1,3)).join(', '); + if(components.indexOf("M") !== -1){ + components += " (" + _.sampleSize(['a small doll', 'a crushed button worth at least 1cp', 'discarded gum wrapper'], _.random(1,3)).join(', ') + ")" + } + + return [ + "#### " + _.sample(spellNames), + "*" + _.sample(level) + "-level " + _.sample(spellSchools) + "*", + "___", + "- **Casting Time:** 1 action", + "- **Range:** " + _.sample(["Self", "Touch", "30 feet", "60 feet"]), + "- **Components:** " + components, + "- **Duration:** " + _.sample(["Until dispelled", "1 round", "Instantaneous", "Concentration, up to 10 minutes", "1 hour"]), + "", + "A flame, equivalent in brightness to a torch, springs from from an object that you touch. ", + "The effect look like a regular flame, but it creates no heat and doesn't use oxygen. ", + "A *continual flame* can be covered or hidden but not smothered or quenched.", + "\n\n\n" + ].join('\n'); + } +} \ No newline at end of file diff --git a/client/homebrew/editor/snippets/monsterblock.gen.js b/client/homebrew/editor/snippets/monsterblock.gen.js index 796f1d1..abbcd6c 100644 --- a/client/homebrew/editor/snippets/monsterblock.gen.js +++ b/client/homebrew/editor/snippets/monsterblock.gen.js @@ -1,196 +1,196 @@ -var _ = require('lodash'); - -var genList = function(list, max){ - return _.sampleSize(list, _.random(0,max)).join(', ') || "None"; -} - -var getMonsterName = function(){ - return _.sample([ - "All-devouring Baseball Imp", - "All-devouring Gumdrop Wraith", - "Chocolate Hydra", - "Devouring Peacock", - "Economy-sized Colossus of the Lemonade Stand", - "Ghost Pigeon", - "Gibbering Duck", - "Sparklemuffin Peacock Spider", - "Gum Elemental", - "Illiterate Construct of the Candy Store", - "Ineffable Chihuahua", - "Irritating Death Hamster", - "Irritating Gold Mouse", - "Juggernaut Snail", - "Juggernaut of the Sock Drawer", - "Koala of the Cosmos", - "Mad Koala of the West", - "Milk Djinni of the Lemonade Stand", - "Mind Ferret", - "Mystic Salt Spider", - "Necrotic Halitosis Angel", - "Pinstriped Famine Sheep", - "Ritalin Leech", - "Shocker Kangaroo", - "Stellar Tennis Juggernaut", - "Wailing Quail of the Sun", - "Angel Pigeon", - "Anime Sphinx", - "Bored Avalanche Sheep of the Wasteland", - "Devouring Nougat Sphinx of the Sock Drawer", - "Djinni of the Footlocker", - "Ectoplasmic Jazz Devil", - "Flatuent Angel", - "Gelatinous Duck of the Dream-Lands", - "Gelatinous Mouse", - "Golem of the Footlocker", - "Lich Wombat", - "Mechanical Sloth of the Past", - "Milkshake Succubus", - "Puffy Bone Peacock of the East", - "Rainbow Manatee", - "Rune Parrot", - "Sand Cow", - "Sinister Vanilla Dragon", - "Snail of the North", - "Spider of the Sewer", - "Stellar Sawdust Leech", - "Storm Anteater of Hell", - "Stupid Spirit of the Brewery", - "Time Kangaroo", - "Tomb Poodle", - ]); -} - -var getType = function(){ - return _.sample(['Tiny', 'Small', 'Medium', 'Large', 'Gargantuan', 'Stupidly vast']) + " " + _.sample(['beast', 'fiend', 'annoyance', 'guy', 'cutie']) -} - -var getAlignment = function(){ - return _.sample([ - "annoying evil", - "chaotic gossipy", - "chaotic sloppy", - "depressed neutral", - "lawful bogus", - "lawful coy", - "manic-depressive evil", - "narrow-minded neutral", - "neutral annoying", - "neutral ignorant", - "oedpipal neutral", - "silly neutral", - "unoriginal neutral", - "weird neutral", - "wordy evil", - "unaligned" - ]); -}; - -var getStats = function(){ - return '>|' + _.times(6, function(){ - var num = _.random(1,20); - var mod = Math.ceil(num/2 - 5) - return num + " (" + (mod >= 0 ? '+'+mod : mod ) + ")" - }).join('|') + '|'; -} - -var genAbilities = function(){ - return _.sample([ - "> ***Pack Tactics.*** These guys work together. Like super well, you don't even know.", - "> ***False Appearance. *** While the armor reamin motionless, it is indistinguishable from a normal suit of armor.", - ]); -} - -var genAction = function(){ - var name = _.sample([ - "Abdominal Drop", - "Airplane Hammer", - "Atomic Death Throw", - "Bulldog Rake", - "Corkscrew Strike", - "Crossed Splash", - "Crossface Suplex", - "DDT Powerbomb", - "Dual Cobra Wristlock", - "Dual Throw", - "Elbow Hold", - "Gory Body Sweep", - "Heel Jawbreaker", - "Jumping Driver", - "Open Chin Choke", - "Scorpion Flurry", - "Somersault Stump Fists", - "Suffering Wringer", - "Super Hip Submission", - "Super Spin", - "Team Elbow", - "Team Foot", - "Tilt-a-whirl Chin Sleeper", - "Tilt-a-whirl Eye Takedown", - "Turnbuckle Roll" - ]) - - return "> ***" + name + ".*** *Melee Weapon Attack:* +4 to hit, reach 5ft., one target. *Hit* 5 (1d6 + 2) "; -} - - -module.exports = { - - full : function(){ - return [ - "___", - "___", - "> ## " + getMonsterName(), - ">*" + getType() + ", " + getAlignment() + "*", - "> ___", - "> - **Armor Class** " + _.random(10,20), - "> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)", - "> - **Speed** " + _.random(0,50) + "ft.", - ">___", - ">|STR|DEX|CON|INT|WIS|CHA|", - ">|:---:|:---:|:---:|:---:|:---:|:---:|", - getStats(), - ">___", - "> - **Condition Immunities** " + genList(["groggy", "swagged", "weak-kneed", "buzzed", "groovy", "melancholy", "drunk"], 3), - "> - **Senses** passive Perception " + _.random(3, 20), - "> - **Languages** " + genList(["Common", "Pottymouth", "Gibberish", "Latin", "Jive"], 2), - "> - **Challenge** " + _.random(0, 15) + " (" + _.random(10,10000)+ " XP)", - "> ___", - _.times(_.random(3,6), function(){ - return genAbilities() - }).join('\n>\n'), - "> ### Actions", - _.times(_.random(4,6), function(){ - return genAction() - }).join('\n>\n'), - ].join('\n') + '\n\n\n'; - }, - - half : function(){ - return [ - "___", - "> ## " + getMonsterName(), - ">*" + getType() + ", " + getAlignment() + "*", - "> ___", - "> - **Armor Class** " + _.random(10,20), - "> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)", - "> - **Speed** " + _.random(0,50) + "ft.", - ">___", - ">|STR|DEX|CON|INT|WIS|CHA|", - ">|:---:|:---:|:---:|:---:|:---:|:---:|", - getStats(), - ">___", - "> - **Condition Immunities** " + genList(["groggy", "swagged", "weak-kneed", "buzzed", "groovy", "melancholy", "drunk"], 3), - "> - **Senses** passive Perception " + _.random(3, 20), - "> - **Languages** " + genList(["Common", "Pottymouth", "Gibberish", "Latin", "Jive"], 2), - "> - **Challenge** " + _.random(0, 15) + " (" + _.random(10,10000)+ " XP)", - "> ___", - _.times(_.random(0,2), function(){ - return genAbilities() - }).join('\n>\n'), - "> ### Actions", - _.times(_.random(1,2), function(){ - return genAction() - }).join('\n>\n'), - ].join('\n') + '\n\n\n'; - } -} +var _ = require('lodash'); + +var genList = function(list, max){ + return _.sampleSize(list, _.random(0,max)).join(', ') || "None"; +} + +var getMonsterName = function(){ + return _.sample([ + "All-devouring Baseball Imp", + "All-devouring Gumdrop Wraith", + "Chocolate Hydra", + "Devouring Peacock", + "Economy-sized Colossus of the Lemonade Stand", + "Ghost Pigeon", + "Gibbering Duck", + "Sparklemuffin Peacock Spider", + "Gum Elemental", + "Illiterate Construct of the Candy Store", + "Ineffable Chihuahua", + "Irritating Death Hamster", + "Irritating Gold Mouse", + "Juggernaut Snail", + "Juggernaut of the Sock Drawer", + "Koala of the Cosmos", + "Mad Koala of the West", + "Milk Djinni of the Lemonade Stand", + "Mind Ferret", + "Mystic Salt Spider", + "Necrotic Halitosis Angel", + "Pinstriped Famine Sheep", + "Ritalin Leech", + "Shocker Kangaroo", + "Stellar Tennis Juggernaut", + "Wailing Quail of the Sun", + "Angel Pigeon", + "Anime Sphinx", + "Bored Avalanche Sheep of the Wasteland", + "Devouring Nougat Sphinx of the Sock Drawer", + "Djinni of the Footlocker", + "Ectoplasmic Jazz Devil", + "Flatuent Angel", + "Gelatinous Duck of the Dream-Lands", + "Gelatinous Mouse", + "Golem of the Footlocker", + "Lich Wombat", + "Mechanical Sloth of the Past", + "Milkshake Succubus", + "Puffy Bone Peacock of the East", + "Rainbow Manatee", + "Rune Parrot", + "Sand Cow", + "Sinister Vanilla Dragon", + "Snail of the North", + "Spider of the Sewer", + "Stellar Sawdust Leech", + "Storm Anteater of Hell", + "Stupid Spirit of the Brewery", + "Time Kangaroo", + "Tomb Poodle", + ]); +} + +var getType = function(){ + return _.sample(['Tiny', 'Small', 'Medium', 'Large', 'Gargantuan', 'Stupidly vast']) + " " + _.sample(['beast', 'fiend', 'annoyance', 'guy', 'cutie']) +} + +var getAlignment = function(){ + return _.sample([ + "annoying evil", + "chaotic gossipy", + "chaotic sloppy", + "depressed neutral", + "lawful bogus", + "lawful coy", + "manic-depressive evil", + "narrow-minded neutral", + "neutral annoying", + "neutral ignorant", + "oedpipal neutral", + "silly neutral", + "unoriginal neutral", + "weird neutral", + "wordy evil", + "unaligned" + ]); +}; + +var getStats = function(){ + return '>|' + _.times(6, function(){ + var num = _.random(1,20); + var mod = Math.ceil(num/2 - 5) + return num + " (" + (mod >= 0 ? '+'+mod : mod ) + ")" + }).join('|') + '|'; +} + +var genAbilities = function(){ + return _.sample([ + "> ***Pack Tactics.*** These guys work together. Like super well, you don't even know.", + "> ***False Appearance. *** While the armor reamin motionless, it is indistinguishable from a normal suit of armor.", + ]); +} + +var genAction = function(){ + var name = _.sample([ + "Abdominal Drop", + "Airplane Hammer", + "Atomic Death Throw", + "Bulldog Rake", + "Corkscrew Strike", + "Crossed Splash", + "Crossface Suplex", + "DDT Powerbomb", + "Dual Cobra Wristlock", + "Dual Throw", + "Elbow Hold", + "Gory Body Sweep", + "Heel Jawbreaker", + "Jumping Driver", + "Open Chin Choke", + "Scorpion Flurry", + "Somersault Stump Fists", + "Suffering Wringer", + "Super Hip Submission", + "Super Spin", + "Team Elbow", + "Team Foot", + "Tilt-a-whirl Chin Sleeper", + "Tilt-a-whirl Eye Takedown", + "Turnbuckle Roll" + ]) + + return "> ***" + name + ".*** *Melee Weapon Attack:* +4 to hit, reach 5ft., one target. *Hit* 5 (1d6 + 2) "; +} + + +module.exports = { + + full : function(){ + return [ + "___", + "___", + "> ## " + getMonsterName(), + ">*" + getType() + ", " + getAlignment() + "*", + "> ___", + "> - **Armor Class** " + _.random(10,20), + "> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)", + "> - **Speed** " + _.random(0,50) + "ft.", + ">___", + ">|STR|DEX|CON|INT|WIS|CHA|", + ">|:---:|:---:|:---:|:---:|:---:|:---:|", + getStats(), + ">___", + "> - **Condition Immunities** " + genList(["groggy", "swagged", "weak-kneed", "buzzed", "groovy", "melancholy", "drunk"], 3), + "> - **Senses** passive Perception " + _.random(3, 20), + "> - **Languages** " + genList(["Common", "Pottymouth", "Gibberish", "Latin", "Jive"], 2), + "> - **Challenge** " + _.random(0, 15) + " (" + _.random(10,10000)+ " XP)", + "> ___", + _.times(_.random(3,6), function(){ + return genAbilities() + }).join('\n>\n'), + "> ### Actions", + _.times(_.random(4,6), function(){ + return genAction() + }).join('\n>\n'), + ].join('\n') + '\n\n\n'; + }, + + half : function(){ + return [ + "___", + "> ## " + getMonsterName(), + ">*" + getType() + ", " + getAlignment() + "*", + "> ___", + "> - **Armor Class** " + _.random(10,20), + "> - **Hit Points** " + _.random(1, 150) + "(1d4 + 5)", + "> - **Speed** " + _.random(0,50) + "ft.", + ">___", + ">|STR|DEX|CON|INT|WIS|CHA|", + ">|:---:|:---:|:---:|:---:|:---:|:---:|", + getStats(), + ">___", + "> - **Condition Immunities** " + genList(["groggy", "swagged", "weak-kneed", "buzzed", "groovy", "melancholy", "drunk"], 3), + "> - **Senses** passive Perception " + _.random(3, 20), + "> - **Languages** " + genList(["Common", "Pottymouth", "Gibberish", "Latin", "Jive"], 2), + "> - **Challenge** " + _.random(0, 15) + " (" + _.random(10,10000)+ " XP)", + "> ___", + _.times(_.random(0,2), function(){ + return genAbilities() + }).join('\n>\n'), + "> ### Actions", + _.times(_.random(1,2), function(){ + return genAction() + }).join('\n>\n'), + ].join('\n') + '\n\n\n'; + } +} diff --git a/client/homebrew/editor/snippets/snippets.js b/client/homebrew/editor/snippets/snippets.js index 5275c90..5fa6947 100644 --- a/client/homebrew/editor/snippets/snippets.js +++ b/client/homebrew/editor/snippets/snippets.js @@ -1,11 +1,10 @@ -var SpellGen = require('./spell.gen.js'); +var MagicGen = require('./magic.gen.js'); var ClassTableGen = require('./classtable.gen.js'); var MonsterBlockGen = require('./monsterblock.gen.js'); var ClassFeatureGen = require('./classfeature.gen.js'); var FullClassGen = require('./fullclass.gen.js'); - module.exports = [ { @@ -67,7 +66,12 @@ module.exports = [ { name : 'Spell', icon : 'fa-magic', - gen : SpellGen, + gen : MagicGen.spell, + }, + { + name : 'Spell List', + icon : 'fa-list', + gen : MagicGen.spellList, }, { name : 'Class Feature', @@ -171,5 +175,3 @@ module.exports = [ }, ] - - diff --git a/client/homebrew/editor/snippets/spell.gen.js b/client/homebrew/editor/snippets/spell.gen.js deleted file mode 100644 index c927683..0000000 --- a/client/homebrew/editor/snippets/spell.gen.js +++ /dev/null @@ -1,78 +0,0 @@ -var _ = require('lodash'); - -module.exports = function(){ - - - var spellNames = [ - "Astral Rite of Acne", - "Create Acne", - "Cursed Ramen Erruption", - "Dark Chant of the Dentists", - "Erruption of Immaturity", - "Flaming Disc of Inconvenience", - "Heal Bad Hygene", - "Heavenly Transfiguration of the Cream Devil", - "Hellish Cage of Mucus", - "Irritate Peanut Butter Fairy", - "Luminous Erruption of Tea", - "Mystic Spell of the Poser", - "Sorcerous Enchantment of the Chimneysweep", - "Steak Sauce Ray", - "Talk to Groupie", - "Astonishing Chant of Chocolate", - "Astounding Pasta Puddle", - "Ball of Annoyance", - "Cage of Yarn", - "Control Noodles Elemental", - "Create Nervousness", - "Cure Baldness", - "Cursed Ritual of Bad Hair", - "Dispell Piles in Dentist", - "Eliminate Florists", - "Illusionary Transfiguration of the Babysitter", - "Necromantic Armor of Salad Dressing", - "Occult Transfiguration of Foot Fetish", - "Protection from Mucus Giant", - "Tinsel Blast", - "Alchemical Evocation of the Goths", - "Call Fangirl", - "Divine Spell of Crossdressing", - "Dominate Ramen Giant", - "Eliminate Vindictiveness in Gym Teacher", - "Extra-Planar Spell of Irritation", - "Induce Whining in Babysitter", - "Invoke Complaining", - "Magical Enchantment of Arrogance", - "Occult Globe of Salad Dressing", - "Overwhelming Enchantment of the Chocolate Fairy", - "Sorcerous Dandruff Globe", - "Spiritual Invocation of the Costumers", - "Ultimate Rite of the Confetti Angel", - "Ultimate Ritual of Mouthwash", - ]; - - - var level = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th"]; - var spellSchools = ["abjuration", "conjuration", "divination", "enchantment", "evocation", "illusion", "necromancy", "transmutation"]; - - - var components = _.sampleSize(["V", "S", "M"], _.random(1,3)).join(', '); - if(components.indexOf("M") !== -1){ - components += " (" + _.sampleSize(['a small doll', 'a crushed button worth at least 1cp', 'discarded gum wrapper'], _.random(1,3)).join(', ') + ")" - } - - return [ - "#### " + _.sample(spellNames), - "*" + _.sample(level) + "-level " + _.sample(spellSchools) + "*", - "___", - "- **Casting Time:** 1 action", - "- **Range:** " + _.sample(["Self", "Touch", "30 feet", "60 feet"]), - "- **Components:** " + components, - "- **Duration:** " + _.sample(["Until dispelled", "1 round", "Instantaneous", "Concentration, up to 10 minutes", "1 hour"]), - "", - "A flame, equivalent in brightness to a torch, springs from from an object that you touch. ", - "The effect look like a regular flame, but it creates no heat and doesn't use oxygen. ", - "A *continual flame* can be covered or hidden but not smothered or quenched.", - "\n\n\n" - ].join('\n'); -} \ No newline at end of file diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index f1bc168..184cc67 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -1,56 +1,56 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var CreateRouter = require('pico-router').createRouter; - -var HomePage = require('./pages/homePage/homePage.jsx'); -var EditPage = require('./pages/editPage/editPage.jsx'); -var SharePage = require('./pages/sharePage/sharePage.jsx'); -var NewPage = require('./pages/newPage/newPage.jsx'); - -var Router; -var Homebrew = React.createClass({ - getDefaultProps: function() { - return { - url : "", - welcomeText : "", - changelog : "", - brew : { - title : '', - text : '', - shareId : null, - editId : null, - createdAt : null, - updatedAt : null, - } - }; - }, - componentWillMount: function() { - Router = CreateRouter({ - '/homebrew/edit/:id' : (args) => { - return - }, - - '/homebrew/share/:id' : (args) => { - return - }, - '/homebrew/changelog' : (args) => { - return - }, - '/homebrew/new' : (args) => { - return - }, - '/homebrew*' : , - }); - }, - render : function(){ - return( -
- -
- ); - } -}); - -module.exports = Homebrew; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +var CreateRouter = require('pico-router').createRouter; + +var HomePage = require('./pages/homePage/homePage.jsx'); +var EditPage = require('./pages/editPage/editPage.jsx'); +var SharePage = require('./pages/sharePage/sharePage.jsx'); +var NewPage = require('./pages/newPage/newPage.jsx'); + +var Router; +var Homebrew = React.createClass({ + getDefaultProps: function() { + return { + url : "", + welcomeText : "", + changelog : "", + brew : { + title : '', + text : '', + shareId : null, + editId : null, + createdAt : null, + updatedAt : null, + } + }; + }, + componentWillMount: function() { + Router = CreateRouter({ + '/homebrew/edit/:id' : (args) => { + return + }, + + '/homebrew/share/:id' : (args) => { + return + }, + '/homebrew/changelog' : (args) => { + return + }, + '/homebrew/new' : (args) => { + return + }, + '/homebrew*' : , + }); + }, + render : function(){ + return( +
+ +
+ ); + } +}); + +module.exports = Homebrew; diff --git a/client/homebrew/homebrew.less b/client/homebrew/homebrew.less index b8df9a4..00deebe 100644 --- a/client/homebrew/homebrew.less +++ b/client/homebrew/homebrew.less @@ -1,17 +1,17 @@ -@import 'naturalcrit/styles/core.less'; -.homebrew{ - height : 100%; - - //TODO: Consider making backgroudn color lighter - background-color : @steel; - .page{ - display : flex; - height : 100%; - flex-direction : column; - .content{ - position : relative; - height : calc(~"100% - 29px"); //Navbar height - flex : auto; - } - } +@import 'naturalcrit/styles/core.less'; +.homebrew{ + height : 100%; + + //TODO: Consider making backgroudn color lighter + background-color : @steel; + .page{ + display : flex; + height : 100%; + flex-direction : column; + .content{ + position : relative; + height : calc(~"100% - 29px"); //Navbar height + flex : auto; + } + } } \ No newline at end of file diff --git a/client/homebrew/navbar/editTitle.navitem.jsx b/client/homebrew/navbar/editTitle.navitem.jsx index 2533bd6..0698a57 100644 --- a/client/homebrew/navbar/editTitle.navitem.jsx +++ b/client/homebrew/navbar/editTitle.navitem.jsx @@ -1,33 +1,33 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); -var Nav = require('naturalcrit/nav/nav.jsx'); - -const MAX_TITLE_LENGTH = 50; - - -var EditTitle = React.createClass({ - getDefaultProps: function() { - return { - title : '', - onChange : function(){} - }; - }, - - handleChange : function(e){ - if(e.target.value.length > MAX_TITLE_LENGTH) return; - this.props.onChange(e.target.value); - }, - render : function(){ - return - - -
= MAX_TITLE_LENGTH})}> - {this.props.title.length}/{MAX_TITLE_LENGTH} -
-
- }, - -}); - +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); +var Nav = require('naturalcrit/nav/nav.jsx'); + +const MAX_TITLE_LENGTH = 50; + + +var EditTitle = React.createClass({ + getDefaultProps: function() { + return { + title : '', + onChange : function(){} + }; + }, + + handleChange : function(e){ + if(e.target.value.length > MAX_TITLE_LENGTH) return; + this.props.onChange(e.target.value); + }, + render : function(){ + return + + +
= MAX_TITLE_LENGTH})}> + {this.props.title.length}/{MAX_TITLE_LENGTH} +
+
+ }, + +}); + module.exports = EditTitle; \ No newline at end of file diff --git a/client/homebrew/navbar/issue.navitem.jsx b/client/homebrew/navbar/issue.navitem.jsx index ffa235a..12716d2 100644 --- a/client/homebrew/navbar/issue.navitem.jsx +++ b/client/homebrew/navbar/issue.navitem.jsx @@ -1,8 +1,8 @@ -var React = require('react'); -var Nav = require('naturalcrit/nav/nav.jsx'); - -module.exports = function(props){ - return - report issue - +var React = require('react'); +var Nav = require('naturalcrit/nav/nav.jsx'); + +module.exports = function(props){ + return + report issue + }; \ No newline at end of file diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index f643fe1..e952fd2 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -11,7 +11,7 @@ var Navbar = React.createClass({
The Homebrewery
- v2.0.6 + v2.1.0 {this.props.children} diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less index d313e9c..f4a3f31 100644 --- a/client/homebrew/navbar/navbar.less +++ b/client/homebrew/navbar/navbar.less @@ -1,58 +1,95 @@ - -.homebrew nav{ - .homebrewLogo{ - .animate(color); - font-family : CodeBold; - font-size : 12px; - color : white; - div{ - margin-top : 2px; - margin-bottom : -2px; - } - &:hover{ - color : @blue; - } - } - .editTitle.navItem{ - padding : 2px 12px; - input{ - margin : 0; - padding : 2px; - width : 250px; - background-color : #444; - font-family : 'Open Sans', sans-serif; - font-size : 12px; - font-weight : 800; - color : white; - text-align : center; - border : 1px solid @blue; - outline : none; - } - .charCount{ - display : inline-block; - vertical-align : bottom; - margin-left : 8px; - text-align : right; - color : #666; - &.max{ - color : @red; - } - } - } - .brewTitle.navItem{ - font-size : 12px; - font-weight : 800; - color : white; - text-align : center; - text-transform: initial; - } - .patreon.navItem{ - i{ - .animate(color); - &:hover{ - color : @red; - } - } - } - + +.homebrew nav{ + .homebrewLogo{ + .animate(color); + font-family : CodeBold; + font-size : 12px; + color : white; + div{ + margin-top : 2px; + margin-bottom : -2px; + } + &:hover{ + color : @blue; + } + } + .editTitle.navItem{ + padding : 2px 12px; + input{ + width : 250px; + margin : 0; + padding : 2px; + background-color : #444; + font-family : 'Open Sans', sans-serif; + font-size : 12px; + font-weight : 800; + color : white; + text-align : center; + border : 1px solid @blue; + outline : none; + } + .charCount{ + display : inline-block; + vertical-align : bottom; + margin-left : 8px; + color : #666; + text-align : right; + &.max{ + color : @red; + } + } + } + .brewTitle.navItem{ + font-size : 12px; + font-weight : 800; + color : white; + text-align : center; + text-transform : initial; + } + .patreon.navItem{ + i{ + .animate(color); + &:hover{ + color : @red; + } + } + } + .recent.navItem{ + position : relative; + .dropdown{ + position : absolute; + top : 28px; + left : 0px; + z-index : 10000; + width : 100%; + .item{ + .animate(background-color); + position : relative; + display : block; + box-sizing : border-box;; + padding : 13px 5px; + background-color : #333; + color : white; + text-decoration : none; + border-top : 1px solid #888; + &:hover{ + background-color : @blue; + } + .title{ + display : inline-block; + overflow : hidden; + width : 100%; + text-overflow : ellipsis; + white-space : nowrap; + } + .time{ + position : absolute; + right : 2px; + bottom : 2px; + font-size : 0.7em; + color : #888; + } + } + } + } } \ No newline at end of file diff --git a/client/homebrew/navbar/patreon.navitem.jsx b/client/homebrew/navbar/patreon.navitem.jsx index cde3414..a7a53d3 100644 --- a/client/homebrew/navbar/patreon.navitem.jsx +++ b/client/homebrew/navbar/patreon.navitem.jsx @@ -1,13 +1,13 @@ -var React = require('react'); -var Nav = require('naturalcrit/nav/nav.jsx'); - -module.exports = function(props){ - return - help out - +var React = require('react'); +var Nav = require('naturalcrit/nav/nav.jsx'); + +module.exports = function(props){ + return + help out + }; \ No newline at end of file diff --git a/client/homebrew/navbar/print.navitem.jsx b/client/homebrew/navbar/print.navitem.jsx index 19ddc0b..1b1796c 100644 --- a/client/homebrew/navbar/print.navitem.jsx +++ b/client/homebrew/navbar/print.navitem.jsx @@ -1,8 +1,8 @@ -var React = require('react'); -var Nav = require('naturalcrit/nav/nav.jsx'); - -module.exports = function(props){ - return - print - +var React = require('react'); +var Nav = require('naturalcrit/nav/nav.jsx'); + +module.exports = function(props){ + return + print + }; \ No newline at end of file diff --git a/client/homebrew/navbar/recent.navitem.jsx b/client/homebrew/navbar/recent.navitem.jsx new file mode 100644 index 0000000..703c029 --- /dev/null +++ b/client/homebrew/navbar/recent.navitem.jsx @@ -0,0 +1,118 @@ +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); +var Moment = require('moment'); + +var Nav = require('naturalcrit/nav/nav.jsx'); + +var BaseItem = React.createClass({ + getDefaultProps: function() { + return { + storageKey : '', + text : '', + currentBrew:{ + title : '', + id : '', + url : '' + } + }; + }, + getInitialState: function() { + return { + showDropdown: false, + brews : [] + }; + }, + + componentDidMount: function() { + var brews = JSON.parse(localStorage.getItem(this.props.storageKey) || '[]'); + + brews = _.filter(brews, (brew)=>{ + return brew.id !== this.props.currentBrew.id; + }); + brews.unshift({ + id : this.props.currentBrew.id, + url : this.props.currentBrew.url, + title : this.props.currentBrew.title, + ts : Date.now() + }); + brews = _.slice(brews, 0, 8); + localStorage.setItem(this.props.storageKey, JSON.stringify(brews)); + this.setState({ + brews : brews + }); + }, + + handleDropdown : function(show){ + this.setState({ + showDropdown : show + }) + }, + + renderDropdown : function(){ + if(!this.state.showDropdown) return null; + + var items = _.map(this.state.brews, (brew)=>{ + return + {brew.title} + {Moment(brew.ts).fromNow()} + + }); + + return
{items}
+ }, + + render : function(){ + return + {this.props.text} + {this.renderDropdown()} + + }, + +}); + + + +module.exports = { + viewed : React.createClass({ + getDefaultProps: function() { + return { + brew : { + title : '', + shareId : '' + } + }; + }, + render : function(){ + return + }, + }), + + edited : React.createClass({ + getDefaultProps: function() { + return { + brew : { + title : '', + editId : '' + } + }; + }, + render : function(){ + return + }, + }), +} \ No newline at end of file diff --git a/client/homebrew/navbar/reddit.navitem.jsx b/client/homebrew/navbar/reddit.navitem.jsx index b78ca83..fe7e695 100644 --- a/client/homebrew/navbar/reddit.navitem.jsx +++ b/client/homebrew/navbar/reddit.navitem.jsx @@ -1,51 +1,51 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -//var striptags = require('striptags'); - -var Nav = require('naturalcrit/nav/nav.jsx'); - -const MAX_URL_SIZE = 2083; -const MAIN_URL = "https://www.reddit.com/r/UnearthedArcana/submit?selftext=true" - - -var RedditShare = React.createClass({ - getDefaultProps: function() { - return { - brew : { - title : '', - sharedId : '', - text : '' - } - }; - }, - - getText : function(){ - - }, - - - handleClick : function(){ - var url = [ - MAIN_URL, - 'title=' + encodeURIComponent(this.props.brew.title ? this.props.brew.title : 'Check out my brew!'), - - 'text=' + encodeURIComponent(this.props.brew.text) - - - ].join('&'); - - window.open(url, '_blank'); - }, - - - render : function(){ - return - share on reddit - - }, - -}); - +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +//var striptags = require('striptags'); + +var Nav = require('naturalcrit/nav/nav.jsx'); + +const MAX_URL_SIZE = 2083; +const MAIN_URL = "https://www.reddit.com/r/UnearthedArcana/submit?selftext=true" + + +var RedditShare = React.createClass({ + getDefaultProps: function() { + return { + brew : { + title : '', + sharedId : '', + text : '' + } + }; + }, + + getText : function(){ + + }, + + + handleClick : function(){ + var url = [ + MAIN_URL, + 'title=' + encodeURIComponent(this.props.brew.title ? this.props.brew.title : 'Check out my brew!'), + + 'text=' + encodeURIComponent(this.props.brew.text) + + + ].join('&'); + + window.open(url, '_blank'); + }, + + + render : function(){ + return + share on reddit + + }, + +}); + module.exports = RedditShare; \ No newline at end of file diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 81f52bc..ef81126 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -1,198 +1,205 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); -var request = require("superagent"); - -var Nav = require('naturalcrit/nav/nav.jsx'); -var Navbar = require('../../navbar/navbar.jsx'); - -var EditTitle = require('../../navbar/editTitle.navitem.jsx'); -var ReportIssue = require('../../navbar/issue.navitem.jsx'); -var PrintLink = require('../../navbar/print.navitem.jsx'); - - -var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); -var Editor = require('../../editor/editor.jsx'); -var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); - - - -const SAVE_TIMEOUT = 3000; - - - -var EditPage = React.createClass({ - getDefaultProps: function() { - return { - id : null, - brew : { - title : '', - text : '', - shareId : null, - editId : null, - createdAt : null, - updatedAt : null, - } - }; - }, - - getInitialState: function() { - return { - title : this.props.brew.title, - text: this.props.brew.text, - isSaving : false, - isPending : false, - errors : null, - lastUpdated : this.props.brew.updatedAt - }; - }, - savedBrew : null, - - componentDidMount: function(){ - this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT); - window.onbeforeunload = ()=>{ - if(this.state.isSaving || this.state.isPending){ - return 'You have unsaved changes!'; - } - } - }, - componentWillUnmount: function() { - window.onbeforeunload = function(){}; - }, - - handleSplitMove : function(){ - this.refs.editor.update(); - }, - - handleTitleChange : function(title){ - this.setState({ - title : title, - isPending : true - }); - - (this.hasChanges() ? this.debounceSave() : this.debounceSave.cancel()); - }, - - handleTextChange : function(text){ - this.setState({ - text : text, - isPending : true - }); - - (this.hasChanges() ? this.debounceSave() : this.debounceSave.cancel()); - }, - - handleDelete : function(){ - if(!confirm("are you sure you want to delete this brew?")) return; - if(!confirm("are you REALLY sure? You will not be able to recover it")) return; - - request.get('/homebrew/api/remove/' + this.props.brew.editId) - .send() - .end(function(err, res){ - window.location.href = '/homebrew'; - }); - }, - - hasChanges : function(){ - if(this.savedBrew){ - if(this.state.text !== this.savedBrew.text) return true; - if(this.state.title !== this.savedBrew.title) return true; - }else{ - if(this.state.text !== this.props.brew.text) return true; - if(this.state.title !== this.props.brew.title) return true; - } - return false; - }, - - save : function(){ - this.debounceSave.cancel(); - this.setState({ - isSaving : true, - errors : null - }); - - request - .put('/homebrew/api/update/' + this.props.brew.editId) - .send({ - text : this.state.text, - title : this.state.title - }) - .end((err, res) => { - if(err){ - this.setState({ - errors : err, - }) - }else{ - this.savedBrew = res.body; - this.setState({ - isPending : false, - isSaving : false, - lastUpdated : res.body.updatedAt - }) - } - }) - }, - - renderSaveButton : function(){ - if(this.state.errors){ - var errMsg = ''; - try{ - errMsg += this.state.errors.toString() + '\n\n'; - errMsg += '```\n' + JSON.stringify(this.state.errors.response.error, null, ' ') + '\n```'; - }catch(e){} - - - return - Oops! -
- Looks like there was a problem saving.
- Report the issue - here - . -
-
- } - - if(this.state.isSaving){ - return saving... - } - if(!this.state.isPending && !this.state.isSaving){ - return saved. - } - if(this.state.isPending && this.hasChanges()){ - return Save Now - } - }, - renderNavbar : function(){ - return - - - - - {this.renderSaveButton()} - - Share - - - - Delete - - - - }, - - render : function(){ - return
- {this.renderNavbar()} - -
- - - - -
-
- } -}); - -module.exports = EditPage; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); +var request = require("superagent"); + +var Nav = require('naturalcrit/nav/nav.jsx'); +var Navbar = require('../../navbar/navbar.jsx'); + +var EditTitle = require('../../navbar/editTitle.navitem.jsx'); +var ReportIssue = require('../../navbar/issue.navitem.jsx'); +var PrintLink = require('../../navbar/print.navitem.jsx'); +var RecentlyEdited = require('../../navbar/recent.navitem.jsx').edited; + + +var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); +var Editor = require('../../editor/editor.jsx'); +var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); + +var HijackPrint = require('../hijackPrint.js'); + + + +const SAVE_TIMEOUT = 3000; + + + +var EditPage = React.createClass({ + getDefaultProps: function() { + return { + id : null, + brew : { + title : '', + text : '', + shareId : null, + editId : null, + createdAt : null, + updatedAt : null, + } + }; + }, + + getInitialState: function() { + return { + title : this.props.brew.title, + text: this.props.brew.text, + isSaving : false, + isPending : false, + errors : null, + lastUpdated : this.props.brew.updatedAt + }; + }, + savedBrew : null, + + componentDidMount: function(){ + this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT); + window.onbeforeunload = ()=>{ + if(this.state.isSaving || this.state.isPending){ + return 'You have unsaved changes!'; + } + }; + + document.onkeydown = HijackPrint(this.props.brew.shareId); + }, + componentWillUnmount: function() { + window.onbeforeunload = function(){}; + document.onkeydown = function(){}; + }, + + handleSplitMove : function(){ + this.refs.editor.update(); + }, + + handleTitleChange : function(title){ + this.setState({ + title : title, + isPending : true + }); + + (this.hasChanges() ? this.debounceSave() : this.debounceSave.cancel()); + }, + + handleTextChange : function(text){ + this.setState({ + text : text, + isPending : true + }); + + (this.hasChanges() ? this.debounceSave() : this.debounceSave.cancel()); + }, + + handleDelete : function(){ + if(!confirm("are you sure you want to delete this brew?")) return; + if(!confirm("are you REALLY sure? You will not be able to recover it")) return; + + request.get('/homebrew/api/remove/' + this.props.brew.editId) + .send() + .end(function(err, res){ + window.location.href = '/homebrew'; + }); + }, + + hasChanges : function(){ + if(this.savedBrew){ + if(this.state.text !== this.savedBrew.text) return true; + if(this.state.title !== this.savedBrew.title) return true; + }else{ + if(this.state.text !== this.props.brew.text) return true; + if(this.state.title !== this.props.brew.title) return true; + } + return false; + }, + + save : function(){ + this.debounceSave.cancel(); + this.setState({ + isSaving : true, + errors : null + }); + + request + .put('/homebrew/api/update/' + this.props.brew.editId) + .send({ + text : this.state.text, + title : this.state.title + }) + .end((err, res) => { + if(err){ + this.setState({ + errors : err, + }) + }else{ + this.savedBrew = res.body; + this.setState({ + isPending : false, + isSaving : false, + lastUpdated : res.body.updatedAt + }) + } + }) + }, + + renderSaveButton : function(){ + if(this.state.errors){ + var errMsg = ''; + try{ + errMsg += this.state.errors.toString() + '\n\n'; + errMsg += '```\n' + JSON.stringify(this.state.errors.response.error, null, ' ') + '\n```'; + }catch(e){} + + + return + Oops! +
+ Looks like there was a problem saving.
+ Report the issue + here + . +
+
+ } + + if(this.state.isSaving){ + return saving... + } + if(!this.state.isPending && !this.state.isSaving){ + return saved. + } + if(this.state.isPending && this.hasChanges()){ + return Save Now + } + }, + renderNavbar : function(){ + return + + + + + {this.renderSaveButton()} + + + Share + + + + Delete + + + + }, + + render : function(){ + return
+ {this.renderNavbar()} + +
+ + + + +
+
+ } +}); + +module.exports = EditPage; diff --git a/client/homebrew/pages/editPage/editPage.less b/client/homebrew/pages/editPage/editPage.less index 029d2ba..775013c 100644 --- a/client/homebrew/pages/editPage/editPage.less +++ b/client/homebrew/pages/editPage/editPage.less @@ -1,27 +1,27 @@ - -.editPage{ - .navItem.save{ - width : 75px; - text-align : center; - &.saved{ - cursor : initial; - color : #666; - } - &.error{ - position : relative; - background-color : @red; - .errorContainer{ - position : absolute; - top : 29px; - left : -20px; - z-index : 1000; - width : 120px; - padding : 8px; - background-color : #333; - a{ - color : @teal; - } - } - } - } + +.editPage{ + .navItem.save{ + width : 75px; + text-align : center; + &.saved{ + cursor : initial; + color : #666; + } + &.error{ + position : relative; + background-color : @red; + .errorContainer{ + position : absolute; + top : 29px; + left : -20px; + z-index : 1000; + width : 120px; + padding : 8px; + background-color : #333; + a{ + color : @teal; + } + } + } + } } \ No newline at end of file diff --git a/client/homebrew/pages/hijackPrint.js b/client/homebrew/pages/hijackPrint.js new file mode 100644 index 0000000..144a1fc --- /dev/null +++ b/client/homebrew/pages/hijackPrint.js @@ -0,0 +1,10 @@ +module.exports = function(shareId){ + return function(event){ + event = event || window.event; + if((event.ctrlKey || event.metaKey) && event.keyCode == 80){ + var win = window.open(`/homebrew/print/${shareId}?dialog=true`, '_blank'); + win.focus(); + event.preventDefault(); + } + }; +}; \ No newline at end of file diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index c5cc591..0e95c50 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -1,70 +1,87 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var Nav = require('naturalcrit/nav/nav.jsx'); -var Navbar = require('../../navbar/navbar.jsx'); -var PatreonNavItem = require('../../navbar/patreon.navitem.jsx'); - - -var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); -var Editor = require('../../editor/editor.jsx'); -var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); - - - -var HomePage = React.createClass({ - getDefaultProps: function() { - return { - welcomeText : "" - }; - }, - getInitialState: function() { - return { - text: this.props.welcomeText - }; - }, - handleSplitMove : function(){ - this.refs.editor.update(); - }, - handleTextChange : function(text){ - this.setState({ - text : text - }); - }, - renderNavbar : function(){ - return - - - - report issue - - - Changelog - - - New Brew - - - - }, - - render : function(){ - return
- {this.renderNavbar()} - -
- - - - -
- - - Create your own - -
- } -}); - -module.exports = HomePage; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); +var request = require("superagent"); + +var Nav = require('naturalcrit/nav/nav.jsx'); +var Navbar = require('../../navbar/navbar.jsx'); +var PatreonNavItem = require('../../navbar/patreon.navitem.jsx'); + + +var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); +var Editor = require('../../editor/editor.jsx'); +var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); + + + +var HomePage = React.createClass({ + getDefaultProps: function() { + return { + welcomeText : "" + }; + }, + getInitialState: function() { + return { + text: this.props.welcomeText + }; + }, + handleSave : function(){ + request.post('/homebrew/api') + .send({ + title : 'Change This', + text : this.state.text + }) + .end((err, res)=>{ + if(err) return; + var brew = res.body; + window.location = '/homebrew/edit/' + brew.editId; + }); + }, + handleSplitMove : function(){ + this.refs.editor.update(); + }, + handleTextChange : function(text){ + this.setState({ + text : text + }); + }, + renderNavbar : function(){ + return + + + + report issue + + + Changelog + + + New Brew + + + + }, + + render : function(){ + return
+ {this.renderNavbar()} + +
+ + + + +
+ +
+ Save current +
+ + + Create your own + +
+ } +}); + +module.exports = HomePage; diff --git a/client/homebrew/pages/homePage/homePage.less b/client/homebrew/pages/homePage/homePage.less index 6f49934..37b4122 100644 --- a/client/homebrew/pages/homePage/homePage.less +++ b/client/homebrew/pages/homePage/homePage.less @@ -1,21 +1,43 @@ - -.homePage{ - position : relative; - a.floatingNewButton{ - .animate(background-color); - position : absolute; - display : block; - right : 70px; - bottom : 70px; - z-index : 100; - padding : 1em; - background-color : @orange; - font-size : 1.5em; - color : white; - text-decoration : none; - box-shadow : 3px 3px 15px black; - &:hover{ - background-color : darken(@orange, 20%); - } - } +.homePage{ + position : relative; + a.floatingNewButton{ + .animate(background-color); + position : absolute; + display : block; + right : 70px; + bottom : 70px; + z-index : 100; + z-index : 5001; + padding : 1em; + background-color : @orange; + font-size : 1.5em; + color : white; + text-decoration : none; + box-shadow : 3px 3px 15px black; + &:hover{ + background-color : darken(@orange, 20%); + } + } + .floatingSaveButton{ + .animateAll(); + position : absolute; + display : block; + right : 200px; + bottom : 90px; + z-index : 100; + z-index : 5000; + padding : 0.8em; + cursor : pointer; + background-color : @blue; + font-size : 0.8em; + color : white; + text-decoration : none; + box-shadow : 3px 3px 15px black; + &:hover{ + background-color : darken(@blue, 20%); + } + &.show{ + right : 350px; + } + } } \ No newline at end of file diff --git a/client/homebrew/pages/homePage/welcome_msg.txt b/client/homebrew/pages/homePage/welcome_msg.txt index e08c96c..99b6717 100644 --- a/client/homebrew/pages/homePage/welcome_msg.txt +++ b/client/homebrew/pages/homePage/welcome_msg.txt @@ -8,17 +8,6 @@ The Homebrewery makes the creation and sharing of authentic looking Fifth-Editio - -#### Features -* Monster Stat Blocks -* Full class tables -* Notes and Tables -* Images -* Page numbering and footers -* Vertical spacing, column breaks, and multiple pages - - - ### Editing and Sharing When you create your own homebrew you will be given a *edit url* and a *share url*. Any changes you make will be automatically saved to the database within a few seconds. Anyone with the edit url will be able to make edits to your homebrew. So be careful about who you share it with. @@ -33,20 +22,9 @@ This tool will **always** be free, never have ads, and I will never offer any "p Have an idea of how to make The Homebrewery better? Or did you find something that wasn't quite right? Head [here](https://github.com/stolksdorf/NaturalCrit/issues/new) and let me know!. -``` -``` - -## New Things in v2.0.0! -What's new in the latest update? Check out the full changelog [here](/homebrew/changelog) - -* **A whole new look** The site has been re-built from the ground up! -* **Better editor and Split Pane** Syntax highlighting will make writing your brews even easier, and now you can customize how large your editor is. -* **More reliable rendering** Lots of work has been put into making the rendering more reliable, not just for web, but also for PDFs -* **PDF Printing on Chrome** You don't need to use Chrome Canary anymore! -* ** Performance Improvements** The site should load faster, save faster, and render large brews *much* faster. -* **Patreon page** If you like this tool and want to show some thanks you can [head here](https://www.patreon.com/stolksdorf). - >##### PDF Exporting +> PDF Printing works best in Chrome. If you are having quality/consistency issues, try using Chrome to print instead. +> > After clicking the "Print" item in the navbar a new page will open and a print dialog will pop-up. > * Set the **Destination** to "Save as PDF" > * Set **Paper Size** to "Letter" @@ -54,11 +32,32 @@ What's new in the latest update? Check out the full changelog [here](/homebrew/c > * In **Options** make sure "Background Images" is selected. > * Hit print and enjoy! You're done! > -> PDF Printing works best in Chrome. If you are having quality/consistency issues, try using Chrome to print instead. -> > If you want to save ink or have a monochrome printer, add the **Ink Friendly** snippet to your brew before you print +``` +``` + +## New Things in v2.1.0! +What's new in the latest update? Check out the full changelog [here](/homebrew/changelog) + +* **Spell Lists** Tweaking the Markdown lexer and parser, I can now do nested Markdown within HTML blocks. Which means the available syntax I can use has vastly increased. Spell Lists are just the first of many new elements. +* **Recently Viewed/Edited** The Homebrewery now remembers which brews you've been editing and viewing. Check the navbar to quickly jump around to these. +* **Print Command Capturing** Pressing ctrl+p/cmd+p on any edit or share page will now jump you straight to the print page. Much more intutive. + + +## V2 Overhaul +A lot of has been put into version 2 of The Homebrewery. Here are the highlights: + +* **A whole new look** The site has been re-built from the ground up! +* **Better editor and split pane** Syntax highlighting will make writing your brews even easier, and now you can customize how large your editor is. +* **More reliable rendering** Lots of work has been put into making the rendering more reliable, not just for web, but also for PDFs +* **PDF Printing on Chrome** You don't need to use Chrome Canary anymore! +* ** Performance Improvements** The site should load faster, save faster, and render large brews *much* faster. +* **Patreon page** If you like this tool and want to show some thanks you can [head here](https://www.patreon.com/stolksdorf). + + + diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 85e2e22..62eda48 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -1,130 +1,130 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); -var request = require("superagent"); - -var Nav = require('naturalcrit/nav/nav.jsx'); -var Navbar = require('../../navbar/navbar.jsx'); -var EditTitle = require('../../navbar/editTitle.navitem.jsx'); - - -var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); -var Editor = require('../../editor/editor.jsx'); -var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); - - -const KEY = 'naturalCrit-homebrew-new'; - -var NewPage = React.createClass({ - getInitialState: function() { - return { - title : 'My Awesome Brew v99', - text: '', - isSaving : false - }; - }, - - - componentDidMount: function() { - var storage = localStorage.getItem(KEY); - if(storage){ - this.setState({ - text : storage - }) - } - window.onbeforeunload = (e)=>{ - if(this.state.text == '') return; - return "Your homebrew isn't saved. Are you sure you want to leave?"; - }; - }, - - - componentWillUnmount: function() { - window.onbeforeunload = function(){}; - }, - - handleSplitMove : function(){ - this.refs.editor.update(); - }, - - handleTitleChange : function(title){ - this.setState({ - title : title - }); - }, - - handleTextChange : function(text){ - this.setState({ - text : text - }); - localStorage.setItem(KEY, text); - }, - - handleSave : function(){ - this.setState({ - isSaving : true - }); - request.post('/homebrew/api') - .send({ - title : this.state.title, - text : this.state.text - }) - .end((err, res)=>{ - - if(err){ - this.setState({ - isSaving : false - }); - return; - } - window.onbeforeunload = function(){}; - var brew = res.body; - localStorage.removeItem(KEY); - window.location = '/homebrew/edit/' + brew.editId; - }) - }, - - renderSaveButton : function(){ - if(this.state.isSaving){ - return - save... - - }else{ - return - save - - } - }, - - - renderNavbar : function(){ - return - - - - - - {this.renderSaveButton()} - - report issue - - - - }, - - render : function(){ - return
- {this.renderNavbar()} - - -
- - - - -
-
- } -}); - -module.exports = NewPage; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); +var request = require("superagent"); + +var Nav = require('naturalcrit/nav/nav.jsx'); +var Navbar = require('../../navbar/navbar.jsx'); +var EditTitle = require('../../navbar/editTitle.navitem.jsx'); + + +var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); +var Editor = require('../../editor/editor.jsx'); +var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); + + +const KEY = 'naturalCrit-homebrew-new'; + +var NewPage = React.createClass({ + getInitialState: function() { + return { + title : 'My Awesome Brew v99', + text: '', + isSaving : false + }; + }, + + + componentDidMount: function() { + var storage = localStorage.getItem(KEY); + if(storage){ + this.setState({ + text : storage + }) + } + window.onbeforeunload = (e)=>{ + if(this.state.text == '') return; + return "Your homebrew isn't saved. Are you sure you want to leave?"; + }; + }, + + + componentWillUnmount: function() { + window.onbeforeunload = function(){}; + }, + + handleSplitMove : function(){ + this.refs.editor.update(); + }, + + handleTitleChange : function(title){ + this.setState({ + title : title + }); + }, + + handleTextChange : function(text){ + this.setState({ + text : text + }); + localStorage.setItem(KEY, text); + }, + + handleSave : function(){ + this.setState({ + isSaving : true + }); + request.post('/homebrew/api') + .send({ + title : this.state.title, + text : this.state.text + }) + .end((err, res)=>{ + + if(err){ + this.setState({ + isSaving : false + }); + return; + } + window.onbeforeunload = function(){}; + var brew = res.body; + localStorage.removeItem(KEY); + window.location = '/homebrew/edit/' + brew.editId; + }) + }, + + renderSaveButton : function(){ + if(this.state.isSaving){ + return + save... + + }else{ + return + save + + } + }, + + + renderNavbar : function(){ + return + + + + + + {this.renderSaveButton()} + + report issue + + + + }, + + render : function(){ + return
+ {this.renderNavbar()} + + +
+ + + + +
+
+ } +}); + +module.exports = NewPage; diff --git a/client/homebrew/pages/newPage/newPage.less b/client/homebrew/pages/newPage/newPage.less index 557cc6d..8cd21b2 100644 --- a/client/homebrew/pages/newPage/newPage.less +++ b/client/homebrew/pages/newPage/newPage.less @@ -1,10 +1,10 @@ -.newPage{ - - .saveButton{ - background-color: @orange; - &:hover{ - background-color: @green; - } - } - +.newPage{ + + .saveButton{ + background-color: @orange; + &:hover{ + background-color: @green; + } + } + } \ No newline at end of file diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index 7252c52..f1333b7 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -1,48 +1,58 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var Nav = require('naturalcrit/nav/nav.jsx'); -var Navbar = require('../../navbar/navbar.jsx'); - -var PrintLink = require('../../navbar/print.navitem.jsx'); - -var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); - -var SharePage = React.createClass({ - getDefaultProps: function() { - return { - brew : { - title : '', - text : '', - shareId : null, - createdAt : null, - updatedAt : null, - views : 0 - } - }; - }, - - render : function(){ - return
- - - {this.props.brew.title} - - - - - - source - - - - -
- -
-
- } -}); - -module.exports = SharePage; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +var Nav = require('naturalcrit/nav/nav.jsx'); +var Navbar = require('../../navbar/navbar.jsx'); +var PrintLink = require('../../navbar/print.navitem.jsx'); +var RecentlyViewed = require('../../navbar/recent.navitem.jsx').viewed; + +var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); + +var HijackPrint = require('../hijackPrint.js'); + +var SharePage = React.createClass({ + getDefaultProps: function() { + return { + brew : { + title : '', + text : '', + shareId : null, + createdAt : null, + updatedAt : null, + views : 0 + } + }; + }, + + componentDidMount: function() { + document.onkeydown = HijackPrint(this.props.brew.shareId); + }, + componentWillUnmount: function() { + document.onkeydown = function(){}; + }, + + render : function(){ + return
+ + + {this.props.brew.title} + + + + + + + source + + + + +
+ +
+
+ } +}); + +module.exports = SharePage; diff --git a/client/homebrew/pages/sharePage/sharePage.less b/client/homebrew/pages/sharePage/sharePage.less index fa0fbf9..6c798f2 100644 --- a/client/homebrew/pages/sharePage/sharePage.less +++ b/client/homebrew/pages/sharePage/sharePage.less @@ -1,3 +1,3 @@ -.sharePage{ - +.sharePage{ + } \ No newline at end of file diff --git a/client/homebrew/phbStyle/phb.assets.less b/client/homebrew/phbStyle/phb.assets.less index 2c18966..2d82bc7 100644 --- a/client/homebrew/phbStyle/phb.assets.less +++ b/client/homebrew/phbStyle/phb.assets.less @@ -1,6 +1,6 @@ -@footerAccentImage : url(data:image/png;base64,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); -@frameBorderImage: url(data:image/png;base64,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); -@backgroundImage: url(data:image/jpeg;base64,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); -@redTriangleImage: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAeCAYAAACR82geAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4zjOaXUAAAAt5JREFUaEPtWTtoVEEUHf8iaEjMZt/ME6Jx3X1zlwgavyAICoL4aRWFIFYWAUURLZQo+GkUTGHc92Y2q2AKI0oKLbQIKRS0UPxCilgEFIKCTYIfyBrPi4NImGKJyWZ3Xw4cpth9b84c7ty59w3TaXdAS3FXEz8VkLtNp5YuZjNgoTGj/1KRGNEkXoEqkM4RmLamlbG55u/RwXhj7BRDMKw3kPyKkmKflk69ebxyYTeiAJL4CLO6AynOaI/v8Buqq8wrKwPWRU+Ef7bgOy3dm4p4i0456/wmNs9MU36wLnKySO4wzHqCyLoGsw4EyfiKUcZmmalLG9YFTSVJDMKkB0ryc1np7OxsrKo2UkoLVvHFJLl5GNWHpH5bS35UUXxDWyKxwMibPljFTjdJfMP2ewbDrgee06xWxhIoGWYbycWBVViJMQvCqM/go4D4Be25u/wkr4X8qctXNiFlwjwiqx9RdQfj8ZznbvI5X2SW9f+wTFi+JPEdfIHaysd4SKdEqnXrBKt26wQVQrMFv+IE7MlKcakjLfbkKOYUVDLYXljhzOMEHEBU3UMfeDJLfIu1cbY8GDmqtPiJyHoDaph1OJOqa5wxBgyNCUi8DY3pgDEqWbc6csaotPsLUTEAE+7rdES30t/kS7wHJlzGSbU349Xy6CVfEj9gwksk1yDKxzV6LPEBlXAXxhPaE5v9pogVeOGWQAR8AR/DhIuBJ3ZnE04M8iPWEqCJRIJ8jmhohynNimKJLsbmGMnFgVVYMTn22cHtgxGdgcePZWR8Y66+fqGRN32wip1KkhgEHwaSnw8/VClaVmOklBas4ieL5A7jlHiK4qlNEz/YvqquIXqfNkmMoIJ8j+R4C2a0+ElnfSux+Waa8oN1kQUwS+ITzOhWnjir05G9PhFDMKEX7ftV1Av7b6Tiy83jlYvxJmArhPdDrzHq8Io24/G1Ub2iHbvURzN1GuP2tkTNEvNThMHYbySiA8IawOrpAAAAAElFTkSuQmCC); -@monsterBorderImage: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAA8CAMAAADG+c2+AAAACVBMVEX///8AAADmmihtJc8lAAAAAXRSTlMAQObYZgAAACxJREFUeAHt2EEBACAAwkCwf2hL8NK7AAuwdCw9U5Og4FgeAAAAAK7IBxPjAl3qBs+hfAnLAAAAAElFTkSuQmCC); +@footerAccentImage : url(data:image/png;base64,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); +@frameBorderImage: url(data:image/png;base64,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); +@backgroundImage: url(data:image/jpeg;base64,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); +@redTriangleImage: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAeCAYAAACR82geAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4zjOaXUAAAAt5JREFUaEPtWTtoVEEUHf8iaEjMZt/ME6Jx3X1zlwgavyAICoL4aRWFIFYWAUURLZQo+GkUTGHc92Y2q2AKI0oKLbQIKRS0UPxCilgEFIKCTYIfyBrPi4NImGKJyWZ3Xw4cpth9b84c7ty59w3TaXdAS3FXEz8VkLtNp5YuZjNgoTGj/1KRGNEkXoEqkM4RmLamlbG55u/RwXhj7BRDMKw3kPyKkmKflk69ebxyYTeiAJL4CLO6AynOaI/v8Buqq8wrKwPWRU+Ef7bgOy3dm4p4i0456/wmNs9MU36wLnKySO4wzHqCyLoGsw4EyfiKUcZmmalLG9YFTSVJDMKkB0ryc1np7OxsrKo2UkoLVvHFJLl5GNWHpH5bS35UUXxDWyKxwMibPljFTjdJfMP2ewbDrgee06xWxhIoGWYbycWBVViJMQvCqM/go4D4Be25u/wkr4X8qctXNiFlwjwiqx9RdQfj8ZznbvI5X2SW9f+wTFi+JPEdfIHaysd4SKdEqnXrBKt26wQVQrMFv+IE7MlKcakjLfbkKOYUVDLYXljhzOMEHEBU3UMfeDJLfIu1cbY8GDmqtPiJyHoDaph1OJOqa5wxBgyNCUi8DY3pgDEqWbc6csaotPsLUTEAE+7rdES30t/kS7wHJlzGSbU349Xy6CVfEj9gwksk1yDKxzV6LPEBlXAXxhPaE5v9pogVeOGWQAR8AR/DhIuBJ3ZnE04M8iPWEqCJRIJ8jmhohynNimKJLsbmGMnFgVVYMTn22cHtgxGdgcePZWR8Y66+fqGRN32wip1KkhgEHwaSnw8/VClaVmOklBas4ieL5A7jlHiK4qlNEz/YvqquIXqfNkmMoIJ8j+R4C2a0+ElnfSux+Waa8oN1kQUwS+ITzOhWnjir05G9PhFDMKEX7ftV1Av7b6Tiy83jlYvxJmArhPdDrzHq8Io24/G1Ub2iHbvURzN1GuP2tkTNEvNThMHYbySiA8IawOrpAAAAAElFTkSuQmCC); +@monsterBorderImage: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAA8CAMAAADG+c2+AAAACVBMVEX///8AAADmmihtJc8lAAAAAXRSTlMAQObYZgAAACxJREFUeAHt2EEBACAAwkCwf2hL8NK7AAuwdCw9U5Og4FgeAAAAAK7IBxPjAl3qBs+hfAnLAAAAAElFTkSuQmCC); @noteBorderImage: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAA8CAMAAADG+c2+AAAANlBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHL6OuAAAAEXRSTlMABAwYJDRIXHSLo7fL2+fz+6go4VUAAAB6SURBVHgB7dg5DsJQAANRZ9+Xuf9lQUKKEHT5LlL4HWB6W5d61m1zrT/dhm5j6/RjPCkJco761ixQFoSl0aXfKQ+y9/qoJnAEYar01q64gqytNBz4ghyDMPMHnyYiIiIiIgIzYeYfj/Z56x3g7ovAf2L4bxb/EWS/ql7LZCDx/Ry3RwAAAABJRU5ErkJggg==); \ No newline at end of file diff --git a/client/homebrew/phbStyle/phb.fonts.css b/client/homebrew/phbStyle/phb.fonts.css index 6db49fd..ea67d47 100644 --- a/client/homebrew/phbStyle/phb.fonts.css +++ b/client/homebrew/phbStyle/phb.fonts.css @@ -1,59 +1,59 @@ -/* Main Font */ -@font-face { - font-family: BookSanity; - src: url(data:font/opentype;base64,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AAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBAQ1Cb29raW5zYW5pdHkAAQEBN/gQAPhPDAD4UAL4UAP4GARADAO9DAT7Avtr+rX5zQUdAAACkw8dAAAD6hEdAAAACx0AAEzGEgA2AgABAAYADgAWAB0AIwAoAC0ANAA6AEAARQBMAFMAWQBfAGQAaQBuAHUAewCBAIYAjQCUAJoAoAClAKoArwC2ALwAwgDHAM4A1QDbAOsA8wD7AQUBFAEkATMBQwFOAVYBXgFsAXoBiQGVAZ0BxQHRLm51bGxub3RlcXVhbGluZmluaXR5bmJzcGFjZXplcm8uMW9uZS4xdHdvLjF0aHJlZS4xZm91ci4xZml2ZS4xc2l4LjFzZXZlbi4xZWlnaHQuMW5pbmUuMXplcm8uMm9uZS4yb25lLjN0d28uMnRocmVlLjJmb3VyLjJmaXZlLjJzaXguMnNldmVuLjJlaWdodC4ybmluZS4yemVyby4zb25lLjRvbmUuNXR3by4zdGhyZWUuM2ZvdXIuM2ZpdmUuM3NpeC4zc2V2ZW4uM2VpZ2h0LjNuaW5lLjNwZXJpb2RjZW50ZXJlZC4xYnVsbGV0LjFleGNsYW0uMXF1ZXN0aW9uLjFndWlsbGVtb3RsZWZ0LjFndWlsbGVtb3RyaWdodC4xZ3VpbHNpbmdsbGVmdC4xZ3VpbHNpbmdscmlnaHQuMWh5cGhlbi5jYXNlZW5kYXNoLjFlbWRhc2guMXBhcmVubGVmdC5jYXNlYnJhY2VsZWZ0LmMyc2NicmFjZXJpZ2h0LmMyc2NudW1iZXJzaWduLjFkb2xsYXIuMUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxCb29raW5zYW5pdHkAAAABhwCoAAEAAgADAAQABQAGAAcAaAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAq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AAAAAP/mAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/8wAAAAAAAP/z//3/9v/4//MAAP/2AAD/8wAAAAAAAAAAAAD/+P/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9l/7f/xv+wAAAAAAAAAAAAAAAAAAD/rQAA/6j/6f/9AAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//j//QAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8wAAAAAAAAAAAAAAAAAA//sAAP/7AAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+jAAUAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAD/+//7//gAAP/7AAX/+wAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/uAAAAAAAAAAAAAP/4//v/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/yQAAAAAAAP/4AAAAAAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6QAAAAAAAAAAAAAAAAAA/+wAAP/kAAD/3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/4gAAAAAAAAAAAAAAAAAA/+cAAP/f//j/7AAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAP/sAAD/ywAAAAAAAP/4AAAAAAAA/+kAAP/LAAD/8QAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7//sAAAAAAAAAAP/7AAD/+AAAAAAAAAAAAAAAAAAA/+kAAP/2AAD/8QAAAAAAAAAAAAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+m//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/6j/+wAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAr/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAAAAAAAAAAAAAAA/+cAAP/Q//b/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAP/hAAAAAAAAAAAAAAAAAAD/sAAAAAAAAwAAAAAAAAAAAAAAAAAAAAD//QAAAAD/8f/EAAD/2P/x/8EAEP/9AAD/7AADAAAAAAAAAAD/0wAAAAD/xgAAAAAAAP/4/90AAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAAAAAAAAAAAAD/vgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAD/5//z/98AAAAAAAD/8wAAAAAAAAAAAAAAAAAA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AAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAA/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7cAAP+3AAAAAAAAAAAAAAAAAAAAAP/u/8QAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAFr/5wAAAAAAAAAAAAAAAAAAAAAAAAAAADcAAABEAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAPAArAAAAKAAAAAD/3wAAAAAAAAAAAAAAAAAAAAAAAAAA/+L/+//LAAAAAAAAAAD/8QAAAAAAAP/s/+IAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA/8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/60AAP+1AAAAAAAAAAAAAAAAAAAAAP/k/8EAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/iAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/+/+7AAAAAAAAAAD/7AAAAAD//f/i//IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+L//QAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAA/+5AAAAAAAAAAAAAAAAAAAAAP/9/84AAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAP+6AAAAAAAAAAAAAAAAAAAAAAAS//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8sAAP+/AAAAAAAAAAAAAAAAAAAAAP/4/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/+//QAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+kAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8kAAP+3AAAAAAAAAAAAAAAAAAAAAP/x/8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/nf/zAAAAAAAAAAD//QAAAAAAAAAAAAD/+/+5AAAAAAAAAAD/9gAAAAAACv/4//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/3/+3AAAAAAAAAAD/5//xAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP+3AAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//4AAAAAAAA//sAAAAA//AAAAAAAAAAAP/4AAAAAAAA//YAAAAAAAAAAAAA//0AAAAAAAAAAAAFAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEAAgCaAAAAAQACAJkAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQACAAMABAAFAAYABwAIAAkACQAKAAsADAAJAAoADQAOAA0ADwAQABEAEgATABQAFQAWABcAAQABAAEAAQABAAEAGAAZABoAAQAbABwAHQAeAB8AHwAgAAEAHgAeACEAGQAiACMAJAAlACYAJwAnACgAJwApAAEAAQABAAEAAQABAAEAAQABAAEABgAqAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAEAKIANQANAAAAAAAAACIADQAAADEAAQAAAAIADgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoACgAAAAAAAAADwAAAAMAAAAEAAAAAAAAAAQAAAAAABAAAAAAAAAAAAAEAAAABAAAACkAEQASAAUABgATAAcAAAAAAAAAMgAAAAAAAAAIADQAFAAVABQAMAAJADQAIwAjADQANAAkACQAFAAkABUAJAAWABcAJAAYABgAIAAYACUAAAAAADMAAAABAAAAAQAAAAAAAAAKAAsAAAACAAAAAAAZAAAAGQAAAA4AAgACAAAAAAAAAAAAAAAAACoAAAAAAAAAGgAAACsAGwAsABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0ALgAAAC8AJgAMACcAKwAhACwAHQAeAB4AAAAAAB8AAAAfAAAAHgAeAB4AAQAAAAoA3AFmAAFsYXRuAAgAIgAFQVpFIAA+Q1JUIABaTU9MIAB2Uk9NIACSVFJLIACuAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAthYWx0AERjMnNjAExjYXNlAFJsbnVtAFhvbnVtAF5vcmRuAGRwbnVtAGpzYWx0AHBzczAyAHhzczA1AH50bnVtAIQAAAACAAAAAQAAAAEAAgAAAAEAAwAAAAEABAAAAAEABQAAAAEABgAAAAEABwAAAAIACAAJAAAAAQAIAAAAAQAJAAAAAQAKAAsAGAAgACgAMAA4AEAASABYAGAAaABwAAEAAAABAGAAAwAAAAEAcgABAAAAAQIMAAEAAAABAiIAAQAAAAECMAABAAAAAQJsAAYAAAAFAqoCzgLwAxoDPAABAAAAAQNWAAEAAAABA5IAAQAAAAEDmAABAAAAAQOiAAIADgAEAJ0AqQCeAJsAAQAEAAQABgAiAHIAAQFoAC0AYABkAGgAbAByAHgAfgCEAIoAkACWAJwAogCoAKwAsAC2ALwAwgDIAM4A1ADaAOAA5gDsAPIA+gEAAQYBDAESARgBHgEkASoBMAE4AT4BRAFKAVABVgFcAWIAAQCqAAEApgABAKMAAgCFAHsAAgCGAHwAAgCIAH0AAgCJAH4AAgCKAH8AAgCLAIAAAgCMAIEAAgCNAIIAAgCOAIMAAgCPAIQAAQCnAAEAqAACAJAAEwACAJEAFAACAJMAFQACAJQAFgACAJUAFwACAJYAGAACAJcAGQACAJgAGgACAJkAGwACAJoAHAACABMAkAADAIcAFACRAAIAFQCTAAIAFgCUAAIAFwCVAAIAGACWAAIAGQCXAAIAGgCYAAIAGwCZAAIAHACaAAIAewCFAAMAkgB8AIYAAgB9AIgAAgB+AIkAAgB/AIoAAgCAAIsAAgCBAIwAAgCCAI0AAgCDAI4AAgCEAI8AAgAJAAcABwAAAAsACwABABAAEAACABMAHAADAF4AXgANAGAAYAAOAHsAhgAPAIgAkQAbAJMAmgAlAAIAEAAFAJ0AqQCeAKcAqAABAAUABAAGACIAXgBgAAIADAADAKYAowCbAAEAAwALABAAcgACAC4AFAATABQAFQAWABcAGAAZABoAGwAcAHsAfAB9AH4AfwCAAIEAggCDAIQAAgADAIUAhgAAAIgAkQACAJMAmgAMAAIAMAAVAKkAhQCGAIgAiQCKAIsAjACNAI4AjwCQAJEAkwCUAJUAlgCXAJgAmQCaAAIAAwAGAAYAAAATABwAAQB7AIQACwADAAIAEgASAAEAGAABAB4AAAABAAEAFAABAAEAVgABAAEAVwADAAIAEAAWAAEAHAAAAAAAAQABABUAAQABABQAAQABAEcAAwACABIAGAABAB4AAQAkAAAAAQABABUAAQABABQAAQABAFEAAQABAEcAAwACABAAFgABABwAAAAAAAEAAQAWAAEAAQAUAAEAAQBHAAMAAgASABgAAQAeAAEAJAAAAAEAAQAWAAEAAQAUAAEAAQBVAAEAAQBHAAIALgAUAHsAfAB9AH4AfwCAAIEAggCDAIQAkACRAJMAlACVAJYAlwCYAJkAmgACAAMAEwAcAAAAhQCGAAoAiACPAAwAAgAIAAEAqgABAAEABwACAAoAAgCHAJIAAQACAIYAkQACAC4AFAATABQAFQAWABcAGAAZABoAGwAcAIUAhgCIAIkAigCLAIwAjQCOAI8AAgADAHsAhAAAAJAAkQAKAJMAmgAM) format('opentype'); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: BookSanity; - src: url(data:font/opentype;base64,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AGMAZABlAGYAZwBoAGkAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBARJCb29raW5zYW5pdHktQm9sZAABAQE3+BAA+E8MAPhQAvhRA/gUBEAMA70MBPsb+4j60/nqBR0AAAKrDx0AAAQCER0AAAALHQAATR0SADcCAAEABgAOABYAHQAjACgALQA0ADoAQABFAEwAUwBZAF8AZABpAG4AdQB7AIEAhgCNAJQAmgCgAKUAqgCvALYAvADCAMcAzgDVANsA6wDzAPsBBQEUASQBMwFDAU4BVgFeAWwBegGJAZUBnQHFAdYB4i5udWxsbm90ZXF1YWxpbmZpbml0eW5ic3BhY2V6ZXJvLjFvbmUuMXR3by4xdGhyZWUuMWZvdXIuMWZpdmUuMXNpeC4xc2V2ZW4uMWVpZ2h0LjFuaW5lLjF6ZXJvLjJvbmUuMm9uZS4zdHdvLjJ0aHJlZS4yZm91ci4yZml2ZS4yc2l4LjJzZXZlbi4yZWlnaHQuMm5pbmUuMnplcm8uM29uZS40b25lLjV0d28uM3RocmVlLjNmb3VyLjNmaXZlLjNzaXguM3NldmVuLjNlaWdodC4zbmluZS4zcGVyaW9kY2VudGVyZWQuMWJ1bGxldC4xZXhjbGFtLjFxdWVzdGlvbi4xZ3VpbGxlbW90bGVmdC4xZ3VpbGxlbW90cmlnaHQuMWd1aWxzaW5nbGxlZnQuMWd1aWxzaW5nbHJpZ2h0LjFoeXBoZW4uY2FzZWVuZGFzaC4xZW1kYXNoLjFwYXJlbmxlZnQuY2FzZWJyYWNlbGVmdC5jMnNjYnJhY2VyaWdodC5jMnNjbnVtYmVyc2lnbi4xZG9sbGFyLjFBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsQm9va2luc2FuaXR5IEJvbGRCb29raW5zYW5pdHkAAAABhwCoAAEAAgADAAQABQAG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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/+wAA//v/+//7AAD/9gAA//sAAAAAAAAAAAAA//v/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5gADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//MAAAAAAAD/8//9//b/+P/zAAD/9gAA//MAAAAAAAAAAAAA//j/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/Zf+3/8b/sAAAAAAAAAAAAAAAAAAA/60AAP+o/+n//QAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4//0AAAAAAAD/7gADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//MAAAAAAAAAAAAAAAAAAP/7AAD/+wAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/owAFAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAA//v/+//4AAD/+wAF//sAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/7gAAAAAAAAAAAAD/+P/7/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA/8kAAAAAAAD/+AAAAAAAAAAAAAD/2AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+kAAAAAAAAAAAAAAAAAAP/sAAD/5AAA/90AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA/+IAAAAAAAAAAAAAAAAAAP/nAAD/3//4/+wAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//f/7AAAAAAAAAAD/7AAA/8sAAAAAAAD/+AAAAAAAAP/pAAD/ywAA//EAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//7AAAAAAAAAAD/+wAA//gAAAAAAAAAAAAAAAAAAP/pAAD/9gAA//EAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/pv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+o//sAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAK//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAAAAAAAAAAAAAAAP/nAAD/0P/2/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAD/4QAAAAAAAAAAAAAAAAAA/7AAAAAAAAMAAAAAAAAAAAAAAAAAAAAA//0AAAAA//H/xAAA/9j/8f/BABD//QAA/+wAAwAAAAAAAAAA/9MAAAAA/8YAAAAAAAD/+P/dAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAMAAAAAAAAAAAAAAAUAAAAAAAAAAP/JAAD/wAAAAAAAAAAAAAAAAAAAAAD/+P/OAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3AAD/twAAAAAAAAAAAAAAAAAAAAD/7v/EAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAABa/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAA3AAAARAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEADwAKwAAACgAAAAA/98AAAAAAAAAAAAAAAAAAAAAAAAAAP/i//v/ywAAAAAAAAAA//EAAAAAAAD/7P/iAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+tAAD/tQAAAAAAAAAAAAAAAAAAAAD/5P/BAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/4gAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/y//v/uwAAAAAAAAAA/+wAAAAA//3/4v/yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/i//0AAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAP/uQAAAAAAAAAAAAAAAAAAAAD//f/OAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5IAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAD/ugAAAAAAAAAAAAAAAAAAAAAAEv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/LAAD/vwAAAAAAAAAAAAAAAAAAAAD/+P/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/x//v/0AAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/JAAD/twAAAAAAAAAAAAAAAAAAAAD/8f/LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX/53/8wAAAAAAAAAA//0AAAAAAAAAAAAA//v/uQAAAAAAAAAA//YAAAAAAAr/+P/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7/9//twAAAAAAAAAA/+f/8QAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAD/twAAAAAAAAAAAAAAAAAAAAAAAP/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/+AAAAAAAAP/7AAAAAP/wAAAAAAAAAAD/+AAAAAAAAP/2AAAAAAAAAAAAAP/9AAAAAAAAAAAABQAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABAAIAmgAAAAEAAgCZAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAgADAAQABQAGAAcACAAJAAkACgALAAwACQAKAA0ADgANAA8AEAARABIAEwAUABUAFgAXAAEAAQABAAEAAQABABgAGQAaAAEAGwAcAB0AHgAfAB8AIAABAB4AHgAhABkAIgAjACQAJQAmACcAJwAoACcAKQABAAEAAQABAAEAAQABAAEAAQABAAYAKgABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEABACiADUADQAAAAAAAAAiAA0AAAAxAAEAAAACAA4AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAAAAAAAAAA8AAAADAAAABAAAAAAAAAAEAAAAAAAQAAAAAAAAAAAABAAAAAQAAAApABEAEgAFAAYAEwAHAAAAAAAAADIAAAAAAAAACAA0ABQAFQAUADAACQA0ACMAIwA0ADQAJAAkABQAJAAVACQAFgAXACQAGAAYACAAGAAlAAAAAAAzAAAAAQAAAAEAAAAAAAAACgALAAAAAgAAAAAAGQAAABkAAAAOAAIAAgAAAAAAAAAAAAAAAAAqAAAAAAAAABoAAAArABsALAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtAC4AAAAvACYADAAnACsAIQAsAB0AHgAeAAAAAAAfAAAAHwAAAB4AHgAeAAEAAAAKANwBZgABbGF0bgAIACIABUFaRSAAPkNSVCAAWk1PTCAAdlJPTSAAklRSSyAArgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgALYWFsdABEYzJzYwBMY2FzZQBSbG51bQBYb251bQBeb3JkbgBkcG51bQBqc2FsdABwc3MwMgB4c3MwNQB+dG51bQCEAAAAAgAAAAEAAAABAAIAAAABAAMAAAABAAQAAAABAAUAAAABAAYAAAABAAcAAAACAAgACQAAAAEACAAAAAEACQAAAAEACgALABgAIAAoADAAOABAAEgAWABgAGgAcAABAAAAAQBgAAMAAAABAHIAAQAAAAECDAABAAAAAQIiAAEAAAABAjAAAQAAAAECbAAGAAAABQKqAs4C8AMaAzwAAQAAAAEDVgABAAAAAQOSAAEAAAABA5gAAQAAAAEDogACAA4ABACdAKkAngCbAAEABAAEAAYAIgByAAEBaAAtAGAAZABoAGwAcgB4AH4AhACKAJAAlgCcAKIAqACsALAAtgC8AMIAyADOANQA2gDgAOYA7ADyAPoBAAEGAQwBEgEYAR4BJAEqATABOAE+AUQBSgFQAVYBXAFiAAEAqgABAKYAAQCjAAIAhQB7AAIAhgB8AAIAiAB9AAIAiQB+AAIAigB/AAIAiwCAAAIAjACBAAIAjQCCAAIAjgCDAAIAjwCEAAEApwABAKgAAgCQABMAAgCRABQAAgCTABUAAgCUABYAAgCVABcAAgCWABgAAgCXABkAAgCYABoAAgCZABsAAgCaABwAAgATAJAAAwCHABQAkQACABUAkwACABYAlAACABcAlQACABgAlgACABkAlwACABoAmAACABsAmQACABwAmgACAHsAhQADAJIAfACGAAIAfQCIAAIAfgCJAAIAfwCKAAIAgACLAAIAgQCMAAIAggCNAAIAgwCOAAIAhACPAAIACQAHAAcAAAALAAsAAQAQABAAAgATABwAAwBeAF4ADQBgAGAADgB7AIYADwCIAJEAGwCTAJoAJQACABAABQCdAKkAngCnAKgAAQAFAAQABgAiAF4AYAACAAwAAwCmAKMAmwABAAMACwAQAHIAAgAuABQAEwAUABUAFgAXABgAGQAaABsAHAB7AHwAfQB+AH8AgACBAIIAgwCEAAIAAwCFAIYAAACIAJEAAgCTAJoADAACADAAFQCpAIUAhgCIAIkAigCLAIwAjQCOAI8AkACRAJMAlACVAJYAlwCYAJkAmgACAAMABgAGAAAAEwAcAAEAewCEAAsAAwACABIAEgABABgAAQAeAAAAAQABABQAAQABAFYAAQABAFcAAwACABAAFgABABwAAAAAAAEAAQAVAAEAAQAUAAEAAQBHAAMAAgASABgAAQAeAAEAJAAAAAEAAQAVAAEAAQAUAAEAAQBRAAEAAQBHAAMAAgAQABYAAQAcAAAAAAABAAEAFgABAAEAFAABAAEARwADAAIAEgAYAAEAHgABACQAAAABAAEAFgABAAEAFAABAAEAVQABAAEARwACAC4AFAB7AHwAfQB+AH8AgACBAIIAgwCEAJAAkQCTAJQAlQCWAJcAmACZAJoAAgADABMAHAAAAIUAhgAKAIgAjwAMAAIACAABAKoAAQABAAcAAgAKAAIAhwCSAAEAAgCGAJEAAgAuABQAEwAUABUAFgAXABgAGQAaABsAHACFAIYAiACJAIoAiwCMAI0AjgCPAAIAAwB7AIQAAACQAJEACgCTAJoADA==) format('opentype'); - font-weight: bold; - font-style: normal; -} -@font-face { - font-family: BookSanity; - src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGICGZBk0AAAfcAABO6kRTSUcAAAABAABZeAAAAAhHREVGALsAAwAAWYAAAAAYR1BPU2uUukYAAFmYAAAmKEdTVULlMciwAAB/wAAABbxPUy8yOu7UAAAAAUAAAABgY21hcJ/aplYAAATEAAAC9mhlYWQIEgIzAAAA3AAAADZoaGVhCLIGaAAAARQAAAAkaG10eFh6MKQAAFbIAAACrm1heHAArFAAAAABOAAAAAZuYW1lHo8siwAAAaAAAAMhcG9zdP+sADIAAAe8AAAAIAABAAAAAQBCIIbG8F8PPPUAAQPoAAAAANKJ1JUAAAAA0onqGv9y/ykEdQM5AAIAAwACAAAAAAAAAAEAAAPz/nYAAAQp/3L/NgR1A+gA1QAAAAAAAAAAAAAAAACrAABQAACsAAAAAwIGAZAABQAAArwCigAAAIwCvAKKAAAB3QAyAPoAAAIABQMHAAAJAAOAAAAjAAAASAAAAAAAAAAAICAgIAABAAAiYALu/wYAAAPzAYoAAAABAAAAAAHDArwAAAAgAAIAAAAUAPYAAQAAAAAAAAAoAFkAAQAAAAAAAQAMAAAAAQAAAAAAAgAGAA0AAQAAAAAAAwAhAAAAAQAAAAAABAATAAAAAQAAAAAABQAeACEAAQAAAAAABgATAD8AAQAAAAAACQAHAFIAAQAAAAAADQAoAFkAAQAAAAAADgA4AIEAAwABBAkAAABQALkAAwABBAkAAQAYAQkAAwABBAkAAgAMASMAAwABBAkAAwBCAQkAAwABBAkABAAmAQkAAwABBAkABQA8AUsAAwABBAkABgAmAYcAAwABBAkACQAOAa0AAwABBAkADQBQALkAAwABBAkADgBwAbtCb29raW5zYW5pdHkgSXRhbGljOlZlcnNpb24gMS4wMDFWZXJzaW9uIDEuMDAxIERlY2VtYmVyIDYsIDIwMTVCb29raW5zYW5pdHktSXRhbGljU29sYmVyYUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wL2xlZ2FsY29kZQBBAHQAdAByAGkAYgB1AHQAaQBvAG4ALQBTAGgAYQByAGUAQQBsAGkAawBlACAANAAuADAAIABJAG4AdABlAHIAbgBhAHQAaQBvAG4AYQBsAEIAbwBvAGsAaQBuAHMAYQBuAGkAdAB5ACAASQB0AGEAbABpAGMAOgBWAGUAcgBzAGkAbwBuACAAMQAuADAAMAAxAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwADEAIABEAGUAYwBlAG0AYgBlAHIAIAA2ACwAIAAyADAAMQA1AEIAbwBvAGsAaQBuAHMAYQBuAGkAdAB5AC0ASQB0AGEAbABpAGMAUwBvAGwAYgBlAHIAYQBoAHQAdABwAHMAOgAvAC8AYwByAGUAYQB0AGkAdgBlAGMAbwBtAG0AbwBuAHMALgBvAHIAZwAvAGwAaQBjAGUAbgBzAGUAcwAvAGIAeQAtAHMAYQAvADQALgAwAC8AbABlAGcAYQBsAGMAbwBkAGUAAAAAAAADAAAAAwAAABwAAQAAAAAA9AADAAEAAAAcAAQA2AAAACwAIAAEAAwAAAAdAH4AoACkAKkArwC0ALcAxgDYAPcCxgLaAtwgGiAeICYhIiIeImD//wAAAAAAHQAgAKAApACoAK4AtAC3AMYA1wD3AsYC2ALcIBggHCAmISIiHiJg//8AAf/j/+P/zAAHAAAAAP+x/7v/ogAA/3r9r/2g/ZoAAAAA4EXfQt5M3gcAAQAAAAAAAAAAAAAAIgAkAAAAAAAAACAAAAAAAAAAAAAaAB4AAAAAAAAAAAAAAGYAYwBiAHcAAgBpAG8AcABzAG0AbgB0AAYCAgAAAAAA/AABAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABiAGMAZABlAGYAZwBoAGkAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAP/0AAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBARRCb29raW5zYW5pdHktSXRhbGljAAEBATj4EAD4TwwA+FAC+FED+FIEQAwDvQwE+yL7axwEdfnNBR0AAAK4Dx0AAAQPER0AAAALHQAATt0SADgCAAEABgAOABYAHQAjACgALQA0ADoAQABFAEwAUwBZAF8AZABpAG4AdQB7AIEAhgCNAJQAmgCgAKUAqgCvALYAvADCAMcAzgDVANsA6wDzAPsBBQEUASQBMwFDAU4BVgFeAWwBegGJAZUBnQHFAdgB5AHqLm51bGxub3RlcXVhbGluZmluaXR5bmJzcGFjZXplcm8uMW9uZS4xdHdvLjF0aHJlZS4xZm91ci4xZml2ZS4xc2l4LjFzZXZlbi4xZWlnaHQuMW5pbmUuMXplcm8uMm9uZS4yb25lLjN0d28uMnRocmVlLjJmb3VyLjJmaXZlLjJzaXguMnNldmVuLjJlaWdodC4ybmluZS4yemVyby4zb25lLjRvbmUuNXR3by4zdGhyZWUuM2ZvdXIuM2ZpdmUuM3NpeC4zc2V2ZW4uM2VpZ2h0LjNuaW5lLjNwZXJpb2RjZW50ZXJlZC4xYnVsbGV0LjFleGNsYW0uMXF1ZXN0aW9uLjFndWlsbGVtb3RsZWZ0LjFndWlsbGVtb3RyaWdodC4xZ3VpbHNpbmdsbGVmdC4xZ3VpbHNpbmdscmlnaHQuMWh5cGhlbi5jYXNlZW5kYXNoLjFlbWRhc2guMXBhcmVubGVmdC5jYXNlYnJhY2VsZWZ0LmMyc2NicmFjZXJpZ2h0LmMyc2NudW1iZXJzaWduLjFkb2xsYXIuMUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxCb29raW5zYW5pdHkgSXRhbGljQm9va2luc2FuaXR5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AAAAAAAAAAAAAAAAAAAAAP/xAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAA/90AAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7//v/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAA//v//f/4//j/+AAA//YAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+4AAwAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAA//EAAAAAAAD/+//aAAAAAAAA//gAAP/7//v/+wAA/9oAAP/2AAAAAAAAAAAAAP/p/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAA//sAAP/7//v/+wAA//YAAP/7AAAAAAAAAAAAAP/7//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//f/zAAAAAAAA//P//f/2//j/8wAA//YAAP/zAAAAAAAAAAAAAP/4//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2X/t//G/7AAAAAAAAAAAAAAAAAAAP+tAAD/qP/p//0AAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+P/9AAAAAAAA/+4AAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAAAAAAAAAAAAAAD/+wAA//sAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/6MABQAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAP/7//v/+AAA//sABf/7AAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAA/+4AAAAAAAAAAAAA//j/+//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/JAAAAAAAA//gAAAAAAAAAAAAA/9gAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAAAAAAAAAAAAAAAAAD/7AAA/+QAAP/dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/iAAAAAAAAAAAAAAAAAAD/5wAA/9//+P/sAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/+wAAAAAAAAAA/+wAAP/LAAAAAAAA//gAAAAAAAD/6QAA/8sAAP/xAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/+wAAAAAAAAAA//sAAP/4AAAAAAAAAAAAAAAA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AAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/ywAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/rQAA/7UAAAAAAAAAAAAAAAAAAAAA/+T/wQAAAAAAAAAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/+IAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8v/7/7sAAAAAAAAAAP/sAAAAAP/9/+L/8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4v/9AAAAAAAAAAAAAAAAAAAAAAAAAAD/ugAD/7kAAAAAAAAAAAAAAAAAAAAA//3/zgAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+SAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAA/7oAAAAAAAAAAAAAAAAAAAAAABL/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ywAA/78AAAAAAAAAAAAAAAAAAAAA//j/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/7/9AAAAAAAAAAAAAAAAAAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AVwBYgABAKoAAQCmAAEAowACAIUAewACAIYAfAACAIgAfQACAIkAfgACAIoAfwACAIsAgAACAIwAgQACAI0AggACAI4AgwACAI8AhAABAKcAAQCoAAIAkAATAAIAkQAUAAIAkwAVAAIAlAAWAAIAlQAXAAIAlgAYAAIAlwAZAAIAmAAaAAIAmQAbAAIAmgAcAAIAEwCQAAMAhwAUAJEAAgAVAJMAAgAWAJQAAgAXAJUAAgAYAJYAAgAZAJcAAgAaAJgAAgAbAJkAAgAcAJoAAgB7AIUAAwCSAHwAhgACAH0AiAACAH4AiQACAH8AigACAIAAiwACAIEAjAACAIIAjQACAIMAjgACAIQAjwACAAkABwAHAAAACwALAAEAEAAQAAIAEwAcAAMAXgBeAA0AYABgAA4AewCGAA8AiACRABsAkwCaACUAAgAQAAUAnQCpAJ4ApwCoAAEABQAEAAYAIgBeAGAAAgAMAAMApgCjAJsAAQADAAsAEAByAAIALgAUABMAFAAVABYAFwAYABkAGgAbABwAewB8AH0AfgB/AIAAgQCCAIMAhAACAAMAhQCGAAAAiACRAAIAkwCaAAwAAgAwABUAqQCFAIYAiACJAIoAiwCMAI0AjgCPAJAAkQCTAJQAlQCWAJcAmACZAJoAAgADAAYABgAAABMAHAABAHsAhAALAAMAAgASABIAAQAYAAEAHgAAAAEAAQAUAAEAAQBWAAEAAQBXAAMAAgAQABYAAQAcAAAAAAABAAEAFQABAAEAFAABAAEARwADAAIAEgAYAAEAHgABACQAAAABAAEAFQABAAEAFAABAAEAUQABAAEARwADAAIAEAAWAAEAHAAAAAAAAQABABYAAQABABQAAQABAEcAAwACABIAGAABAB4AAQAkAAAAAQABABYAAQABABQAAQABAFUAAQABAEcAAgAuABQAewB8AH0AfgB/AIAAgQCCAIMAhACQAJEAkwCUAJUAlgCXAJgAmQCaAAIAAwATABwAAACFAIYACgCIAI8ADAACAAgAAQCqAAEAAQAHAAIACgACAIcAkgABAAIAhgCRAAIALgAUABMAFAAVABYAFwAYABkAGgAbABwAhQCGAIgAiQCKAIsAjACNAI4AjwACAAMAewCEAAAAkACRAAoAkwCaAAw=) format('opentype'); - font-weight: normal; - font-style: italic; -} -@font-face { - font-family: BookSanity; - src: url(data:font/opentype;base64,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AAAAAAAAAAAAAABiAGMAZABlAGYAZwBoAGkAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAP/0AAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBARRCb29raW5zYW5pdHktSXRhbGljAAEBATj4EAD4TwwA+FAC+FED+FIEQAwDvQwE+z37iRwEkPnrBR0AAAK4Dx0AAAQPER0AAAALHQAATwUSADgCAAEABgAOABYAHQAjACgALQA0ADoAQABFAEwAUwBZAF8AZABpAG4AdQB7AIEAhgCNAJQAmgCgAKUAqgCvALYAvADCAMcAzgDVANsA6wDzAPsBBQEUASQBMwFDAU4BVgFeAWwBegGJAZUBnQHFAdgB5AHqLm51bGxub3RlcXVhbGluZmluaXR5bmJzcGFjZXplcm8uMW9uZS4xdHdvLjF0aHJlZS4xZm91ci4xZml2ZS4xc2l4LjFzZXZlbi4xZWlnaHQuMW5pbmUuMXplcm8uMm9uZS4yb25lLjN0d28uMnRocmVlLjJmb3VyLjJmaXZlLjJzaXguMnNldmVuLjJlaWdodC4ybmluZS4yemVyby4zb25lLjRvbmUuNXR3by4zdGhyZWUuM2ZvdXIuM2ZpdmUuM3NpeC4zc2V2ZW4uM2VpZ2h0LjNuaW5lLjNwZXJpb2RjZW50ZXJlZC4xYnVsbGV0LjFleGNsYW0uMXF1ZXN0aW9uLjFndWlsbGVtb3RsZWZ0LjFndWlsbGVtb3RyaWdodC4xZ3VpbHNpbmdsbGVmdC4xZ3VpbHNpbmdscmlnaHQuMWh5cGhlbi5jYXNlZW5kYXNoLjFlbWRhc2guMXBhcmVubGVmdC5jYXNlYnJhY2VsZWZ0LmMyc2NicmFjZXJpZ2h0LmMyc2NudW1iZXJzaWduLjFkb2xsYXIuMUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxCb29raW5zYW5pdHkgSXRhbGljQm9va2luc2FuaXR5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/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7/6v/2P/aAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAP/dAAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//7//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/7//3/+P/4//gAAP/2AAAAAAAAAAAAAAAAAAD//f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/xAAAAAAAA//v/2gAAAAAAAP/4AAD/+//7//sAAP/aAAD/9gAAAAAAAAAAAAD/6f/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAP/7AAD/+//7//sAAP/2AAD/+wAAAAAAAAAAAAD/+//7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/8wAAAAAAAP/z//3/9v/4//MAAP/2AAD/8wAAAAAAAAAAAAD/+P/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9l/7f/xv+wAAAAAAAAAAAAAAAAAAD/rQAA/6j/6f/9AAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//j//QAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8wAAAAAAAAAAAAAAAAAA//sAAP/7AAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+jAAUAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAD/+//7//gAAP/7AAX/+wAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/uAAAAAAAAAAAAAP/4//v/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/yQAAAAAAAP/4AAAAAAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6QAAAAAAAAAAAAAAAAAA/+wAAP/kAAD/3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/4gAAAAAAAAAAAAAAAAAA/+cAAP/f//j/7AAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAP/sAAD/ywAAAAAAAP/4AAAAAAAA/+kAAP/LAAD/8QAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAA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AAAAAAAA/+L/+//LAAAAAAAAAAD/8QAAAAAAAP/s/+IAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA/8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/60AAP+1AAAAAAAAAAAAAAAAAAAAAP/k/8EAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/iAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/+/+7AAAAAAAAAAD/7AAAAAD//f/i//IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+L//QAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAA/+5AAAAAAAAAAAAAAAAAAAAAP/9/84AAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAP+6AAAAAAAAAAAAAAAAAAAAAAAS//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8sAAP+/AAAAAAAAAAAAAAAAAAAAAP/4/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/+//QAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAA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) format('opentype'); - font-weight: bold; - font-style: italic; -} - -/* Notes and Tables */ -@font-face { - font-family: ScalySans; - src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), - url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: ScalySansSmallCaps; - src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), - url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAEPYABEAAAAAc3wAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABgAAAABwAAAAcWc9lWEdERUYAAAGcAAAAHgAAACAA8AAET1MvMgAAAbwAAABRAAAAYJIKLSBjbWFwAAACEAAAAckAAAJKTlAlvmN2dCAAAAPcAAAANAAAADQM9RD7ZnBnbQAABBAAAAGxAAACZVO0L6dnYXNwAAAFxAAAAAgAAAAIAAAAEGdseWYAAAXMAAA2/gAAYlyo8FmwaGVhZAAAPMwAAAAxAAAANgyIsOloaGVhAAA9AAAAACAAAAAkDtIGDmhtdHgAAD0gAAABzQAAAwwP01R/bG9jYQAAPvAAAAF6AAABiLMty6BtYXhwAABAbAAAAB8AAAAgAeACb25hbWUAAECMAAABFgAAAioHBVLlcG9zdAAAQaQAAAGOAAACUkMTPyJwcmVwAABDNAAAAJkAAADgIWMV5XdlYmYAAEPQAAAABgAAAAaC+1aWAAAAAQAAAADMPaLPAAAAALrVjw4AAAAA0rwzenjaY2BkYGDgA2IJBhBgYmAEwkNAzALmMQAADKAA9QAAeNpjYGHhZpzAwMrAwriIcREDA5MXjGZIY2IA0gyszCwgiqWBgUGZAQkUVBYVMxxg4FX9w5b2L42Bge0TkxJQmBEkx3yZ1QNIKTAwAgBGdAzeAAAAeNpjYGBgZoBgGQZGIMnA6ALkMYL5LIwaQNqNwYGBlYGNgZdBkUGNwZ4hlqGOYTHDUoYVDKsZ1jKsZ9jIsIVhB8NuhvMM1xjuMLxn+MPwnzGYsYLpGNMdBS4FEQUpBTkFfQUrhXjVP///A83jZVBgUGHQYHBkiGdYgMWc/QwXGW4wPGD4CDQnCGoOg4KAgoSCDNAcS4g5/7/+f/z/4f8H/+//v/d/7/89/3f93/F/+/9t/7f+3/x/w/91/1f/X/V/5f9l/5f+X/w/8L/u3wd/Tz9Y8WDxgwUP5j/of9D2IOnWMYh/qQEY2RjghjEyAQkmdAXAIGZhYGBlY2fg4OTi5uHl4xcQFBIWERUTl5CUkpaRlZNnUFBUUlZRVVPX0NTS1tHV0zcwNDI2MTUzt7C0srZhsLWzd3B0cnZxdXP38PTy9vH18w8IDAoOCQ0Lj4iMio5hyC8oKqluaG1v6+jq7O7t75swcfKkKVOnzZg+c/as+fMWLGRgiE+AuiY9iaGwkSGNgSER7sCeuVlxYEZyJkNsdl794iXbtu/es2PnHIZFSxkY9h8ASe3ay5BbmlNWXFFZVV5bx1DT3NLEsGx5KlAmA4gBYyyhAwAAAAAAA9MFSACBAI4AkwCZAJwAtwCcAKQAqACwALcCXgJqAJcAfQCHAHkAWACRAGMAewBEBRF42l1Ru05bQRDdDQ8DgcTYIDnaFLOZkMZ7oQUJxNWNYmQ7heUIaTdykYtxAR9AgUQN2q8ZoKGkSJsGIRdIfEI+IRIza4iiNDs7s3POmTNLypGqd+lrz1PnJJDC3QbNNv1OSLWzAPek6+uNjLSDB1psZvTKdfv+Cwab0ZQ7agDlPW8pDxlNO4FatKf+0fwKhvv8H/M7GLQ00/TUOgnpIQTmm3FLg+8ZzbrLD/qC1eFiMDCkmKbiLj+mUv63NOdqy7C1kdG8gzMR+ck0QFNrbQSa/tQh1fNxFEuQy6axNpiYsv4kE8GFyXRVU7XM+NrBXbKz6GCDKs2BB9jDVnkMHg4PJhTStyTKLA0R9mKrxAgRkxwKOeXcyf6kQPlIEsa8SUo744a1BsaR18CgNk+z/zybTW1vHcL4WRzBd78ZSzr4yIbaGBFiO2IpgAlEQkZV+YYaz70sBuRS+89AlIDl8Y9/nQi07thEPJe1dQ4xVgh6ftvc8suKu1a5zotCd2+qaqjSKc37Xs6+xwOeHgvDQWPBm8/7/kqB+jwsrjRoDgRDejd6/6K16oirvBc+sifTv7FaAAAAAAEAAf//AA942t28DXQTV5ooWLeqJMuyLJX+LMuyLMtlWQghF1JZCCH/YWy3Y4jjOI7b49A07TiOIU27aeL242UYxkMzhNAOSUhIMHQ2L4/l+bEsp0pWSEKYNJCXpHuyGTYnJ2RzmJxsv5wMcW8mncfm9ASwi/3urZIt89vTb9/OOcuPSlW6VfX9/93vXoqmmimKHtDdTzFUHlUtI0qoTeexxf8ck/W6f6xNMzR8pWQGX9bhy+k8vXumNo3wddHqtwb8Vn8zXa5UoheUId39V/6XZvZ9Ch5JHb72BRrXfU4VUBYqQqUZigpn8vMoGxtGEifIFApn9AbKw4ZlKwrLespqk02WZJJaGk04isTYsnhNFV+h9yDRfrhlqdDSIgitJYUHC/uE1lb42qrru3qM7QaoB69tYT7WfUStou6mvk99TqXz4U2SXpQ7dNNSKpaO0nC6RJRbddNyqTcWQ1KvINWcl5uN01IzJ98PL7cap+W/QGFpWcnJb+Nn3JQzbJRKq81S2WmdvIS7bJYWn9ZJpdyUt7TMHj75re+MF4YUSEu4qfCSxfZwGj7Lnyh/gtebrbYklS5bHK6urkavlHrh25Jq8kdqLEFycw0g2bgqmZTutzYW6A35rhJfdEVDa0elKynBTxUBwF/uyLfaJCoptVobjdaSQM2K+lVt99yPh0RtUlUS6FOGXGXIh8R4PZOoR0CoYDXC/6xljAv+JfAZE4zzeWbkdJTRPmRVr9hrElZHVRD+ImvMVeQqcjr0g02tVeJDfXSf0ByPuFONK6LuoS6Dw+IO+CvcDr+PL+pINoU8S6oTgT46c8bb/JOu7obWMOfjw97HzvnNdHs3CtsqhgvtG0YjIYvLxv5sq55zljmjT3e3jwUdTQJrKkAf02yeyWAo5GyWX/rLzYYCPUtvfcz12r54T3dXJKY4WbPdYHaW2hnDiwGll3WY6JrEzCfotZI+Z2nbmmFKR7VeO6LfpdtN2akgFaYaqPuo/VQ6CryW72Gm0xbgsuxmpjMtqailMCy3wFdeR77yzDSSugWJOp9x5FOlbFhycHIZiJ9RPTNy8hI4a1TPGjm5Hc6WkTMiHWUOq23KolsUAhbI7Y1wEo6mFsMJJbfcA1xbtiSZlN08fDNSSWCPHUguxurpeE01zVeYaVdNPZyX0U6HGc6rabuIeHSHMa3J9Tva23f0JxL9+Lg+ua2ysTsa7WkMBBp7otHuxkpunH32SaV7ufZ7cv0v7oLxyx9Tf28IBBrU8cwf8WV1WH8y2f+Lu6LdKwOBlXNPu/o73edX34JnrFiR885oD34EeRUM6gZ93nXtK/Zb5nPqLqqP+hWV1mEtKxDlHmZacsTStQjUO8JQvVi9HxCkleflxfnTU+2LVxrCMgWqRglyOxwWc/JSoGkyf1pKcrIPKF2mUnotXF3cDpLfnJSWWk/oIjXx2s4eLPVJW7rScG8StMZnldxJqcwmOwqwovToYLghKUWsr3KU2xpPruyE8dh+YOIuAzURY6AfiaAZYZoGQVt4oG8eqmbiNcvEWBHohwW5VBXCXHA6ilx5ZgYzowHZzQy+a5fQ89ia/pfXRNe1rm9zlfm6Ik1Bm89X7grVh4voHSav4FPO+Sqd+tZ72pppOuIPdPLdK5/7RdvPOkJd4e/V3R00HTZ6xWDku2BzQ8rnSQq+z8S+pkoxmYqmbIFgY3wJayl1+ZNNvavCddGwB3XxYX+pPdLZLfgDnL3XFmmv3fLXwVV90eRwOMg3tbQ6/NXhoMuj/LOnxEQ7eAHMLYWQUTHS7+m6KQ9oCJJKsbzL5oJp2YvCYFORw4ZNg1hNg8zZgCi8mcnT08jY3Oau8AdKJuoebg+F2gfrJzzlvkBpWzPKHFPOTNatqY362z74Dpl37kDWf/mwzR2Kd686rrxD3klFFCP6OvedrvNy/tw77SJQfJktXkNj48OX0TangzajyISnys8XtTc1t3krfXyx9uqHFSMfr129PIPiR4+iFceb74uH3G0f/ovyhx07lUvffUCBDRDRBeY9XRvxVdiv2KlKeK9DkPLPY222ghwV5E/LTpAlI1hRWW8iDsWuSwTsLnsQOxPGnmCCrkBQRGuCysne0TMPRgp/bllxZuQjTxCtiTBv/3DL6OzvepCvhc5XjqC+2bQCZ9bnt/xwj4pzB0WxbuY9eD9l91vBBcb9Vt7q70DHtqBjSvcWpRsdVXrQ0RF8BuO3KR+jIep9ykkdoCSjkLHnUflYSYpUH2glPlDiYrJL9UD1E5ck7IFYiQMXZD4tI+tliT0tsdwUzSJ7eIrBn5KZm7KYOXA+cDrvfCQ6mYbL2A2dQGaaYS2c6n/AHannOe7ICj5Xyice1wXSYEZ5IlYXrA7gebf1sgZ9ATzV3OcJhUxG/aO8OPmpw+vxOUJhf7SjV/DGPTsshCY9aCf6lPYDX8oorOlMHphcVkUQGagC4ItOFQmgVg/apWxFOw/BfePXLqIR6hzQkr8uQjAtiBAKyc25ccF4c1RobhaizWujzeQrgaMXdGCayMfdFAYA6wACU4M4mQGZoEE2dCqV6ya//lilMlUt0dUSxcnIdlmiYaDtMj1FIZrJ0olIMuJ7x2l2XDHm1YMtbLv2O+acboT4oibVFsp83rTkFmQLRn0RebPDMK25GtlomJZDmi+RLTpsvRZ4DBu2VfUI60o1GCszusEjtK0cPTIwcGRrU9PW//mhgSOjKzPBlodSdQ+3BYNtA7V1D30vSB97Sfnu5IYNJ5HhpZeQHn9Trry07f19nZ1Pn9u27Rwc972vyvAxCNCGgU46ygV00qu0Zs1UIdA6T2MUFu1jyDOp1LHHr3bBYExfimL26tYA1qVUugK7XINORbfgvOwzEhzxzS6s+K5YEQYeyxVyAt+RJluYfXCxdzC0LFBmT7atGzAWBT2hHkF5jYnO/hbF6x52GY2vvbzucI8txO4aCUS8tgIv+skGvq6uNVQ3ukJ5uHMC7ej4z42+ltDRM/WrzH4M28ZrXzOtul6IDB7SOLJCN50uxkAGdNOZpVFdMQQDS3Ew0ChI8fOy0TQNvl9ylp+3youAVYsE2QlsWgkowK1qDBa1ysYGcO+BpVZbutBZjr1QsVXykSiMUT14VTAbhvEV4D3yAHkRo67HJ05RpQJxQBuFtsa6wLojW1ufeNRT6S22+EoPjQ102fyhqL8vUi9GPE2rQyFbILSssm/z31Q1r024hXhTuMFdbtOvGn157e7XrDavt9wZXZfYPuE3cB6+ZAsfLs7vaos+HHGVe4rNI49tSA22hwz2MheOwRPAr8PAOiNVqFkrMc5beZRA1gQdnpicHJz9D2+hIbRWOYzWjjM/nHmsirbO/oHIyOC1L5gOuHcxVU2l8zA9A1i0w4JUfl42Aa8haJJN5SDEziIsz4E8QjJCGIgtCWmw3ScGEkuyqygvS4hBnxAKe5q/1zfxk/qdvlTHwy3o6KxkTnTURr1nUKh1IOmNxuvDHTaP06y3odbHjg5cGPHwxSYWNU/MPkfrTYa6f2za2Bk2OPkSwHMU9PE4+KEgVUOtVy2JLOqn0+WY+x7gfkGYKQfuF2BpjRPlXATcN8ekRZxcDXgYwGktg2P1IsCngAEuG6yQLWC8wiJcogxwqcAqmbG2cjaN8ViQCe8T9UwKxYMQQuTpwau66tEc20c/O9ezd0Pq+P625/oNzmKfy73M729o6621hZr6O1byg21ru493PR1fv8Gf6hK+o3uVD5TX2rYdGzz+finf0Nea8HojnM1l0u8HrF2c+P1h5ZvjXv+OkaafdAqYTxng0zHgUxHmMKPacZcKlT3uz9DL33IsT9UWczX8k+GGaNDuTpT+cdbAHlcM4vbto2HvPcv72h/pXR2K/83d9OjD2D4w1LprnzATYN94Kgr6NKTpkwAJVVyQXTpVhUrPyzEgYoyTKrEKUSYS5FWSS0Q4wOhJy/FPDiNRK3l5zGp7RefiFgnlJHyOC3BOGR2li2pJ4JYbOQtoQVzmQ4CXq2ZZA059QLf4iio7ieHguwUnP+tqNz5z3/qXNjdaAw3CU6N1MenZzt39K5aLe346dF86Uju6NxXeNTT41zUDXe0D0eDaRwLlyNc62htNPLi7O9TS2Fw1srVuuG3XYaFnpLX5ryJjw4O/XCX2NI1tF++J9/1kgOnvWH9/U+iRUP+WYAvWrUGQuRd1XVQVJVI/pNIOTCE7yBwxi0v00xkm6qgAmWMwuWqIzAULpqWgKnA+07Qch2MQ5712B0hXtTXNVOiTWOSiDKiSPiktsco+zUFgz5fAIRsYlTByYiolluHgisvJH+w40K0aJLJmtLnLXEITX9fam3IsAlFr5vvb13b/n//Q/cxQ7STI2tLvTF3PgNgxjx1/38c3PNCa9KR8WNBe0BcWWYW+Tch2EgmotXX7sZ6GzZ2C4vL6fwF4E5/NvAY+2wWY53ptySJknJr/LiY+RTLFNBcu2WKy+wYvbr2ZR7/es9NvkC+rVlGkroDjqVF4v4MqB8sEL8qUae/0C5LzfMajhgwVQFyP02rLsEbOhrC4XRfmLCNRDpMDgRrxGMwWrs8LEQ/3aCBqyQK0MPKpF3ZY6MezYCGqE2JCF8SEetBBFM9HcdTJvDvzEROeSaLjStcYGkAPjSldBH4R2ViRPkxiWArHQ/ivyFIzFP6PbCOTI8T+5jxThAc688kzk/DMj9DxYXR8TDmoHILnHbt2kf5Kd5HyQVbcSaV5zI+Qyg8IovJZkL4l2GZnqlRGVHE4BpKdEAtF4FgFFjxTYCrz5eNcS2eFhIqSTSEQQCMWvDIGOzIw4HEiclglq0k4n0u4Y+smflzr8ivvTQzx0SDvEoKhjkdWuSNiUySY5aZujWnNyERvdKWgPH9BbylxCT/p7JzYtTlodtjNxisj82Ec4MQB7mndMFDISFEpZPfjAIzxIO6VPTS/J6MYMzs+vYD2Kpt1wzMn6Y2z+4Gan8E9TWAH7UCJaoj/0hTWSAc7nbZjjfSz05lyJ2UHjSzXA00EQXKfhwQBNBKbKBPo41Ls+Z0OVffKrRAaS36bZAIyiP6sp9eqLbzfbs06eYAMf8fVFFBO/jP0bdeu9cue3bXp3yej4tZ+5a7JL/c8Fyzn+9Z++WXH3Z7ESq4yHA+I63d2jr/iCfzH4bYxQQhcbUGf/tVo/MFSr4seRScc3sTApiauyKLP+mJ2UrcefHGdZoutedPpKuLd9KpTBvNSZCBOmZKtOHopTEoea5oyl+GYpcpGYhYINItYbEnAP2hZcZxYjiJXAnhKjO3gw68hakLoFd2hUKRM6NrbM3r2ibvuGnvlx/2HOrrdwQreNbL76e9ObKCPHlJmTm0oMOlNFpv5F7y3c98H20feGu+ILttuc9vNhsjGNxSVn8AbXTvwppDy4log4YwZOFOIMbBgES3DuivnARd8GAMLJDNSnkr5ZZrUYZr7tYgYU/0zdEa6uLb3hw+duLJPqZtE1JazT3a6w3WBpiM7+x4ZmNn59B/TD11tYSOd46c3J7YMDwSbkkBLgIXBOQLkbyIOTbT/nzHG2RfR75UiunPWMI4+fRKdfZLQHo//GMbnY0mcGz2ZHUqvfQr9w5Maj77WrQP85ngE3iCEMSzFPKqe45Ewx6OCpFQKPDJVYB6FbBK/gEcoAYlllkv4HPOpDKn1PbjM6unB4beQ/kDP6y1czD/Z1Vez/eNf9bY0dvyXp7qeT5kqixsTjZH4obYJ5cqbm+gj+xXl1CZXEWs10SGlnivsee7cYwNvtK/t9Lr1nHmPr9Rktg69cY2isnjr1qh0wnhD7AhZrpX/bJLxTk7OfD6J1U7XNnuKbp4bj3aR3MtBZZM/GRVMa5kfPAPunVTzCJPCk7FOUjcoEiTzebkAhrrm0wf4By8kQbRpkz8SKLc7vEVO06S/1OjiBWX7Wp8QFkp94rKGsG74amTtoZSjKpxQZY3dTuBQOcbbkZiP8LsztPfc7Ec0dxrA7p/toU/Qz2j8/ZzkQqo88J8x7OzhyXH2jTm89EH4vZQ8DWJbJCIMHNADgS8BXsDDJ/RGo8WERg6gp4zmQoN+8kvl+8Z8PWuwKA99ye7zLQmEPDN+5opnER/wXF2va7v6jrc8BP/YFeQd177VifAOj/oOHOPgfwjTXC3tqq+Z1OfraYPeYGHpo2cnWZo2GvJYIzvbf4Hd53Aa9WYj58q/+l913Vd36Y2sl7MauTxWr+ogyKcuAzYE56zN2ZxVl62c6v7HZK2DD2eu7Nt3+cTAwInvnt13JfPw6x27MoMDr+zqgONDg5ldHfThiWvUqQ0bToHReQGhN4aG3lCU5zf//f7e3v1/v3nLe8/19j73nmZD2CSx7xUQlapG3clOS3mCXI6h5wXJc57Y8UqsX+U4HaGTktNKLDhhXTZfm7PfpAKeh4PJzyYj9ZGAYzi9bZUYT+5/TOmd/LJrfdmanruahvnVNMXqWbphdHLj+qfiqaWzLXSkxLdm1/pnyzwsoa0SJbStppqoFJVejGGrwUCtIiQVgKQCJyeBlAEgaTMugELom8l3ehfjSFgKWKUiUqiCANhVxvhQtpAPNhmzvp65DYkbR/6nH9m85dVlXh+AzvsStXfF1glNccETT7rcjrEP9nWq1D/x0KudQP1BlfoPD554/G768JYPpZ1+PchUXkWoPi563FUgqmMOn9fvCNa6S0rc2078fucEde3vbs4YlS+biS77qUoq7cS4u7BJrxAkHzAEEOZxpugDfrBJ1RKIWIdQdu6CUbmBM0QnB6Y1g0bOKD9d0xtK1idj3rq7flinDExeiNSHfVy78t/oZrA5a7nqUHxfZ8cewRssKpjdjaZp0LvUduW7udz1Y7DFSWpAk/SaPC0yd2JbvEKQgudlGzh/GydHcf4HYpOCoy0IUCZx3v9Koc5ZsaQGc8dgkzwg+jVaTcBpnTJ4gkn8S4VNKtUmZLRoCPNLqy7nmmq1toyHwV+cvWCu4qmXzbvf/2Z5tHXv4I52z5MjoY1BfyKOJ1ziW1IDR0YaHz+wfjPXyTvQ4/9u8Ad8wwo8xRJ573j7jlDdmkRHU12gZ4PVZPT68KQKZxXX7ewc+s/3xlcYIxD49z/Cm/kgoQeOp+qAR3nzNUsOvTWJzl79kD15tZU9+aRq605d+4T9FMb5KEGjWxGW4nIixV7IXrwcrsXJRrDVfjgWeoEkOlVyizAJMEux2caJMF+B0WTg/FRbz8SFTya6vzep53zuhyUapTe4y6z6SXRu5/HWbdtaj+1its6cbOhujHoefdQTbexuYFoJ3Nc+ZV9QfRBYcYQNrrMqiDjaOUgXTirb9WD9IAhsu/Kc7pGrv+N89pCb9ZH7vtB/AvdZKQsFUTCSbIJsV30LEj3kSYydL0C8nYGHefv++O0QTR1Rtnx67pe7d0189JHyIDzzV/T22THdg1eP0Ctpt/Ir9OAseA92bZaeY1nfmE/8C/xD3FtoKxo5rYTQ279WXlQOnEZn6eDsJ7REvzD7L3T+7MbsvT1wrwHjBLzAtxJmXEgrexTsUitm99Oj9AfEtSKqB8YPq/EH9k8o7nf6UQ/rnvnfGMuMiTHPXBpnf9T35NVnYex+xYi+IHyuAL9qmCvAFkLcr4vJ+dgj46Ivk1RrsTzE9f796J5MRpEV4xZ97xbqlnVUJn9aYjgZLayjnu29oY7KqHVUdLM6KpC+l2bHZ2d0bd+dzavH7/IAzBtzYYY3SGwsQxOwCcw0IjE5foATwi+naPWgexQ5o2zbkle/5fIkgZm6todVqxdOLcJEjFqFVgOQqNMfZ6mRETz2EBukOd2IWq+mhQy8vBBnkNpgmaLhhQg0G2SFOXRx/LRuREmjDjV/g1d8xXx1Q24iHvoJOrx5QvnpgQcmjyBO+Yb5avY/oleVu+Atp+CeceZDkEZ/Tm7C4XlLRJEZykwFyCrkJhWMmpsUQ25izOYm+VpuYuXU3KSC5Cb8TXKTELJbU6hIrZHkYQehJidqanIKvdj8067Iow+uWae8rTx/KNMRDXhLK/2c01fkCmYyA/fVmB2+cCDYtj7V/7ec+bGeSzPHUZwtcTQFQ60OQwGLTiBPXfuakLFQTwMdt177mvmM+QIiimzMawaceKTOxc5FFFphWDZrE3ZuiHnzfTjmBRzK5wo/yyAnYcAXg23MZiWqCcX2c2vXvvcfa9vdHfFFo8sqNu1dnqhL9O/uDnf7PQH+rs4D60befboLfb351OOrS/ktnN3ERuOJ/T2du9bHzUajyz0ajdz9+GvAv29An7YCLzjgRTYXsQLUHIbaxqiOCyKJPCNxXJRss96Yi8yFENhfIy0N/AYN7X2rqWm1MyCWNb89rrxw8IzYURd11bW2psTRR5paWt9cF3loXbevdeXMcfoDvbXELh7o6X5JCGGbBXAxfQBXAVjf7PyHjCzTUn6M2Nx5xc1NW76hNypRNKLsQW/NvjyG4mPIM6bqMH5eBzwvn8TjRoFoUp55Wi7IxuPZRxzM3o8mx1BojPD1KzbKfE6F53MZoFAQU8jDqAUFnMsYSQlhPpfB+aaJ1MiDNsmfw9eFqYzK2qIc57i199BH2+teXmkOeg62dQbWvbx1Vd3wc73JvxEcQpO4IhD6y9rHPni+B301fPKJux0cW2CA5P89kyE19FR3567+RInT6BnzuIxG02rgMcGd3UtouSB3+eYg/ciBA7PPHUQnlHbmQ2UAHZqjFdoD4xfmLvm5ucs3Bw/CABjrVV5AA/DVCdH6XO6ST3IXucBM6iY3yWG8P3YHSl0ms8vlMB/0+Iw2D69M3+uu8vtsjmBY5JmvZ46veyzKeXxBTUbNBJ4FOQzAMIkOXlDa0YvnAPwixYWm0e9zZEdH4NfPyY42maPmNURUDo4xXXM460JwT3E251BjsgV5zTcH9RYbsvx7FOEKjRNvK68a81gWXO7Zd+hLISE0u5eeCFQFZ75lPpyNeEtcvmIXTWj0zbVv2SFi7+aerWYy8Mi9rKuYDo2Psw7L7McHGc4R8M/WM5/NfO2KWenX1FwF7Ap7AuzKglwlay0XWpa5XMV4+1zl9v0WWzuffnd05Dd7u7r2/vbR0Xef7jycHPxlZ+eegWRy4Jf3dP5yMImmh19/fPXqx18fHj6JjyeHO39JfoVRg0kYTal8Y44C3mbKTS2j0makWnlJJ8guONDYmlsw+CWC5DgvG0FsPFiBOAuG1JHUEhWUnV+YqzKBVfzmoGc01b6tL3pCUo4dnBwZ/HFf8yDaaTBFun7WvG9CEdGajt6eAY7QT3mZ0C8I2QjkI8QgR/B7a9W5DyDbIk6OYXIB2ergGFtktaUNvAcrb5lV5qzJbFSHUxGUzUbgH57QvwURO77nb7yrr7HhoZQ7IjaEuwNiuNLlrvDzjnf/j9sQdui1Nn+ELzJ1PhjiPCUe7sdmp6vIavaUBTwi0p+8A71BE6hC8OOQexRiPAl9fXOtCOWAXL7rhtxjjrok6yDe8ZuDTyI6o1wa2nZySnn14EQ46ncUpuKch48GcK0RHeJe/Nmup5Q61ESzhYZwT4dg5vJpLO+j4AcTYC+XU4OatIogrVVz0poUpBDYS4igitT+F8z5FXAswoXW5bjj5VWdJc9dWbVExHmF0SaVgQCLWsbhtk4Zy0LL8S9aIU/LOEjOodZjq0jSkc05qnDwrSfzJtp0CU44RuMJ333DLHPkzeIVa1vbvr+stMD0yLqG9oAQTAhR/t4fsOzh00Ob0ylxfU93hze2tMdfWli2b0ekvaGe55f4PJzNn2x0mJyeMbfLWLz3sY7t8R7vqmhda7nJxwMdeODHCPAjJ8/g0doJtHbmONOF/2u+6dy1z1kPsaGQZ+g1/0KMKUinHchk52QLTho1u2qxzwWAJI1SfQrONDhdOWPlzzV0JF9oa3seUqIJ5VvlW3QA7d33kuAPhfyRw09DxviycgkhC70O3i1eu8h8qPqGbE6RVxOEb0e70OFJ5Wu9jjYqnzAfzjgggKsz2SxuB/0Wue9r3ctwn5XcN5dE5AVxEiEiqf3Xv+lChyaUjycnx/se3js5obwHD/Ggk0or88WsAY2gHRcvKpuV52k1R8Vx5LtZHzWfQ4gZZEElryq70VBGUa5Rp1APcc9/RJ/iSVqFz977Etybm0OImNCjGWVWUcAcfw5O4gTtBandi/NhGH+MxAI5OcQg0wqJxj0zH9Gds9IY/V3f2KwBxkqKmXHpvqFi1GoqvQinzGGGVFmMDJ7gy8QYqg3HyqIgseel6pjMAb98MbmGBM5GMGQsGA8pRnq1FtlkXzUxwGLMaXUUpVBcC/CsWG6ryCwfnoqBc8xS8rseRubxUvuhv3xmywP+lRxXQBvMBYF4VBSa9bTRyjWVP7Dl6W2H2tG7Xyr1T//VGO9x1yXRi6FEyM8lCgwm41+kOJe7FB1KNRZ5/WPbnlHqLyKS34LHXKP76FZ+3g5e6tRTTymuvDdVOU0oZvpFoIWIaeHAtLADERDcB4d8IWPSaFEjSJHzkicm6/LxrDKe2aPkfDy1p1sMtDBZpcqk5AC/VEpo4cR6CwiTOWP4UkVm9EjUbsUVIHW2Mw/012lVQ8sE4Nu5pr390Lant/T5m64jSQHHNfmVvYAoOrt59Cf0l+isRpWUMqBRxWgEqthcrlKlP4mpotYF0Hq2ju4A2/l3OE+WjGLGRXr4pOIYTvt0olwGmHpjSAoIcpWa8n3187fMpEVWVy0VV0s6TvbaL0vFnGy0Xz457fsvKdIcq+Om9DqjPTyVjz8lLzfl9hbDaSn+TMNnTtOSO5mGUfgb6PiUPt9dSjqWXtXp843F7lKv1sKkZpGyy4Qn5JHqqOCmJIm21OI4M9fxl6cPVoB44fgSjDtXW7eznm8Qom2p5eW9D4ZT4qpInG9u4BuFQaGLb1/rrgwE0Ls9QhxIVGbV8xwf6POXFboQ54y4bAGj3eEFf3NIcaMdrIP0noUpiRHu2NFcmPWjc5NldpHhD7UIeFZMaCnJmA8wL5EZslWrrrSx96rxT++1BmYLOwA62IhqqTSHey0LRbmEnZaWC3JZShTlahYC8sVLYriheSWxm2LBtCRyOLzPmEgvnGTicEiUWaR2xjVp/WVff/sXasZeUC0tqpYKONnkuIzjgZDj8sn6f/y/LxP+FXBTxoKQPayDp0wVmhbZw3O/TXnxqW6qDB+mgvgTD1+Mh0+l8Of80Fp8moYn5bC7NpmGJ5AeNWOBybsoVJvtUXvVWOgtCy5O1eZyXBbVzAf3X7CgTLhnTQpZp7iS6uWkjaAE0mKZLgKBWA4JiMuPY5hqm1RB4j4tfskTE1m3oc58VQXtxFcywQSfR9xlNqApEhnsQXv3QIwe5llDPt/ntzmsoT4+0pTsTD7YxjmsYyEh0OupCgp+f5/fWGDQ9x/b1jYZ6RiqZY36MV+ZZRC9/enfcm6b00zT7N8dpekCI7jIrWGeZumjJrd/G5khO3GMvvvxE/3tY+sT9Ow6h9PSp9odStHrBN0F6gd0IZVeie1OO7AeZAxrYxknLcGBJNjjtKHABBIg3S/Iy3pEMdNNlFe+DwYnQS7WkSYN8KfyD1XeG988PU1U11BtlvSn5SLbZekHp0/WvfeH+/Fls/R9Tuo8Lcecl6Xa0ye/NZzx48s6kBTSiViluyzxp0/+4ZmzAXV4IYib2QA/meUKuKf89Mn8ztPHifzouak8vQHLD4iGqcAMQvH162fXk98quCl/RTlcqXv+64PkSoybEmO1ID5x/KmbWkZOkvhzbtDUCnIxhT8B0Kl7v98Jp134Uzd1HznpwZ9peO+8tKVhQI7s3ZtMw4vwt3hSWpGUUsk0gJLTvd/o1Beai8r5qviKru//IM9fERNTtZ33Vt/sD2oszQ5ellzRdV8P3AAcue09uYJtL7XaphLLV7YTMTZyJNqTl5ThlpBqskpAKk3KK++D8+YWbOespGhO/GQMnESRS6055+Fo0OlQg7xs9Ad2jwxtQHZ/wm/HHXnaPC/pv2PyGF2eH7sZ3C9UXlDXbvS3BKzBFn68dd3O3UbTBKuj9Y80t4jLWVOgmLOYwLGarIYCljYafV1oh6hsy5jdbq+jub8pUTLiCNe2i517RW/IX+F+X1GCiE55Von+1pWKkdXrzByrz9cXlNtQ/4+8qWSRzVPgdXTYOTNDQ0bJmp0G1l+yFi0dp19LdiwPOdoDybsj9QEuGnYLLZt6Z/3uR78cHA24HIbcGirueUIQy+C/ariJ/6oV1aeUL1AHrtpNok5Fgv+fo8lshXXbyDgp6MGB3kHqrDS1k43QJ9kZ0tdSg227ZBGxeXeAIXXGcEcLXkEABj4GF/RgNMGy2siZ1tiSa+R1Od931odDdXWhcD16uE79VsfuU69kf8E9pV1UB2uE5FynRqbxCIqrn13onPLfkKUEDpcgWD2nbD9y4cKksk09Xtd/Sy3osMW/7WE7Aa8P4DeP2pvLTM+HPubpnMbcPbQw+wHbOab6oGyfM4OzeLXklNPtzLw3E5/veB5Bu3Gv9BbUpxzBvegdzBX6LVI/LqbSNNiv6yusS6NItPOoY/zLV5gruLCKkE/x0seufQF3LKUgYc44GWo5vsMtSLbzGYPqw0rwXI3NiiuflOzUaR2HCPt9Qm2w5XMJcxD5wqkI7+jZ1NnWODiysq1xaYWvNam0m+0GdqhrTefPTgcEf9hZrOI7DPQPZemfyEfOQhp/oGH0vytLcT0XTaMPFAGZlUsdaAztmLxw4Yh2JPdPKC76E4gNcB/O3ZRkF+RiMMO8oDXjZItmOFrmOJyWag05pAunHOu+HdI7yPSKXA5iD/hiuObU1jNoCTjuAwAGOLG3AsVFOWI2EVq9aaUH99yIuB0HAvwEaccJOIQgWp3tY9rUeWjX5oDZxXGGA6Y1I88/EF0loA2f6i2lzsgw/U9znVaM2oOjP0o67c05lW6XGFzQifPb34+fHc5246DUpUtXt5OOnIXPMC54hgchMcEv6OZR/mnvl6/ktvQwey/lPGMMnmHGuVf2GUExAZAsbAp6Z8+BQ3unx17OQlPxxBPfXJ3U+oPU52zDq9yoKJWksDtdDO40GJsqX8wZwljgyOqVmCCLpCjjJO3xUrlVNpSANV6MpwFxCUEFIODKmtSibNCpFq9JHw0wx0PPQ6b800pXid1s9Ac9IWGovfWuYIhv5IVK3umu5kOCz80ZrE113iUDWdAnHzBbjfksZ3Yn/FyJv8tdyuk5m8NTyNK0z+S5ekmjMavhtRXwsoM9rKA6KalAkErEjFW1XeUxMjduOJ8xq7bLzOGcOuNVbVclSJ/ZYLWl82gHDpxcVpA5yWtL65miZFKtmWgUz12WR+f2f83j+X49WDewcvXtn17YVR8Op1JhsHsEo/+gmbqrXxPuXsxavnkcLhE5wTj0UZJZyJSD+QB4S4SMg3wjeBScz7jU6NbF4XUmGatqGTAergJSqZe81nS+w4yxUcsGcgluU7YWJHPYh2UwBwVXtpkUWLhQLv92/armdeuam394d00FH43yvJgrpWyA/Lj+R6t4UeThd2wLrn1KUbpvwf5xwBOKF+1z5XpSEWGQlX/rNHqKYWcPoEuQYvbN5m+4iDrxc7XOo5nf0ZnZNepctuIhvV+rqDEqXY5rJYv10+kG0mKgx0sOMjbNUjbnNhtYgDSl6tKqFlxBESDU0BW5fbiIVGoFka9pIFbG5gYaFWEpTxc4S5NEztNGXRX+VgPhdDCBvzXgKtVcf4Irx8jmkbA6XhNGiQWrrW7sK1s+8PQD7kXhOD/a2N4gBLwtK8T29dH+zb+ytxvWPhJMxW/ba7bpnaM7QkaryaB/V7XaQx7HYM+hn3uMruI79Z4x02CDCub9mPrfDvZjQdfXMxfHT2v0R/2XLt3u3gCYrwX3op6nLma0m396af69Y3CvbeG9CdVyLbh9dPehA898NaY94C6wW8T2qc/YRmISnlpNSRZB8oi4yRZrth80u1KQTOe1OAQ3MxTjFXWqZgdwPwPkylNsnoHBaxfLivGSKF3y+jmkxC0ClwUQbsFajbUbbQOdrq0F3dagPYfjGFXTyRFwT4LgHge6qT2u2GOIVj755fhpy+Sk/uilS5dx8Abj3oaP5Nw4oCke9/b4xcyRyUnda9owGIcXMwwCLfV4ztWuWX4Y6lINvhdGPw00u7ydjGfwugc6BTYR881DtZFozj4Xzblj2vq4nGiOA7oVGag6oJs3dzmyXISTS/PN0ngrn0u4RK1Kg9rJycmnUur3lJ7TrNzlt3Vtv5mP9Ui/l34jwNaEPVGlINczeLHyVE19JXiikOaJVgm4V4iSK3GV2Iv1US7FeUG9TRKyUwW3aBVLEO+UIPNsN/VOt+kle+OOvooDXxW5XcvZqT5wXwaWQ5biBPJzHuzArHrO7vCY4E1lJo86U0960oD/6pre782vpNK60vLm5hqv60qL5KzLVZfi/isb07BQ3tic1rkrM5BtThvI7OrMXHzyzM0b1Ibfeba399l3hvGxZ/877AjYi39LfHA8dWd80MugW38SQsyOeXzGCD7Vt8BHuBk+S3PwWfJn8UdV8juj9M4vD048/X+N/WlIrSWGNYtXP8Grg3r0JnhJSwW5HXTye7GpxvaloJNxTSfvuRm6nTnorliIrrw0DsobSkqNVnnRClDedpuU+pOFdC7EvLkS35k8P25yldgsWJcXCUOrs7oc4B1uAXS5TIs7I38a+d7VtNo8p9Re7jqlZjXaPkZoK1IN1JabUTcsSAkxE1XtcV2MrCeaJ+siMMbVqmmu5vDEQmaFerZinuR4PVFNNSa5m9f9WRJ2C693Z5qemkvoX8q6wj+Nfp+psXE2Rq4nNrD12oTuTd0p8O8ClcLzhwZMraRuOu3G1Arp1GnbsvNyJVCnktBDLjSo07aVuFaEeBKrnaANdje3ZCmO8AptpDJOyaGk1XaikCvj6UgU/+C2Qpq5NOpDCVIsVykUTATzcBsmJhPeMMJl14I3VI3sZAIRk6yqdfV7rrp1ax9c+cLMicHB/lNr3jSlHujpS75w5cSAOdgQs3XuTPeveTE5u1ZIHqUnG9Z07koP9D4bbJi2hZeXFWw4ieiJ/Qht+Hjlx/n8Erdx6O+UKwebh4eGW9Cnw795obdenLnS8LpykrE2vz+0+bfP9a7Evp/0JIJN9VJ+vN6IyJJDp7bpgMh4CqYlz3xXIm41LfRAOqMrK08mb9GZGNT6EhGYmIW9iUPpbGdiANLam7QnjqBsfyIJEf/HwoejzFvB9+txSJdvBx+OQufhGwP4KhfCF7gZfFXz8FXcET4tkr0FiN/tOYQt822BJJEuo8G4HWAMUfG59YYAJV7TFREzQdVQiGAoluVCjXfxqFRNAyjGYjhbSmI4aek8Rgm8sUSl2qcq+7GRNhWUerX1hrdG7RbW4Ra4/j5rCNCL2djvtnh/oI7O3pUCGpC+Qt3IDfUWu1iAcrsLj0CWsiHbYYh24zLmTInWZzj/jBvrLXZ+QYei8g0WoJw2RXo/6qQWPOPGeguzsNHxt3smDj71+7HRLDSpCxfmgKHmn6X//7LmMg+d8vc3930VTrdQEVqa9X1L/lMW/EyfmSswaDWX67ybz1Qy8w8aYqyKFzvz/17NRdY7k7jqIuOiy59Uc5nH8+2sT9k4eaRrzjURjP6TlnLMfIBBZ9jcmovKm6G5msv96gx3pkStuszVX25XdZGMMYKM12W1ZfL0+Q6zOiH3ryq3LBTLN24st+QIKbNM/XF9TrkFbBx1TdGxpKfTTlHOG+otdmv6RbSGHlJENKLsRm/Pvtx79F9o5FC+2qF2TM6+i95UmtS5t62Kn/S0NlF/TaW92A6FmOl0Pe7lqQHRLRIyhVq9RVvcYST1FiMQxa2WovD6DiNe2qzTW4tKa1S3m/aG6sni3sIiEHErKVLpObe68EvW8Vq5pXJFUk3wUtlyy4Jay1ydOzuTeet+2YbRoxtGG9obBFz0FrOV8PamSEIIrRDu0EY78L/u6DX/Nhjxh+3Fg2a7kd3Y1d61xWA0Wh136K1l+sB24Lybp7Kz4tkuVqvWxZpmTObkDVUI3Gq9oJtVAEOndbSil7X26//OdyTACi54xx+evJjR3tGFzd+C59vI8+0Lnu+Yfz53s+cTI7ngFbY9E4f2/n5Me0s3NpHENpL3sN/9G9V2FoBYcuMMlQbuqRvnqfACvlOkdz6PooBpBbj00Aa8Mh08qLbJX8GttISWv4WPhuxYOxAfF21+u/di5uDBg2wAdaojaYicKHozjJuv7zBkqH/PxIFnvtpeBKODmHDqeAZ0k6KbyVzdv7K+E/uz6ztNWcocP3hwZ9bizs3jXW1iPjw9TyPS/wp+z0Itw16vWJBjYDqE2NSiWDF4Pa/m9RKCvBx7vWKvahIWWWWuAvdOqStBr2+dTdzJ+13XWxu9sY7TgHM/rY5TbFXrONe34L5/ezeI6U/6c7X9b3LqHAs6dJfcrEP3DnWO2zfpYgtx50bd/otPnrljsy5zQTMo/1a44HjsT2g6LgX7dEdk6D3EdF2HS/UtcBFuhssd6jV32tCOKOyd0Vmvxot3RmicWMksPizgs4LqoLZr+LRn8WnEvWmCnIBDTWwqkvCCblUsqNOkAM0Uh2dAIOYkmOJSTYoiM6tSi/UVS1HFooRaP2hsz5ZsvBXqnEjEKjuDoI8Jm7ToJnSw5d1eIfXMnbrMz4q5IWp7a3twkaqiC8szq+/YjE4Pli/U2nvJhOGc1s5yN3RP4xiQ0Bfs6A21mhyJuWWtxnjrWk1dTq3GeMdazR2k6xYe7M7iVppNsdB/nUvK7ih6l6/3eCSPuTbNisznpBfCQ9Wr+yFlCvNwuJd2460P7dokfynpiuViGaOBKgEqFMXIZniyvRA3LdIEYdyicotNUMg+IGhPqxhtbY2KrdkjOjqirNJO6Y+jLS1wrYXox2Hgn5kqoQLAv0e12pEA3CvC3Ctn5rae8QC36BjOmSFLxrvNFRrVDWg82BMyLM61rK/oDPaiiqoFBSTBgJvrILCAnOyVQo6q4IP49yL43a6yz5XnSswtWcClJDUAJXxchktIrrkSEqjA0bG6XXXPPjjyzt6uvo5H6n/c8EL/iMq8JzpHBxRHNHEY/XMknhx44m6fEF2Opj/71X7xYLgKeLZpy7upHcL2cJjw7QlQg6bZN4Unv6EbQ092dO4eSOlNbjXuIP3lYAedlBssR06HecnNOsw9cLRTqspbrFN6V7Fb3S/m5s3m2A3d2HC+98vxM7doOs9Gr38OXLjzfUpf5MIQ4T7i4lvDFQCXcpNG+DXj4EJuDpga8i6Aq5RamQuX92ZwlS2gV0bvcntKCXg2qeTW4Gmx8Y0Q7sYB8lfbbwGjFjAzKozsFbLOPIJ9QRZK3CEUEDM+1UCFY9mtNgDqqSI7BT6hVLVP8yhMLTJZsK9QLVWFkFmkTv0J8HMpUFx2+5JkmaUeMLTJgTBZTmTFe8A5IFFP3hLHW9iqG5HeNVcw2jRnm25OgDdvMEhqXeUlVqEMZBekTtK7XSxmbCoJymJkL6T88xmLiriFw1ti4p2RYtrOSJZ8wIU2IJxsOq1pNo/B3zzZRRbZNQXBW+CTs9aAm5sXHsyCuHD5wVs5BW981Pai0F/S9YPdEqhGzeeEdWC1cMWb7OawVLVahmm8PJ+CH4EphnxihaYoI2dVbZBkmy/2L0vkpD3X1fxdVnUz18GHpH9+IrTte4x99rnsxHbbX4Z2fy099HrH7tc2eJdEon5fNCyUbnx9dwd9eJ9y7c1NFpM20W0y//jX16h9I7/Z38Ma7KYZvdlqZHvw7hTqmrUv9AHmImh2mFql4RQES+zULHHarq0Gy4aTJdnlk8E55DiMXAmfsxnaAqyqVLua3QpGW1C5tXP3yU2Bn7bSHygi2qKMozOzqe1tw2f3dh9eVZva0Z/6+T3dO1ev2b2hDl0Yen1Xh8W0HSW2I36b7d6n3vxR+/54ImLmZrvdzvqNT2h9Uj36UU22Vv7rZctpAZPFsHnapltzwnQr5chZ/B4GPQBJAV34VVZmFq6H/831MyiIGmOu0B/o2sjeW6qJGVObKZgrWq6NKJGNMA2Qj1XhbMwg4FXWki82VVxhACtQqEWMQQEHM5RsKCSLv6Viq0zZkmSTB3syu6nlbbKvPy2Wi7Av3Sm/un0/55/7m4iOsiLtg9/sC/pA5/s/1eDj6IjWg46OGqhbjsfiaKC+I8MRNcF0kf18HHgfVzzJl6G1XW6d6roIHYmG5CKtUZas9Vb3KOTJSpeJn/NRvpfV5xv1ePs1Tzhk4piPdphdFxxeT5krGOZrOr6/NIXh2sZsREO69eAHeHUXmIzxZjvqzu0ldOudbc3W+Z1tdSn1TaEQX7OmT/DWuHeYVTr8/3//Xhr4183QZL+MAFWmclCqEDUmSg7Q+SpBDs4xr54G7pFOdN6MdDkXGHxh4uec213u6jMUGs3O4qGmFvTvRuFKmbvPYCowGE1W01DDXczHO2hDoelCSPBHwoGhM21zpzCwxD74lrrXH7OJ/lzbswjg0mO4SsQMmodrkZDdc1ZU8TbTeS7c1M7orr+wbbCp5dF5QEwmC9pELnncvqI+Y4HRYCzkmE2DZzEspkIVlmKPbej0/AVXWYmH7EH4Cf05yISd7IQLUiF5xYxFhYrPhSqhvjpvDhbd9Re2ZYExZcFD67PAmLLgTV4IRXhXmafYPvBW207aYDGpwAClhn5NLqiy2kV10H7Sw0wt6B3PNo3jMcMwpkEdk1jY4Nwx386M9R/ve8Z8DPq/RN0lQf1A4MW0LUEyjIXKY8PaIbvNhtVvxffNhP4fx54ERAAAeNpjYGRgYADiG6L2FfH8Nl8Z5DkYQODSHuMqGP3/7j82Dga2T0AuBwMTSBQAO4QLzQAAAHjaY2BkYGD79PceAwMHw/+7/3M4GBiAIijgMACh7gbweNptkjFoE1EYx/957921FIeji2CVVnQQJFOQ4CRIK51qUCihg4OFG1wKLiWlKTiIg2QIRcFYB8Gl0KFD6FAyFRyEQqEIneqNpdDhEBwciv6+awJBe/Djf3l33/e+/N65M02Lyw24ri9hRmm8r0eR9MadlMbcicpBqoRUcy6o6e5p3jm1/IzqrM/6c22Rdv8CqpDCMnThmf2296FJjxpYr5qvU7enJOwqC0dKo23yMZSVRZvMcFeZSwuuhLYy/0vZSKwsHodr7PGyn1vUMDO1SfRBvbCpJD6l7zqksMe80nubl5xgHvlEG2FKFXr2yEbIlPtD6CoP52pEa8rdCjzVDXrnflU5e+VRHcpqUFdkYM3vaNm/061wqoMQqxJ9p+9vOOR/jitl32327ZHVsMA8F543fAtnHyWb0T/Q67CiJ+aW+7fm2ielOd8qTbK+hKtO4eoS4oU/x+avcDcE3u7DV7gK1YG3/7jNWeNtGHNzGdEq8+KrcDUErmbhG9yEhwNP/2JnX6S5GsJcjdSZ5VPxTuK6euU/47AhxT85r366mlTqwZ0L9INcJJ/zzL7LPrbPqHkO6hTfLPg1dcCyaTWuje+2lqyfP5L+AhzMpBYAAAB42mNgYNCBwgTGECYRpifMcsxhzDOYN7AosdixpLHMYvnFKsaawvqOjYctie0BOxf7HA4JjgiORRw7OM5wPOD04kzhvMRlxFXBNYFrCTcPtwq3FXcGdwP3BO5D3F94QngW8SrwZvF+4mPj8+PL4pvFt4PvAt8zfi5+B/4U/ir+GfybBOQEKgSOCLwR5BLMEmwSnCF4SvCR4B8hLSEvoWVCr4TjhBeJqIlYiVSITBHZI3JL5JMoh2iZaJ/oP7FpQHhK/JRklGSL5BHJR5IfpHiktKRcpFqklkjzSOtJB0iXSD+QcZJZJXNBtkC2T3aN7Dk5LTk7uSC5LLld8nbyyxT4FKoUNRQPKAUoLVD6oOykfET5mQqHip7KLJU/qkmqHWpqahFqHWp71CXU9dSd1KPUV2lIaTRoPNP00/ynNUnrnnaW9jYdJp0QnVu6VrpL9Dj0EvSK9E7hgDf0nul90efRV9KP0J9gwGTgZzDL4BkQ/jDkAUI9ABO9dOIAAHjaY2BkYGA4zBDHwMoAAkwMjEAsxgCieEECACADAVMAeNp9kE1KA0EUhL92oiCELF0EF3MA0Z4YApplwEVAECdglkYdJRImcRIXehCPJP6cwGt4Aqt/IhghPF5Tr7peTfUAdV5IMLVtYF8dsGFXU8AbNOhHnFAyjLjGHq8Rb0rzHfEWTbP0eWPHNCN+xxob8QcNcxnxJ3VTBvyVaPeZHlNmVEqQcaQ6JOWUkZgFYyUI071UU3E515om6lxdMtd9T2gmdE7BHY/+tmKgDooBT7ovpGypz6TvrvXpYlWZEllfbm5zoGRWp/UJMzHHQi2dbTpr/dKVZH/d/28u9y60dcWt3l3qX6Rxx7E3mvpe7diQxyVxviGPe6ubOtIW8hj5ry9UDlXqOSe/zjkPYsbiK6knP3r5S/oAAHjabdDXb85xFAfg51vV0mm19ow937e7dpXae2+lk6JaRW0Jl4RIXBtXJPYMCReIvWIEF/4Vmr6/S5+bJ+dzknNxJGnP3wI1/pfnhKTQQQfJUnXSWboMmbJk66KrbrrrIUeunnrprY+++ulvgIEGGWyIoYYZboSRRhltjLHGGW+CmLg8+QoUKlKsRKmJJplsiqmmmW6GcjPNUmG2OeaaZ74FFlpksSWWWma5FVZaZbU11lpnvQ022mSzLSpDsitOOuWCM66Gjn4777Q/rrnsujdeuWGrbc6q8k6119765L0PPrZ946vPvrip1jk/fPNdne3q7bBTg10u2m2PRk2atdhrn/0OOKjVIUcc9sglxxx13AmP3XLbEz/9CikhNXQKnUNaSA8ZITNkhezQJXQN3UJ3d9z1wEMv3HPfy9DDU89CTshNqW1obayLp7bsqo/FYjMTlsUi2+e8tkVkPDIvMj+yILIwsiiyOLIksjSyLGE8uhuPp9XU17Y0VVdVNtclqryKhIUJCyvK/wHOkXdQAAB42j3LrQ7CMBQF4HbdurI/ELMkRV9JhkTRJWSGYGgTngMLBgmW17hFEV5u3ECpO9/JOS8+XpHf2IBqZz3nd+d7CXaBMzdgu6dwcXOUcLQMhTYoYIOpNk9xSOCLjJD2AZKQrQJygux+4KjCuaJWPRLwoj8RS2K1jSyI5TpyQiyWkbU2b6bOI4tNQ4M6j5wSm+5Phy18ACcXQFIAAAAAAVaWgvoAAA==) format('woff'); - font-weight: normal; - font-style: normal; -} - -/* Fancy First Letter */ -@font-face { - font-family: Solberry; - src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), - url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); - font-weight: normal; - font-style: normal; -} - -/* Headers */ -@font-face { - font-family: MrJeeves; - src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), - url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); - font-weight: normal; - font-style: normal; -} +/* Main Font */ +@font-face { + font-family: BookSanity; + src: url(data:font/opentype;base64,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AAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBAQ1Cb29raW5zYW5pdHkAAQEBN/gQAPhPDAD4UAL4UAP4GARADAO9DAT7Avtr+rX5zQUdAAACkw8dAAAD6hEdAAAACx0AAEzGEgA2AgABAAYADgAWAB0AIwAoAC0ANAA6AEAARQBMAFMAWQBfAGQAaQBuAHUAewCBAIYAjQCUAJoAoAClAKoArwC2ALwAwgDHAM4A1QDbAOsA8wD7AQUBFAEkATMBQwFOAVYBXgFsAXoBiQGVAZ0BxQHRLm51bGxub3RlcXVhbGluZmluaXR5bmJzcGFjZXplcm8uMW9uZS4xdHdvLjF0aHJlZS4xZm91ci4xZml2ZS4xc2l4LjFzZXZlbi4xZWlnaHQuMW5pbmUuMXplcm8uMm9uZS4yb25lLjN0d28uMnRocmVlLjJmb3VyLjJmaXZlLjJzaXguMnNldmVuLjJlaWdodC4ybmluZS4yemVyby4zb25lLjRvbmUuNXR3by4zdGhyZWUuM2ZvdXIuM2ZpdmUuM3NpeC4zc2V2ZW4uM2VpZ2h0LjNuaW5lLjNwZXJpb2RjZW50ZXJlZC4xYnVsbGV0LjFleGNsYW0uMXF1ZXN0aW9uLjFndWlsbGVtb3RsZWZ0LjFndWlsbGVtb3RyaWdodC4xZ3VpbHNpbmdsbGVmdC4xZ3VpbHNpbmdscmlnaHQuMWh5cGhlbi5jYXNlZW5kYXNoLjFlbWRhc2guMXBhcmVubGVmdC5jYXNlYnJhY2VsZWZ0LmMyc2NicmFjZXJpZ2h0LmMyc2NudW1iZXJzaWduLjFkb2xsYXIuMUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxCb29raW5zYW5pdHkAAAABhwCoAAEAAgADAAQABQAGAAcAaAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAq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AAAAAP/mAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/8wAAAAAAAP/z//3/9v/4//MAAP/2AAD/8wAAAAAAAAAAAAD/+P/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9l/7f/xv+wAAAAAAAAAAAAAAAAAAD/rQAA/6j/6f/9AAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//j//QAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8wAAAAAAAAAAAAAAAAAA//sAAP/7AAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+jAAUAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAD/+//7//gAAP/7AAX/+wAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/uAAAAAAAAAAAAAP/4//v/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/yQAAAAAAAP/4AAAAAAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6QAAAAAAAAAAAAAAAAAA/+wAAP/kAAD/3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/4gAAAAAAAAAAAAAAAAAA/+cAAP/f//j/7AAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAP/sAAD/ywAAAAAAAP/4AAAAAAAA/+kAAP/LAAD/8QAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7//sAAAAAAAAAAP/7AAD/+AAAAAAAAAAAAAAAAAAA/+kAAP/2AAD/8QAAAAAAAAAAAAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+m//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/6j/+wAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAr/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAAAAAAAAAAAAAAA/+cAAP/Q//b/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAP/hAAAAAAAAAAAAAAAAAAD/sAAAAAAAAwAAAAAAAAAAAAAAAAAAAAD//QAAAAD/8f/EAAD/2P/x/8EAEP/9AAD/7AADAAAAAAAAAAD/0wAAAAD/xgAAAAAAAP/4/90AAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAAAAAAAAAAAAD/vgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAD/5//z/98AAAAAAAD/8wAAAAAAAAAAAAAAAAAA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AAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAA/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7cAAP+3AAAAAAAAAAAAAAAAAAAAAP/u/8QAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAFr/5wAAAAAAAAAAAAAAAAAAAAAAAAAAADcAAABEAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAPAArAAAAKAAAAAD/3wAAAAAAAAAAAAAAAAAAAAAAAAAA/+L/+//LAAAAAAAAAAD/8QAAAAAAAP/s/+IAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA/8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/60AAP+1AAAAAAAAAAAAAAAAAAAAAP/k/8EAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/iAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/+/+7AAAAAAAAAAD/7AAAAAD//f/i//IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+L//QAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAA/+5AAAAAAAAAAAAAAAAAAAAAP/9/84AAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAP+6AAAAAAAAAAAAAAAAAAAAAAAS//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8sAAP+/AAAAAAAAAAAAAAAAAAAAAP/4/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/+//QAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+kAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8kAAP+3AAAAAAAAAAAAAAAAAAAAAP/x/8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/nf/zAAAAAAAAAAD//QAAAAAAAAAAAAD/+/+5AAAAAAAAAAD/9gAAAAAACv/4//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/3/+3AAAAAAAAAAD/5//xAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP+3AAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//4AAAAAAAA//sAAAAA//AAAAAAAAAAAP/4AAAAAAAA//YAAAAAAAAAAAAA//0AAAAAAAAAAAAFAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEAAgCaAAAAAQACAJkAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQACAAMABAAFAAYABwAIAAkACQAKAAsADAAJAAoADQAOAA0ADwAQABEAEgATABQAFQAWABcAAQABAAEAAQABAAEAGAAZABoAAQAbABwAHQAeAB8AHwAgAAEAHgAeACEAGQAiACMAJAAlACYAJwAnACgAJwApAAEAAQABAAEAAQABAAEAAQABAAEABgAqAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAEAKIANQANAAAAAAAAACIADQAAADEAAQAAAAIADgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoACgAAAAAAAAADwAAAAMAAAAEAAAAAAAAAAQAAAAAABAAAAAAAAAAAAAEAAAABAAAACkAEQASAAUABgATAAcAAAAAAAAAMgAAAAAAAAAIADQAFAAVABQAMAAJADQAIwAjADQANAAkACQAFAAkABUAJAAWABcAJAAYABgAIAAYACUAAAAAADMAAAABAAAAAQAAAAAAAAAKAAsAAAACAAAAAAAZAAAAGQAAAA4AAgACAAAAAAAAAAAAAAAAACoAAAAAAAAAGgAAACsAGwAsABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0ALgAAAC8AJgAMACcAKwAhACwAHQAeAB4AAAAAAB8AAAAfAAAAHgAeAB4AAQAAAAoA3AFmAAFsYXRuAAgAIgAFQVpFIAA+Q1JUIABaTU9MIAB2Uk9NIACSVFJLIACuAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAthYWx0AERjMnNjAExjYXNlAFJsbnVtAFhvbnVtAF5vcmRuAGRwbnVtAGpzYWx0AHBzczAyAHhzczA1AH50bnVtAIQAAAACAAAAAQAAAAEAAgAAAAEAAwAAAAEABAAAAAEABQAAAAEABgAAAAEABwAAAAIACAAJAAAAAQAIAAAAAQAJAAAAAQAKAAsAGAAgACgAMAA4AEAASABYAGAAaABwAAEAAAABAGAAAwAAAAEAcgABAAAAAQIMAAEAAAABAiIAAQAAAAECMAABAAAAAQJsAAYAAAAFAqoCzgLwAxoDPAABAAAAAQNWAAEAAAABA5IAAQAAAAEDmAABAAAAAQOiAAIADgAEAJ0AqQCeAJsAAQAEAAQABgAiAHIAAQFoAC0AYABkAGgAbAByAHgAfgCEAIoAkACWAJwAogCoAKwAsAC2ALwAwgDIAM4A1ADaAOAA5gDsAPIA+gEAAQYBDAESARgBHgEkASoBMAE4AT4BRAFKAVABVgFcAWIAAQCqAAEApgABAKMAAgCFAHsAAgCGAHwAAgCIAH0AAgCJAH4AAgCKAH8AAgCLAIAAAgCMAIEAAgCNAIIAAgCOAIMAAgCPAIQAAQCnAAEAqAACAJAAEwACAJEAFAACAJMAFQACAJQAFgACAJUAFwACAJYAGAACAJcAGQACAJgAGgACAJkAGwACAJoAHAACABMAkAADAIcAFACRAAIAFQCTAAIAFgCUAAIAFwCVAAIAGACWAAIAGQCXAAIAGgCYAAIAGwCZAAIAHACaAAIAewCFAAMAkgB8AIYAAgB9AIgAAgB+AIkAAgB/AIoAAgCAAIsAAgCBAIwAAgCCAI0AAgCDAI4AAgCEAI8AAgAJAAcABwAAAAsACwABABAAEAACABMAHAADAF4AXgANAGAAYAAOAHsAhgAPAIgAkQAbAJMAmgAlAAIAEAAFAJ0AqQCeAKcAqAABAAUABAAGACIAXgBgAAIADAADAKYAowCbAAEAAwALABAAcgACAC4AFAATABQAFQAWABcAGAAZABoAGwAcAHsAfAB9AH4AfwCAAIEAggCDAIQAAgADAIUAhgAAAIgAkQACAJMAmgAMAAIAMAAVAKkAhQCGAIgAiQCKAIsAjACNAI4AjwCQAJEAkwCUAJUAlgCXAJgAmQCaAAIAAwAGAAYAAAATABwAAQB7AIQACwADAAIAEgASAAEAGAABAB4AAAABAAEAFAABAAEAVgABAAEAVwADAAIAEAAWAAEAHAAAAAAAAQABABUAAQABABQAAQABAEcAAwACABIAGAABAB4AAQAkAAAAAQABABUAAQABABQAAQABAFEAAQABAEcAAwACABAAFgABABwAAAAAAAEAAQAWAAEAAQAUAAEAAQBHAAMAAgASABgAAQAeAAEAJAAAAAEAAQAWAAEAAQAUAAEAAQBVAAEAAQBHAAIALgAUAHsAfAB9AH4AfwCAAIEAggCDAIQAkACRAJMAlACVAJYAlwCYAJkAmgACAAMAEwAcAAAAhQCGAAoAiACPAAwAAgAIAAEAqgABAAEABwACAAoAAgCHAJIAAQACAIYAkQACAC4AFAATABQAFQAWABcAGAAZABoAGwAcAIUAhgCIAIkAigCLAIwAjQCOAI8AAgADAHsAhAAAAJAAkQAKAJMAmgAM) format('opentype'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: BookSanity; + src: url(data:font/opentype;base64,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AGMAZABlAGYAZwBoAGkAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBARJCb29raW5zYW5pdHktQm9sZAABAQE3+BAA+E8MAPhQAvhRA/gUBEAMA70MBPsb+4j60/nqBR0AAAKrDx0AAAQCER0AAAALHQAATR0SADcCAAEABgAOABYAHQAjACgALQA0ADoAQABFAEwAUwBZAF8AZABpAG4AdQB7AIEAhgCNAJQAmgCgAKUAqgCvALYAvADCAMcAzgDVANsA6wDzAPsBBQEUASQBMwFDAU4BVgFeAWwBegGJAZUBnQHFAdYB4i5udWxsbm90ZXF1YWxpbmZpbml0eW5ic3BhY2V6ZXJvLjFvbmUuMXR3by4xdGhyZWUuMWZvdXIuMWZpdmUuMXNpeC4xc2V2ZW4uMWVpZ2h0LjFuaW5lLjF6ZXJvLjJvbmUuMm9uZS4zdHdvLjJ0aHJlZS4yZm91ci4yZml2ZS4yc2l4LjJzZXZlbi4yZWlnaHQuMm5pbmUuMnplcm8uM29uZS40b25lLjV0d28uM3RocmVlLjNmb3VyLjNmaXZlLjNzaXguM3NldmVuLjNlaWdodC4zbmluZS4zcGVyaW9kY2VudGVyZWQuMWJ1bGxldC4xZXhjbGFtLjFxdWVzdGlvbi4xZ3VpbGxlbW90bGVmdC4xZ3VpbGxlbW90cmlnaHQuMWd1aWxzaW5nbGxlZnQuMWd1aWxzaW5nbHJpZ2h0LjFoeXBoZW4uY2FzZWVuZGFzaC4xZW1kYXNoLjFwYXJlbmxlZnQuY2FzZWJyYWNlbGVmdC5jMnNjYnJhY2VyaWdodC5jMnNjbnVtYmVyc2lnbi4xZG9sbGFyLjFBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsQm9va2luc2FuaXR5IEJvbGRCb29raW5zYW5pdHkAAAABhwCoAAEAAgADAAQABQAG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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/+wAA//v/+//7AAD/9gAA//sAAAAAAAAAAAAA//v/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5gADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//MAAAAAAAD/8//9//b/+P/zAAD/9gAA//MAAAAAAAAAAAAA//j/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/Zf+3/8b/sAAAAAAAAAAAAAAAAAAA/60AAP+o/+n//QAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4//0AAAAAAAD/7gADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//MAAAAAAAAAAAAAAAAAAP/7AAD/+wAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/owAFAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAA//v/+//4AAD/+wAF//sAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/7gAAAAAAAAAAAAD/+P/7/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA/8kAAAAAAAD/+AAAAAAAAAAAAAD/2AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+kAAAAAAAAAAAAAAAAAAP/sAAD/5AAA/90AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA/+IAAAAAAAAAAAAAAAAAAP/nAAD/3//4/+wAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//f/7AAAAAAAAAAD/7AAA/8sAAAAAAAD/+AAAAAAAAP/pAAD/ywAA//EAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//7AAAAAAAAAAD/+wAA//gAAAAAAAAAAAAAAAAAAP/pAAD/9gAA//EAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/pv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+o//sAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAK//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAAAAAAAAAAAAAAAP/nAAD/0P/2/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAD/4QAAAAAAAAAAAAAAAAAA/7AAAAAAAAMAAAAAAAAAAAAAAAAAAAAA//0AAAAA//H/xAAA/9j/8f/BABD//QAA/+wAAwAAAAAAAAAA/9MAAAAA/8YAAAAAAAD/+P/dAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA/74AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6QAA/+f/8//fAAAAAAAA//MAAAAAAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAACAA0ABQAFAAAACQAKAAEADQANAAMADwARAAQAHQAeAAcAYgBiAAkAZABkAAoAawBrAAsAbQBwAAwAcgB0ABAAfACEABMAkACcABwAnwClACkAAgArAAUABQABAAkACQACAAoACgABAA0ADQADAA8ADwAEABAAEAAFABEAEQAEAB0AHgAGAGIAYgADAGQAZAADAGsAawAEAG0AbQAHAG4AbgAIAG8AbwAHAHAAcAAIAHIAcgAFAHMAdAAEAHwAfAAJAH0AfQAKAH4AfgALAH8AfwAMAIAAgAANAIEAgQAOAIIAggAPAIMAgwAQAIQAhAARAJAAkAASAJEAkQATAJIAkgAUAJMAkwAVAJQAlAAWAJUAlQAXAJYAlgAYAJcAlwAOAJgAmAAZAJkAmQAQAJoAmgAaAJsAnAAbAJ8AnwAcAKAAoAAdAKEAoQAcAKIAogAdAKMApQAbAAEABQChABkAAAAAAAAAAQAZAAAAAAAkAAAAAgADAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAAlAAAABQAaACYAGgAaABoAJgAaABoAGwAaABoAGgAaACYAGgAmABoAHAAdAB4AHwAgAC4AIQA4AAAAAAAAAAAAAAAAAAYALwAHACcABwAwAAgALwAxADEALwAvAAkACQAHAAkAJwAJAAoAKAAJACkAKQALACkADAAAAAAAAAAAACQAAAAkAAAAAAAAAA0AIgAAAAIAAAAAACMAAAAjAAAAAwACAAIAAAAAAAAAAAAAAAAAKgAOADIAMwAPADYAEAArABEALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgA0ADUAEwAUABUAFgAQAC0AEQAXABgAGAAAAAAANwAAADcAAAAYABgAGAACEjQABAAAEj4TdgArADYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc/57/8QAPABIAEgAS//j/+P/pAA//4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+IAAAAAP/t/7X/yf++AAAAAAAA//gAAP9i//3/w//7/7r/3//7//j/+P////L/8/9q/+n/7v/4//H/4f/dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//f/+//3AAAAAAAAAAAAAP/8AAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+4AAAAA//P/8P/xAAAAAAAAAAAAAP/7AAD/8wAA//0AAP/8AAAAAAAAAAD//P/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9D/+AAA//H/8f/YAAAAAP/eAAAAAP/7AAP/6wAA//0AAP/7AAAACwAAAAAAAP/7AAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/7P/rAAAAAAAAAAAAAP/3AAX/+//9AAD/+v/zAAAAAAAAAAD/9QAAAAD/+wAAAAAAAAAA//3/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ/3b/oQAA//v/+//7/7f/7P9OAAD/cQAA/9oAAAAAAAD/8f/n/7D/sP+3//j/wQAF/9AAAAAA/+7/6QAA/6gAAP/J//j/zv/a//P/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAA/+T/5P/aAAAAAP/7AAAAAP/TAAP/4gAA/+L/+AAAAAAAAAAPAAAAAP/iAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/+//7//v/+wAAAAAAAAAAAAAAAAAA//sAAP/kAAAAAP/7AAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8//a//b/9v/2AAAAAP/u/+IAAP/4/+L/+AAA//b/9v/7/9j/5//9/9//pv/4/8H/+P/2/8b/sP/OAAD/zv/nAAAAAAAAAAAAAAAA//H/9v/a//H/5wAAAAAAAAAAAAAAAAAAAAAAAP8pAAD/+//x/43/pv+NAAAAAP/7//EAAP8pAAX/xgAA/4r/4v/2AAAAAAAA//v/y/8pAAD/0P/uAAD/vP/s//j/ywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9AAAAAA/+f/8f/fAAAAAP/mAAAAAAAAAAP/+AAA//0AAP/fAAAAAAAAAAAAA//7AAAAAAAAAAAAAwAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/0z/twAN//0AAP/9/+IAAP9LAA3/3wAA/98AAAAAAAgAAP/2AAAAAAAAAAUACAAD//MAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAA//v/+//4AAAAAAAAAAAAAP/2/+QAAAAAAAAAAAAA/+T//QAA//3/+//4AAAAAAAAAAD/9v/7AAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/+wAA//b/+P/uAAAAAAAAAAAAAP/sAAP/+wAA//v//f/4AAAAAAAAAAD/8//7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/4D/uv/9AAAAAAAA/3n/4v+IAAD/hQAA/78AAAAAAAAAAP/i/3b/fv+N//b/fgAA/6sAAAAD/8b/xP/p/54AAP/T//b/f/+D/9r/3wAAAAAAAAAAAAD/7v/4//YAAAAAAAAAAAAAAAAAAAAA/87/3wAAAAAAAAAA//H/6f/uAAAAAAAAAAAAAAAAAAAAAAAA/+n/+P/4//P/7AAAAAAAAAAAAAAAAAAA/+wAAP/9AAD//f/zAAAAAP/9AAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAP/5T/tf/nAAAAAP/4/63/2v+8AAD/pgAX/8EADQAAAAAAAP/x/7D/t//G/9D/wQAA/8EAAP/7/9r/2P/nAAD/8f/OAAD/xv+o/+L/0//u//b/+//2AAAAAAAAAAAAAAAZAA8ADwAAAAAAAAAP/7D/yf/xAAAAAP/4/7wAAAAAAAD/0wAA/9oAFAAAAAAAAP/x/7H/xv/Y/+T/0wAF/+IAAP/7AAD/8f/zAAAAAP/fAAD/0AAAAAAAAP/z//j/+//7AAD/6QAAAAAAAAAZAA8ADwAAAAAAAAAAAAD/+//f//H/8f/uAAAAAAAA//sAAAAA/+wAAAAA/+kAAAAA/9//6QAA//v/uwAA/8kAAP/7//H/xv/YAAD/7v/7AAAAAAAAAAAAAAAA//0AAP/4//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5n/vv/f//P/9gAA/4j/lP+T/+7/3QAA/7UABQAAAAAAAP/u/4f/lP+R/63/nAAA/+cAAP/7/+n/wf/fAAD/9v/GAAD/nAAA/+z/5/+c//H/+//z//sAAAAA/+4AAAAZAA8ADwAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAUAAAAAAAD//QAAAAAAAAAAAAD/4gAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+tAAD/tAAAAAAAAAAAAAAAAAAAAAD/7P+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+wAAX/wQAAAAAAAAAAAAAAAAAAAAD//f/EAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAMAAAAAAAAAAAAAAAUAAAAAAAAAAP/JAAD/wAAAAAAAAAAAAAAAAAAAAAD/+P/OAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+3AAD/twAAAAAAAAAAAAAAAAAAAAD/7v/EAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAABa/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAA3AAAARAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEADwAKwAAACgAAAAA/98AAAAAAAAAAAAAAAAAAAAAAAAAAP/i//v/ywAAAAAAAAAA//EAAAAAAAD/7P/iAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+tAAD/tQAAAAAAAAAAAAAAAAAAAAD/5P/BAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/4gAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/y//v/uwAAAAAAAAAA/+wAAAAA//3/4v/yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/i//0AAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAP/uQAAAAAAAAAAAAAAAAAAAAD//f/OAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5IAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAD/ugAAAAAAAAAAAAAAAAAAAAAAEv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/LAAD/vwAAAAAAAAAAAAAAAAAAAAD/+P/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/x//v/0AAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/JAAD/twAAAAAAAAAAAAAAAAAAAAD/8f/LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX/53/8wAAAAAAAAAA//0AAAAAAAAAAAAA//v/uQAAAAAAAAAA//YAAAAAAAr/+P/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7/9//twAAAAAAAAAA/+f/8QAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAD/twAAAAAAAAAAAAAAAAAAAAAAAP/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/+AAAAAAAAP/7AAAAAP/wAAAAAAAAAAD/+AAAAAAAAP/2AAAAAAAAAAAAAP/9AAAAAAAAAAAABQAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABAAIAmgAAAAEAAgCZAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAgADAAQABQAGAAcACAAJAAkACgALAAwACQAKAA0ADgANAA8AEAARABIAEwAUABUAFgAXAAEAAQABAAEAAQABABgAGQAaAAEAGwAcAB0AHgAfAB8AIAABAB4AHgAhABkAIgAjACQAJQAmACcAJwAoACcAKQABAAEAAQABAAEAAQABAAEAAQABAAYAKgABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEABACiADUADQAAAAAAAAAiAA0AAAAxAAEAAAACAA4AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAAAAAAAAAA8AAAADAAAABAAAAAAAAAAEAAAAAAAQAAAAAAAAAAAABAAAAAQAAAApABEAEgAFAAYAEwAHAAAAAAAAADIAAAAAAAAACAA0ABQAFQAUADAACQA0ACMAIwA0ADQAJAAkABQAJAAVACQAFgAXACQAGAAYACAAGAAlAAAAAAAzAAAAAQAAAAEAAAAAAAAACgALAAAAAgAAAAAAGQAAABkAAAAOAAIAAgAAAAAAAAAAAAAAAAAqAAAAAAAAABoAAAArABsALAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtAC4AAAAvACYADAAnACsAIQAsAB0AHgAeAAAAAAAfAAAAHwAAAB4AHgAeAAEAAAAKANwBZgABbGF0bgAIACIABUFaRSAAPkNSVCAAWk1PTCAAdlJPTSAAklRSSyAArgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgAA//8ACwAAAAEAAgADAAQABQAGAAcACAAJAAoAAP//AAsAAAABAAIAAwAEAAUABgAHAAgACQAKAAD//wALAAAAAQACAAMABAAFAAYABwAIAAkACgALYWFsdABEYzJzYwBMY2FzZQBSbG51bQBYb251bQBeb3JkbgBkcG51bQBqc2FsdABwc3MwMgB4c3MwNQB+dG51bQCEAAAAAgAAAAEAAAABAAIAAAABAAMAAAABAAQAAAABAAUAAAABAAYAAAABAAcAAAACAAgACQAAAAEACAAAAAEACQAAAAEACgALABgAIAAoADAAOABAAEgAWABgAGgAcAABAAAAAQBgAAMAAAABAHIAAQAAAAECDAABAAAAAQIiAAEAAAABAjAAAQAAAAECbAAGAAAABQKqAs4C8AMaAzwAAQAAAAEDVgABAAAAAQOSAAEAAAABA5gAAQAAAAEDogACAA4ABACdAKkAngCbAAEABAAEAAYAIgByAAEBaAAtAGAAZABoAGwAcgB4AH4AhACKAJAAlgCcAKIAqACsALAAtgC8AMIAyADOANQA2gDgAOYA7ADyAPoBAAEGAQwBEgEYAR4BJAEqATABOAE+AUQBSgFQAVYBXAFiAAEAqgABAKYAAQCjAAIAhQB7AAIAhgB8AAIAiAB9AAIAiQB+AAIAigB/AAIAiwCAAAIAjACBAAIAjQCCAAIAjgCDAAIAjwCEAAEApwABAKgAAgCQABMAAgCRABQAAgCTABUAAgCUABYAAgCVABcAAgCWABgAAgCXABkAAgCYABoAAgCZABsAAgCaABwAAgATAJAAAwCHABQAkQACABUAkwACABYAlAACABcAlQACABgAlgACABkAlwACABoAmAACABsAmQACABwAmgACAHsAhQADAJIAfACGAAIAfQCIAAIAfgCJAAIAfwCKAAIAgACLAAIAgQCMAAIAggCNAAIAgwCOAAIAhACPAAIACQAHAAcAAAALAAsAAQAQABAAAgATABwAAwBeAF4ADQBgAGAADgB7AIYADwCIAJEAGwCTAJoAJQACABAABQCdAKkAngCnAKgAAQAFAAQABgAiAF4AYAACAAwAAwCmAKMAmwABAAMACwAQAHIAAgAuABQAEwAUABUAFgAXABgAGQAaABsAHAB7AHwAfQB+AH8AgACBAIIAgwCEAAIAAwCFAIYAAACIAJEAAgCTAJoADAACADAAFQCpAIUAhgCIAIkAigCLAIwAjQCOAI8AkACRAJMAlACVAJYAlwCYAJkAmgACAAMABgAGAAAAEwAcAAEAewCEAAsAAwACABIAEgABABgAAQAeAAAAAQABABQAAQABAFYAAQABAFcAAwACABAAFgABABwAAAAAAAEAAQAVAAEAAQAUAAEAAQBHAAMAAgASABgAAQAeAAEAJAAAAAEAAQAVAAEAAQAUAAEAAQBRAAEAAQBHAAMAAgAQABYAAQAcAAAAAAABAAEAFgABAAEAFAABAAEARwADAAIAEgAYAAEAHgABACQAAAABAAEAFgABAAEAFAABAAEAVQABAAEARwACAC4AFAB7AHwAfQB+AH8AgACBAIIAgwCEAJAAkQCTAJQAlQCWAJcAmACZAJoAAgADABMAHAAAAIUAhgAKAIgAjwAMAAIACAABAKoAAQABAAcAAgAKAAIAhwCSAAEAAgCGAJEAAgAuABQAEwAUABUAFgAXABgAGQAaABsAHACFAIYAiACJAIoAiwCMAI0AjgCPAAIAAwB7AIQAAACQAJEACgCTAJoADA==) format('opentype'); + font-weight: bold; + font-style: normal; +} +@font-face { + font-family: BookSanity; + src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGICGZBk0AAAfcAABO6kRTSUcAAAABAABZeAAAAAhHREVGALsAAwAAWYAAAAAYR1BPU2uUukYAAFmYAAAmKEdTVULlMciwAAB/wAAABbxPUy8yOu7UAAAAAUAAAABgY21hcJ/aplYAAATEAAAC9mhlYWQIEgIzAAAA3AAAADZoaGVhCLIGaAAAARQAAAAkaG10eFh6MKQAAFbIAAACrm1heHAArFAAAAABOAAAAAZuYW1lHo8siwAAAaAAAAMhcG9zdP+sADIAAAe8AAAAIAABAAAAAQBCIIbG8F8PPPUAAQPoAAAAANKJ1JUAAAAA0onqGv9y/ykEdQM5AAIAAwACAAAAAAAAAAEAAAPz/nYAAAQp/3L/NgR1A+gA1QAAAAAAAAAAAAAAAACrAABQAACsAAAAAwIGAZAABQAAArwCigAAAIwCvAKKAAAB3QAyAPoAAAIABQMHAAAJAAOAAAAjAAAASAAAAAAAAAAAICAgIAABAAAiYALu/wYAAAPzAYoAAAABAAAAAAHDArwAAAAgAAIAAAAUAPYAAQAAAAAAAAAoAFkAAQAAAAAAAQAMAAAAAQAAAAAAAgAGAA0AAQAAAAAAAwAhAAAAAQAAAAAABAATAAAAAQAAAAAABQAeACEAAQAAAAAABgATAD8AAQAAAAAACQAHAFIAAQAAAAAADQAoAFkAAQAAAAAADgA4AIEAAwABBAkAAABQALkAAwABBAkAAQAYAQkAAwABBAkAAgAMASMAAwABBAkAAwBCAQkAAwABBAkABAAmAQkAAwABBAkABQA8AUsAAwABBAkABgAmAYcAAwABBAkACQAOAa0AAwABBAkADQBQALkAAwABBAkADgBwAbtCb29raW5zYW5pdHkgSXRhbGljOlZlcnNpb24gMS4wMDFWZXJzaW9uIDEuMDAxIERlY2VtYmVyIDYsIDIwMTVCb29raW5zYW5pdHktSXRhbGljU29sYmVyYUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wL2xlZ2FsY29kZQBBAHQAdAByAGkAYgB1AHQAaQBvAG4ALQBTAGgAYQByAGUAQQBsAGkAawBlACAANAAuADAAIABJAG4AdABlAHIAbgBhAHQAaQBvAG4AYQBsAEIAbwBvAGsAaQBuAHMAYQBuAGkAdAB5ACAASQB0AGEAbABpAGMAOgBWAGUAcgBzAGkAbwBuACAAMQAuADAAMAAxAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwADEAIABEAGUAYwBlAG0AYgBlAHIAIAA2ACwAIAAyADAAMQA1AEIAbwBvAGsAaQBuAHMAYQBuAGkAdAB5AC0ASQB0AGEAbABpAGMAUwBvAGwAYgBlAHIAYQBoAHQAdABwAHMAOgAvAC8AYwByAGUAYQB0AGkAdgBlAGMAbwBtAG0AbwBuAHMALgBvAHIAZwAvAGwAaQBjAGUAbgBzAGUAcwAvAGIAeQAtAHMAYQAvADQALgAwAC8AbABlAGcAYQBsAGMAbwBkAGUAAAAAAAADAAAAAwAAABwAAQAAAAAA9AADAAEAAAAcAAQA2AAAACwAIAAEAAwAAAAdAH4AoACkAKkArwC0ALcAxgDYAPcCxgLaAtwgGiAeICYhIiIeImD//wAAAAAAHQAgAKAApACoAK4AtAC3AMYA1wD3AsYC2ALcIBggHCAmISIiHiJg//8AAf/j/+P/zAAHAAAAAP+x/7v/ogAA/3r9r/2g/ZoAAAAA4EXfQt5M3gcAAQAAAAAAAAAAAAAAIgAkAAAAAAAAACAAAAAAAAAAAAAaAB4AAAAAAAAAAAAAAGYAYwBiAHcAAgBpAG8AcABzAG0AbgB0AAYCAgAAAAAA/AABAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABiAGMAZABlAGYAZwBoAGkAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAP/0AAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBARRCb29raW5zYW5pdHktSXRhbGljAAEBATj4EAD4TwwA+FAC+FED+FIEQAwDvQwE+yL7axwEdfnNBR0AAAK4Dx0AAAQPER0AAAALHQAATt0SADgCAAEABgAOABYAHQAjACgALQA0ADoAQABFAEwAUwBZAF8AZABpAG4AdQB7AIEAhgCNAJQAmgCgAKUAqgCvALYAvADCAMcAzgDVANsA6wDzAPsBBQEUASQBMwFDAU4BVgFeAWwBegGJAZUBnQHFAdgB5AHqLm51bGxub3RlcXVhbGluZmluaXR5bmJzcGFjZXplcm8uMW9uZS4xdHdvLjF0aHJlZS4xZm91ci4xZml2ZS4xc2l4LjFzZXZlbi4xZWlnaHQuMW5pbmUuMXplcm8uMm9uZS4yb25lLjN0d28uMnRocmVlLjJmb3VyLjJmaXZlLjJzaXguMnNldmVuLjJlaWdodC4ybmluZS4yemVyby4zb25lLjRvbmUuNXR3by4zdGhyZWUuM2ZvdXIuM2ZpdmUuM3NpeC4zc2V2ZW4uM2VpZ2h0LjNuaW5lLjNwZXJpb2RjZW50ZXJlZC4xYnVsbGV0LjFleGNsYW0uMXF1ZXN0aW9uLjFndWlsbGVtb3RsZWZ0LjFndWlsbGVtb3RyaWdodC4xZ3VpbHNpbmdsbGVmdC4xZ3VpbHNpbmdscmlnaHQuMWh5cGhlbi5jYXNlZW5kYXNoLjFlbWRhc2guMXBhcmVubGVmdC5jYXNlYnJhY2VsZWZ0LmMyc2NicmFjZXJpZ2h0LmMyc2NudW1iZXJzaWduLjFkb2xsYXIuMUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxCb29raW5zYW5pdHkgSXRhbGljQm9va2luc2FuaXR5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AAAAAAAAAAAAAAAAAAAAAP/xAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAA/90AAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7//v/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAA//v//f/4//j/+AAA//YAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+4AAwAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAA//EAAAAAAAD/+//aAAAAAAAA//gAAP/7//v/+wAA/9oAAP/2AAAAAAAAAAAAAP/p/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAA//sAAP/7//v/+wAA//YAAP/7AAAAAAAAAAAAAP/7//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//f/zAAAAAAAA//P//f/2//j/8wAA//YAAP/zAAAAAAAAAAAAAP/4//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2X/t//G/7AAAAAAAAAAAAAAAAAAAP+tAAD/qP/p//0AAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+P/9AAAAAAAA/+4AAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAAAAAAAAAAAAAAD/+wAA//sAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/6MABQAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAP/7//v/+AAA//sABf/7AAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAA/+4AAAAAAAAAAAAA//j/+//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/JAAAAAAAA//gAAAAAAAAAAAAA/9gAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAAAAAAAAAAAAAAAAAD/7AAA/+QAAP/dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/iAAAAAAAAAAAAAAAAAAD/5wAA/9//+P/sAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/+wAAAAAAAAAA/+wAAP/LAAAAAAAA//gAAAAAAAD/6QAA/8sAAP/xAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//v/+wAAAAAAAAAA//sAAP/4AAAAAAAAAAAAAAAA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AAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/ywAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/rQAA/7UAAAAAAAAAAAAAAAAAAAAA/+T/wQAAAAAAAAAAAAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/+IAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8v/7/7sAAAAAAAAAAP/sAAAAAP/9/+L/8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4v/9AAAAAAAAAAAAAAAAAAAAAAAAAAD/ugAD/7kAAAAAAAAAAAAAAAAAAAAA//3/zgAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+SAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAA/7oAAAAAAAAAAAAAAAAAAAAAABL/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ywAA/78AAAAAAAAAAAAAAAAAAAAA//j/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/7/9AAAAAAAAAAAAAAAAAAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AVwBYgABAKoAAQCmAAEAowACAIUAewACAIYAfAACAIgAfQACAIkAfgACAIoAfwACAIsAgAACAIwAgQACAI0AggACAI4AgwACAI8AhAABAKcAAQCoAAIAkAATAAIAkQAUAAIAkwAVAAIAlAAWAAIAlQAXAAIAlgAYAAIAlwAZAAIAmAAaAAIAmQAbAAIAmgAcAAIAEwCQAAMAhwAUAJEAAgAVAJMAAgAWAJQAAgAXAJUAAgAYAJYAAgAZAJcAAgAaAJgAAgAbAJkAAgAcAJoAAgB7AIUAAwCSAHwAhgACAH0AiAACAH4AiQACAH8AigACAIAAiwACAIEAjAACAIIAjQACAIMAjgACAIQAjwACAAkABwAHAAAACwALAAEAEAAQAAIAEwAcAAMAXgBeAA0AYABgAA4AewCGAA8AiACRABsAkwCaACUAAgAQAAUAnQCpAJ4ApwCoAAEABQAEAAYAIgBeAGAAAgAMAAMApgCjAJsAAQADAAsAEAByAAIALgAUABMAFAAVABYAFwAYABkAGgAbABwAewB8AH0AfgB/AIAAgQCCAIMAhAACAAMAhQCGAAAAiACRAAIAkwCaAAwAAgAwABUAqQCFAIYAiACJAIoAiwCMAI0AjgCPAJAAkQCTAJQAlQCWAJcAmACZAJoAAgADAAYABgAAABMAHAABAHsAhAALAAMAAgASABIAAQAYAAEAHgAAAAEAAQAUAAEAAQBWAAEAAQBXAAMAAgAQABYAAQAcAAAAAAABAAEAFQABAAEAFAABAAEARwADAAIAEgAYAAEAHgABACQAAAABAAEAFQABAAEAFAABAAEAUQABAAEARwADAAIAEAAWAAEAHAAAAAAAAQABABYAAQABABQAAQABAEcAAwACABIAGAABAB4AAQAkAAAAAQABABYAAQABABQAAQABAFUAAQABAEcAAgAuABQAewB8AH0AfgB/AIAAgQCCAIMAhACQAJEAkwCUAJUAlgCXAJgAmQCaAAIAAwATABwAAACFAIYACgCIAI8ADAACAAgAAQCqAAEAAQAHAAIACgACAIcAkgABAAIAhgCRAAIALgAUABMAFAAVABYAFwAYABkAGgAbABwAhQCGAIgAiQCKAIsAjACNAI4AjwACAAMAewCEAAAAkACRAAoAkwCaAAw=) format('opentype'); + font-weight: normal; + font-style: italic; +} +@font-face { + font-family: BookSanity; + src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGICf3sWQAAAfcAABPEkRTSUcAAAABAABZoAAAAAhHREVGALsAAwAAWagAAAAYR1BPU2uUukYAAFnAAAAmKEdTVULlMciwAAB/6AAABbxPUy8yOu7UIAAAAUAAAABgY21hcJ/aplYAAATEAAAC9mhlYWQIEwImAAAA3AAAADZoaGVhCLIGTQAAARQAAAAkaG10eFhpHbAAAFbwAAACrm1heHAArFAAAAABOAAAAAZuYW1lHo8siwAAAaAAAAMhcG9zdP+sADIAAAe8AAAAIAABAAAAAQBCE+mVyl8PPPUAAQPoAAAAANKJ1JUAAAAA0onqDf9X/wsEkANXAAMAAwACAAAAAAAAAAEAAAPz/nYAAAQp/1f/GwSQA+gA1QAAAAAAAAAAAAAAAACrAABQAACsAAAAAwIGAZAABQAAArwCigAAAIwCvAKKAAAB3QAyAPoAAAIABQMHAAAJAAOAAAAjAAAASAAAAAAAAAAAICAgIAAhAAAiYALu/wYAAAPzAYoAAAABAAAAAAHDArwAAAAgAAIAAAAUAPYAAQAAAAAAAAAoAFkAAQAAAAAAAQAMAAAAAQAAAAAAAgAGAA0AAQAAAAAAAwAhAAAAAQAAAAAABAATAAAAAQAAAAAABQAeACEAAQAAAAAABgATAD8AAQAAAAAACQAHAFIAAQAAAAAADQAoAFkAAQAAAAAADgA4AIEAAwABBAkAAABQALkAAwABBAkAAQAYAQkAAwABBAkAAgAMASMAAwABBAkAAwBCAQkAAwABBAkABAAmAQkAAwABBAkABQA8AUsAAwABBAkABgAmAYcAAwABBAkACQAOAa0AAwABBAkADQBQALkAAwABBAkADgBwAbtCb29raW5zYW5pdHkgSXRhbGljOlZlcnNpb24gMS4wMDFWZXJzaW9uIDEuMDAxIERlY2VtYmVyIDYsIDIwMTVCb29raW5zYW5pdHktSXRhbGljU29sYmVyYUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wL2xlZ2FsY29kZQBBAHQAdAByAGkAYgB1AHQAaQBvAG4ALQBTAGgAYQByAGUAQQBsAGkAawBlACAANAAuADAAIABJAG4AdABlAHIAbgBhAHQAaQBvAG4AYQBsAEIAbwBvAGsAaQBuAHMAYQBuAGkAdAB5ACAASQB0AGEAbABpAGMAOgBWAGUAcgBzAGkAbwBuACAAMQAuADAAMAAxAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwADEAIABEAGUAYwBlAG0AYgBlAHIAIAA2ACwAIAAyADAAMQA1AEIAbwBvAGsAaQBuAHMAYQBuAGkAdAB5AC0ASQB0AGEAbABpAGMAUwBvAGwAYgBlAHIAYQBoAHQAdABwAHMAOgAvAC8AYwByAGUAYQB0AGkAdgBlAGMAbwBtAG0AbwBuAHMALgBvAHIAZwAvAGwAaQBjAGUAbgBzAGUAcwAvAGIAeQAtAHMAYQAvADQALgAwAC8AbABlAGcAYQBsAGMAbwBkAGUAAAAAAAADAAAAAwAAABwAAQAAAAAA9AADAAEAAAAcAAQA2AAAACwAIAAEAAwAAAAdAH4AoACkAKkArwC0ALcAxgDYAPcCxgLaAtwgGiAeICYhIiIeImD//wAAAAAAHQAgAKAApACoAK4AtAC3AMYA1wD3AsYC2ALcIBggHCAmISIiHiJg//8AAf/j/+P/zAAHAAAAAP+x/7v/ogAA/3r9r/2g/ZoAAAAA4EXfQt5M3gcAAQAAAAAAAAAAAAAAIgAkAAAAAAAAACAAAAAAAAAAAAAaAB4AAAAAAAAAAAAAAGYAYwBiAHcAAgBpAG8AcABzAG0AbgB0AAYCAgAAAAAA/AABAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABiAGMAZABlAGYAZwBoAGkAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrAGwAAAAAAAAAAAAAAAAAAABtAG4AbwBwAHEAAAAAAAAAAACrAAAAAAAAAAAAAAAAAHMAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1AHYAdwB4AHkAegAAAAMAAP/0AAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQBAAEBARRCb29raW5zYW5pdHktSXRhbGljAAEBATj4EAD4TwwA+FAC+FED+FIEQAwDvQwE+z37iRwEkPnrBR0AAAK4Dx0AAAQPER0AAAALHQAATwUSADgCAAEABgAOABYAHQAjACgALQA0ADoAQABFAEwAUwBZAF8AZABpAG4AdQB7AIEAhgCNAJQAmgCgAKUAqgCvALYAvADCAMcAzgDVANsA6wDzAPsBBQEUASQBMwFDAU4BVgFeAWwBegGJAZUBnQHFAdgB5AHqLm51bGxub3RlcXVhbGluZmluaXR5bmJzcGFjZXplcm8uMW9uZS4xdHdvLjF0aHJlZS4xZm91ci4xZml2ZS4xc2l4LjFzZXZlbi4xZWlnaHQuMW5pbmUuMXplcm8uMm9uZS4yb25lLjN0d28uMnRocmVlLjJmb3VyLjJmaXZlLjJzaXguMnNldmVuLjJlaWdodC4ybmluZS4yemVyby4zb25lLjRvbmUuNXR3by4zdGhyZWUuM2ZvdXIuM2ZpdmUuM3NpeC4zc2V2ZW4uM2VpZ2h0LjNuaW5lLjNwZXJpb2RjZW50ZXJlZC4xYnVsbGV0LjFleGNsYW0uMXF1ZXN0aW9uLjFndWlsbGVtb3RsZWZ0LjFndWlsbGVtb3RyaWdodC4xZ3VpbHNpbmdsbGVmdC4xZ3VpbHNpbmdscmlnaHQuMWh5cGhlbi5jYXNlZW5kYXNoLjFlbWRhc2guMXBhcmVubGVmdC5jYXNlYnJhY2VsZWZ0LmMyc2NicmFjZXJpZ2h0LmMyc2NudW1iZXJzaWduLjFkb2xsYXIuMUF0dHJpYnV0aW9uLVNoYXJlQWxpa2UgNC4wIEludGVybmF0aW9uYWxCb29raW5zYW5pdHkgSXRhbGljQm9va2luc2FuaXR5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/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7/6v/2P/aAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAP/dAAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//7//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/7//3/+P/4//gAAP/2AAAAAAAAAAAAAAAAAAD//f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/xAAAAAAAA//v/2gAAAAAAAP/4AAD/+//7//sAAP/aAAD/9gAAAAAAAAAAAAD/6f/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAP/7AAD/+//7//sAAP/2AAD/+wAAAAAAAAAAAAD/+//7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//3/8wAAAAAAAP/z//3/9v/4//MAAP/2AAD/8wAAAAAAAAAAAAD/+P/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9l/7f/xv+wAAAAAAAAAAAAAAAAAAD/rQAA/6j/6f/9AAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//j//QAAAAAAAP/uAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8wAAAAAAAAAAAAAAAAAA//sAAP/7AAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+jAAUAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAD/+//7//gAAP/7AAX/+wAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/uAAAAAAAAAAAAAP/4//v/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/yQAAAAAAAP/4AAAAAAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6QAAAAAAAAAAAAAAAAAA/+wAAP/kAAD/3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/4gAAAAAAAAAAAAAAAAAA/+cAAP/f//j/7AAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//sAAAAAAAAAAP/sAAD/ywAAAAAAAP/4AAAAAAAA/+kAAP/LAAD/8QAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAA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AAAAAAAA/+L/+//LAAAAAAAAAAD/8QAAAAAAAP/s/+IAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA/8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/60AAP+1AAAAAAAAAAAAAAAAAAAAAP/k/8EAAAAAAAAAAAAAAAD/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/iAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/+/+7AAAAAAAAAAD/7AAAAAD//f/i//IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+L//QAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAA/+5AAAAAAAAAAAAAAAAAAAAAP/9/84AAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAP+6AAAAAAAAAAAAAAAAAAAAAAAS//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8sAAP+/AAAAAAAAAAAAAAAAAAAAAP/4/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/+//QAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAA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) format('opentype'); + font-weight: bold; + font-style: italic; +} + +/* Notes and Tables */ +@font-face { + font-family: ScalySans; + src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), + url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: ScalySansSmallCaps; + src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), + url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); + font-weight: normal; + font-style: normal; +} + +/* Fancy First Letter */ +@font-face { + font-family: Solberry; + src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), + url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); + font-weight: normal; + font-style: normal; +} + +/* Headers */ +@font-face { + font-family: MrJeeves; + src: url(data:application/font-woff2;charset=utf-8;base64,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) format('woff2'), + url(data:application/font-woff;charset=utf-8;base64,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) format('woff'); + font-weight: normal; + font-style: normal; +} diff --git a/client/homebrew/phbStyle/phb.style.less b/client/homebrew/phbStyle/phb.style.less index de8291f..2d6a7e1 100644 --- a/client/homebrew/phbStyle/phb.style.less +++ b/client/homebrew/phbStyle/phb.style.less @@ -59,22 +59,25 @@ line-height : 1.3em; &+p{ margin-top : -0.8em; - text-indent : 1em; } } ul{ margin-bottom : 0.8em; + padding-left : 1.4em; line-height : 1.3em; list-style-position : outside; list-style-type : disc; - padding-left: 1.4em; } ol{ margin-bottom : 0.8em; + padding-left : 1.4em; line-height : 1.3em; list-style-position : outside; list-style-type : decimal; - padding-left: 1.4em; + } + //Indents after p or lists + p+p, ul+p, ol+p{ + text-indent : 1em; } img{ z-index : -1; @@ -169,15 +172,15 @@ // *****************************/ blockquote{ .useSansSerif(); - box-sizing : border-box; - margin-bottom : 1em; - padding : 5px 10px; - background-color : @noteGreen; - border-style: solid; - border-width: 11px; - border-image: @noteBorderImage 11; - border-image-outset: 9px 0px; - box-shadow : 1px 4px 14px #888; + box-sizing : border-box; + margin-bottom : 1em; + padding : 5px 10px; + background-color : @noteGreen; + border-style : solid; + border-width : 11px; + border-image : @noteBorderImage 11; + border-image-outset : 9px 0px; + box-shadow : 1px 4px 14px #888; p, ul{ font-size : 0.352cm; line-height : 1.1em; @@ -185,7 +188,7 @@ } //If a note starts a column, give it space at the top to render border pre+blockquote{ - margin-top: 11px; + margin-top : 11px; } //***************************** // * MONSTER STAT BLOCK @@ -222,8 +225,8 @@ margin : 0; column-span : 1; background-color : transparent; + border-style : none; border-image : none; - border-style : none; -webkit-column-span : 1; tbody{ tr:nth-child(odd), tr:nth-child(even){ @@ -339,7 +342,7 @@ -moz-column-span : all; } //Column Break - pre{ + pre, code{ visibility : hidden; -webkit-column-break-after : always; break-after : always; @@ -367,6 +370,31 @@ } } //***************************** +// * SPELL LIST +// *****************************/ +.phb .spellList{ + .useSansSerif(); + column-count : 4; + column-span : all; + -webkit-column-span : all; + -moz-column-span : all; + ul+h5{ + margin-top : 15px; + } + p, ul{ + font-size : 0.352cm; + line-height : 1.3em; + } + ul{ + margin-bottom : 0.5em; + padding-left : 1em; + text-indent : -1em; + list-style-type : none; + -webkit-column-break-inside : auto; + column-break-inside : auto; + } +} +//***************************** // * PRINT // *****************************/ .phb.print{ diff --git a/client/main/main.jsx b/client/main/main.jsx index 815d2c7..43fb07c 100644 --- a/client/main/main.jsx +++ b/client/main/main.jsx @@ -1,86 +1,86 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - -var Router = require('pico-router'); - -var NaturalCritIcon = require('naturalcrit/svg/naturalcrit.svg.jsx'); -var HomebrewIcon = require('naturalcrit/svg/homebrew.svg.jsx'); - -var Main = React.createClass({ - getDefaultProps: function() { - return { - tools : [ - { - id : 'homebrew', - path : '/homebrew', - name : 'The Homebrewery', - icon : , - desc : 'Make authentic-looking 5e homebrews using Markdown', - - show : true, - beta : false - }, - { - id : 'homebrew2', - path : '/homebrew', - name : 'The Homebrewery', - icon : , - desc : 'Make authentic-looking 5e homebrews using Markdown', - - show : false, - beta : true - }, - { - id : 'homebrewfg2', - path : '/homebrew', - name : 'The Homebrewery', - icon : , - desc : 'Make authentic-looking 5e homebrews using Markdown', - - show : false, - beta : false - } - - ] - }; - }, - - renderTool : function(tool){ - if(!tool.show) return null; - - return -
- {tool.icon} -

{tool.name}

-

{tool.desc}

-
-
; - }, - - renderTools : function(){ - return _.map(this.props.tools, (tool)=>{ - return this.renderTool(tool); - }); - }, - - render : function(){ - return
-
-
- - - Natural - Crit - -
-

Top-tier tools for the discerning DM

-
-
- {this.renderTools()} -
-
- } -}); - -module.exports = Main; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + +var Router = require('pico-router'); + +var NaturalCritIcon = require('naturalcrit/svg/naturalcrit.svg.jsx'); +var HomebrewIcon = require('naturalcrit/svg/homebrew.svg.jsx'); + +var Main = React.createClass({ + getDefaultProps: function() { + return { + tools : [ + { + id : 'homebrew', + path : '/homebrew', + name : 'The Homebrewery', + icon : , + desc : 'Make authentic-looking 5e homebrews using Markdown', + + show : true, + beta : false + }, + { + id : 'homebrew2', + path : '/homebrew', + name : 'The Homebrewery', + icon : , + desc : 'Make authentic-looking 5e homebrews using Markdown', + + show : false, + beta : true + }, + { + id : 'homebrewfg2', + path : '/homebrew', + name : 'The Homebrewery', + icon : , + desc : 'Make authentic-looking 5e homebrews using Markdown', + + show : false, + beta : false + } + + ] + }; + }, + + renderTool : function(tool){ + if(!tool.show) return null; + + return +
+ {tool.icon} +

{tool.name}

+

{tool.desc}

+
+
; + }, + + renderTools : function(){ + return _.map(this.props.tools, (tool)=>{ + return this.renderTool(tool); + }); + }, + + render : function(){ + return
+
+
+ + + Natural + Crit + +
+

Top-tier tools for the discerning DM

+
+
+ {this.renderTools()} +
+
+ } +}); + +module.exports = Main; diff --git a/client/main/main.less b/client/main/main.less index 39a2766..21f13ed 100644 --- a/client/main/main.less +++ b/client/main/main.less @@ -1,136 +1,136 @@ -@import 'naturalcrit/styles/core.less'; -.main{ - height : 100vh; - background-color : white; - .top{ - .fadeInTop(1s); - .delay(0.5); - margin-bottom : 100px; - padding-top : 100px; - text-align : center; - .logo{ - font-size : 4em; - color : black; - svg{ - height : .9em; - margin-right : .2em; - cursor : pointer; - fill : black; - } - .name{ - font-family : 'CodeLight'; - .crit{ - font-family : 'CodeBold'; - } - } - } - p{ - margin-top : 10px; - font-size : 1.3em; - font-style : italic; - color : @grey; - } - } - .tools{ - width : 100%; - text-align : center; - .tool{ - .sequentialDelay(0.5s, 1s); - .fadeInDown(1s); - .keep(); - display : inline-block; - cursor : pointer; - opacity : 0; - color : black; - text-align : center; - text-decoration : none; - &+.tool{ - border-left : 1px solid #666; - } - .content{ - .addSketch(360px); - .animateAll(0.5s); - position : relative; - width : 320px; - padding : 35px; - &:hover{ - svg, h2{ - .transform(scale(1.3)); - } - } - h2{ - .animateAll(0.5s); - font-family : 'CodeBold'; - font-size : 2em; - } - p{ - max-width : 300px; - margin : 20px auto; - line-height : 1.5em; - } - svg{ - .animateAll(0.5s); - height : 10em; - } - } - .content:hover{ - background-color : fade(@teal, 20%); - } - //Beta styles - &.beta{ - cursor : initial; - .content{ - &:hover{ - svg, h2{ - .transform(scale(1.0)); - } - } - svg, h2{ - opacity : 0.3; - } - &:after{ - .animateAll(); - content : "beta!"; - position : absolute; - display : block; - top : 120px; - left : 0px; - width : 100%; - padding : 10px 0px; - //opacity : 0; - background-color : fade(@grey, 50%); - font-size : 2em; - font-weight : 800; - text-align : center; - text-transform : uppercase; - } - } - } - } - } -} -.addSketch(@length, @color : black){ - path, line, polyline, circle, rect, polygon { - .sketch(@length, @color, 4s); - stroke-dasharray : @length; - stroke-dashoffset : 0px; - stroke : @color; - stroke-width : 0.5px; - fill : @color; - //.animateAll(3s); - } -} -.sketch(@length, @color : black, @duration : 3s, @easing : @defaultEasing){ - .createAnimation(sketch, @duration, @easing); - .sketchKeyFrames(){ - 0% { stroke-dashoffset : @length; fill: transparent;} - 50% { stroke-dashoffset : @length; fill: transparent;} - 80% { stroke-dashoffset : 0px; fill: transparent;} - 100% { stroke-dashoffset : 0px; fill:@color;} - } - @-webkit-keyframes sketch {.sketchKeyFrames();} - @-moz-keyframes sketch {.sketchKeyFrames();} - @-ms-keyframes sketch {.sketchKeyFrames();} - @-o-keyframes sketch {.sketchKeyFrames();} - @keyframes sketch {.sketchKeyFrames();} +@import 'naturalcrit/styles/core.less'; +.main{ + height : 100vh; + background-color : white; + .top{ + .fadeInTop(1s); + .delay(0.5); + margin-bottom : 100px; + padding-top : 100px; + text-align : center; + .logo{ + font-size : 4em; + color : black; + svg{ + height : .9em; + margin-right : .2em; + cursor : pointer; + fill : black; + } + .name{ + font-family : 'CodeLight'; + .crit{ + font-family : 'CodeBold'; + } + } + } + p{ + margin-top : 10px; + font-size : 1.3em; + font-style : italic; + color : @grey; + } + } + .tools{ + width : 100%; + text-align : center; + .tool{ + .sequentialDelay(0.5s, 1s); + .fadeInDown(1s); + .keep(); + display : inline-block; + cursor : pointer; + opacity : 0; + color : black; + text-align : center; + text-decoration : none; + &+.tool{ + border-left : 1px solid #666; + } + .content{ + .addSketch(360px); + .animateAll(0.5s); + position : relative; + width : 320px; + padding : 35px; + &:hover{ + svg, h2{ + .transform(scale(1.3)); + } + } + h2{ + .animateAll(0.5s); + font-family : 'CodeBold'; + font-size : 2em; + } + p{ + max-width : 300px; + margin : 20px auto; + line-height : 1.5em; + } + svg{ + .animateAll(0.5s); + height : 10em; + } + } + .content:hover{ + background-color : fade(@teal, 20%); + } + //Beta styles + &.beta{ + cursor : initial; + .content{ + &:hover{ + svg, h2{ + .transform(scale(1.0)); + } + } + svg, h2{ + opacity : 0.3; + } + &:after{ + .animateAll(); + content : "beta!"; + position : absolute; + display : block; + top : 120px; + left : 0px; + width : 100%; + padding : 10px 0px; + //opacity : 0; + background-color : fade(@grey, 50%); + font-size : 2em; + font-weight : 800; + text-align : center; + text-transform : uppercase; + } + } + } + } + } +} +.addSketch(@length, @color : black){ + path, line, polyline, circle, rect, polygon { + .sketch(@length, @color, 4s); + stroke-dasharray : @length; + stroke-dashoffset : 0px; + stroke : @color; + stroke-width : 0.5px; + fill : @color; + //.animateAll(3s); + } +} +.sketch(@length, @color : black, @duration : 3s, @easing : @defaultEasing){ + .createAnimation(sketch, @duration, @easing); + .sketchKeyFrames(){ + 0% { stroke-dashoffset : @length; fill: transparent;} + 50% { stroke-dashoffset : @length; fill: transparent;} + 80% { stroke-dashoffset : 0px; fill: transparent;} + 100% { stroke-dashoffset : 0px; fill:@color;} + } + @-webkit-keyframes sketch {.sketchKeyFrames();} + @-moz-keyframes sketch {.sketchKeyFrames();} + @-ms-keyframes sketch {.sketchKeyFrames();} + @-o-keyframes sketch {.sketchKeyFrames();} + @keyframes sketch {.sketchKeyFrames();} } \ No newline at end of file diff --git a/client/template.dot b/client/template.dot index 0433d8c..cd1309a 100644 --- a/client/template.dot +++ b/client/template.dot @@ -1,30 +1,30 @@ - - - - - - - - {{=vitreum.css}} - {{=vitreum.globals}} - Natural Crit - D&D Tools - - -
{{=vitreum.component}}
- - {{=vitreum.libs}} - {{=vitreum.js}} - {{=vitreum.reactRender}} - - {{? vitreum.inProduction}} - - {{?}} - + + + + + + + + {{=vitreum.css}} + {{=vitreum.globals}} + Natural Crit - D&D Tools + + +
{{=vitreum.component}}
+ + {{=vitreum.libs}} + {{=vitreum.js}} + {{=vitreum.reactRender}} + + {{? vitreum.inProduction}} + + {{?}} + diff --git a/gulpfile.js b/gulpfile.js index a06b07b..b054f1d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,51 +1,51 @@ -"use strict"; - -var vitreumTasks = require("vitreum/tasks"); -var gulp = require("gulp"); - - -var gulp = vitreumTasks(gulp, { - entryPoints: [ - './client/main', - './client/homebrew', - './client/admin' - ], - - DEV: true, - buildPath: "./build/", - pageTemplate: "./client/template.dot", - projectModules: ["./shared/naturalcrit","./shared/codemirror"], - additionalRequirePaths : ['./shared', './node_modules'], - assetExts: ["*.svg", "*.png", "*.jpg", "*.pdf", "*.eot", "*.otf", "*.woff", "*.woff2", "*.ico", "*.ttf"], - serverWatchPaths: ["server"], - serverScript: "server.js", - libs: [ - "react", - "react-dom", - "lodash", - "classnames", - - //From ./shared - "codemirror", - "codemirror/mode/gfm/gfm.js", - 'codemirror/mode/javascript/javascript.js', - - "moment", - "superagent", - "marked", - "pico-router", - "pico-flux" - ], - clientLibs: [], -}); - - -var rename = require('gulp-rename'); -var less = require('gulp-less'); -gulp.task('phb', function(){ - gulp.src('./client/homebrew/phbStyle/phb.style.less') - .pipe(less()) - .pipe(rename('phb.standalone.css')) - .pipe(gulp.dest('./')); -}) - +"use strict"; + +var vitreumTasks = require("vitreum/tasks"); +var gulp = require("gulp"); + + +var gulp = vitreumTasks(gulp, { + entryPoints: [ + './client/main', + './client/homebrew', + './client/admin' + ], + + DEV: true, + buildPath: "./build/", + pageTemplate: "./client/template.dot", + projectModules: ["./shared/naturalcrit","./shared/codemirror"], + additionalRequirePaths : ['./shared', './node_modules'], + assetExts: ["*.svg", "*.png", "*.jpg", "*.pdf", "*.eot", "*.otf", "*.woff", "*.woff2", "*.ico", "*.ttf"], + serverWatchPaths: ["server"], + serverScript: "server.js", + libs: [ + "react", + "react-dom", + "lodash", + "classnames", + + //From ./shared + "codemirror", + "codemirror/mode/gfm/gfm.js", + 'codemirror/mode/javascript/javascript.js', + + "moment", + "superagent", + "marked", + "pico-router", + "pico-flux" + ], + clientLibs: [], +}); + + +var rename = require('gulp-rename'); +var less = require('gulp-less'); +gulp.task('phb', function(){ + gulp.src('./client/homebrew/phbStyle/phb.style.less') + .pipe(less()) + .pipe(rename('phb.standalone.css')) + .pipe(gulp.dest('./')); +}) + diff --git a/package.json b/package.json index 7fc86b1..b3a662a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "naturalcrit", "description": "D&D Tools for the discerning DM", - "version": "2.0.6", + "version": "2.1.0", "scripts": { "postinstall": "gulp prod", "start": "node server.js" diff --git a/phb.standalone.css b/phb.standalone.css index 2adf8fd..eeadfc2 100644 --- a/phb.standalone.css +++ b/phb.standalone.css @@ -208,21 +208,25 @@ table { } .phb p + p { margin-top: -0.8em; - text-indent: 1em; } .phb ul { margin-bottom: 0.8em; + padding-left: 1.4em; line-height: 1.3em; list-style-position: outside; list-style-type: disc; - padding-left: 1.4em; } .phb ol { margin-bottom: 0.8em; + padding-left: 1.4em; line-height: 1.3em; list-style-position: outside; list-style-type: decimal; - padding-left: 1.4em; +} +.phb p + p, +.phb ul + p, +.phb ol + p { + text-indent: 1em; } .phb img { z-index: -1; @@ -384,8 +388,8 @@ table { margin: 0; column-span: 1; background-color: transparent; - border-image: none; border-style: none; + border-image: none; -webkit-column-span: 1; } .phb hr + blockquote hr + table tbody tr:nth-child(odd), @@ -492,7 +496,8 @@ table { -webkit-column-span: all; -moz-column-span: all; } -.phb pre { +.phb pre, +.phb code { visibility: hidden; -webkit-column-break-after: always; break-after: always; @@ -521,6 +526,38 @@ table { margin-bottom: 0px; margin-left: 1.5em; } +.phb .spellList { + font-family: ScalySans; + column-count: 4; + column-span: all; + -webkit-column-span: all; + -moz-column-span: all; +} +.phb .spellList em { + font-family: ScalySans; + font-style: italic; +} +.phb .spellList strong { + font-family: ScalySans; + font-weight: 800; + letter-spacing: -0.02em; +} +.phb .spellList ul + h5 { + margin-top: 15px; +} +.phb .spellList p, +.phb .spellList ul { + font-size: 0.352cm; + line-height: 1.3em; +} +.phb .spellList ul { + margin-bottom: 0.5em; + padding-left: 1em; + text-indent: -1em; + list-style-type: none; + -webkit-column-break-inside: auto; + column-break-inside: auto; +} .phb.print blockquote { box-shadow: none; } diff --git a/server.js b/server.js index 038066a..93064a9 100644 --- a/server.js +++ b/server.js @@ -1,67 +1,67 @@ -'use strict'; -var _ = require('lodash'); -require('app-module-path').addPath('./shared'); -var vitreumRender = require('vitreum/render'); -var bodyParser = require('body-parser') -var express = require("express"); -var app = express(); -app.use(express.static(__dirname + '/build')); -app.use(bodyParser.json({limit: '25mb'})); - -//Mongoose -var mongoose = require('mongoose'); -var mongoUri = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || 'mongodb://localhost/naturalcrit'; -mongoose.connect(mongoUri); -mongoose.connection.on('error', function(){ - console.log(">>>ERROR: Run Mongodb.exe ya goof!"); -}); - -//Admin route -process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; -process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password'; -process.env.ADMIN_KEY = process.env.ADMIN_KEY || 'admin_key'; -var auth = require('basic-auth'); -app.get('/admin', function(req, res){ - var credentials = auth(req) - if (!credentials || credentials.name !== process.env.ADMIN_USER || credentials.pass !== process.env.ADMIN_PASS) { - res.setHeader('WWW-Authenticate', 'Basic realm="example"') - return res.status(401).send('Access denied') - } - vitreumRender({ - page: './build/admin/bundle.dot', - prerenderWith : './client/admin/admin.jsx', - clearRequireCache : !process.env.PRODUCTION, - initialProps: { - url: req.originalUrl, - admin_key : process.env.ADMIN_KEY, - }, - }, function (err, page) { - return res.send(page) - }); -}); - - -//Populate homebrew routes -app = require('./server/homebrew.api.js')(app); -app = require('./server/homebrew.server.js')(app); - - - -app.get('*', function (req, res) { - vitreumRender({ - page: './build/main/bundle.dot', - globals:{}, - prerenderWith : './client/main/main.jsx', - initialProps: { - url: req.originalUrl - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); -}); - - -var port = process.env.PORT || 8000; -app.listen(port); +'use strict'; +var _ = require('lodash'); +require('app-module-path').addPath('./shared'); +var vitreumRender = require('vitreum/render'); +var bodyParser = require('body-parser') +var express = require("express"); +var app = express(); +app.use(express.static(__dirname + '/build')); +app.use(bodyParser.json({limit: '25mb'})); + +//Mongoose +var mongoose = require('mongoose'); +var mongoUri = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || 'mongodb://localhost/naturalcrit'; +mongoose.connect(mongoUri); +mongoose.connection.on('error', function(){ + console.log(">>>ERROR: Run Mongodb.exe ya goof!"); +}); + +//Admin route +process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; +process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password'; +process.env.ADMIN_KEY = process.env.ADMIN_KEY || 'admin_key'; +var auth = require('basic-auth'); +app.get('/admin', function(req, res){ + var credentials = auth(req) + if (!credentials || credentials.name !== process.env.ADMIN_USER || credentials.pass !== process.env.ADMIN_PASS) { + res.setHeader('WWW-Authenticate', 'Basic realm="example"') + return res.status(401).send('Access denied') + } + vitreumRender({ + page: './build/admin/bundle.dot', + prerenderWith : './client/admin/admin.jsx', + clearRequireCache : !process.env.PRODUCTION, + initialProps: { + url: req.originalUrl, + admin_key : process.env.ADMIN_KEY, + }, + }, function (err, page) { + return res.send(page) + }); +}); + + +//Populate homebrew routes +app = require('./server/homebrew.api.js')(app); +app = require('./server/homebrew.server.js')(app); + + + +app.get('*', function (req, res) { + vitreumRender({ + page: './build/main/bundle.dot', + globals:{}, + prerenderWith : './client/main/main.jsx', + initialProps: { + url: req.originalUrl + }, + clearRequireCache : !process.env.PRODUCTION, + }, function (err, page) { + return res.send(page) + }); +}); + + +var port = process.env.PORT || 8000; +app.listen(port); console.log('Listening on localhost:' + port); \ No newline at end of file diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 9a630ce..f3020de 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -1,133 +1,133 @@ -var _ = require('lodash'); -var Moment = require('moment'); -var HomebrewModel = require('./homebrew.model.js').model; - -var homebrewTotal = 0; -var refreshCount = function(){ - HomebrewModel.count({}, function(err, total){ - homebrewTotal = total; - }); -}; -refreshCount() - -var mw = { - adminOnly : function(req, res, next){ - if(req.query && req.query.admin_key == process.env.ADMIN_KEY){ - next(); - }else{ - return res.status(401).send('Access denied'); - } - } -}; - - -var getTopBrews = function(cb){ - HomebrewModel.find().sort({views: -1}).limit(5).exec(function(err, brews) { - cb(brews); - }); -} - - -module.exports = function(app){ - - app.get('/homebrew/top', function(req, res){ - getTopBrews(function(topBrews){ - return res.json(topBrews); - }); - }); - - app.post('/homebrew/api', function(req, res){ - var newHomebrew = new HomebrewModel(req.body); - newHomebrew.save(function(err, obj){ - if(err) return; - return res.json(obj); - }) - }); - - app.put('/homebrew/api/update/:id', function(req, res){ - HomebrewModel.find({editId : req.params.id}, function(err, objs){ - if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); - var resEntry = objs[0]; - resEntry.text = req.body.text; - resEntry.title = req.body.title; - resEntry.updatedAt = new Date(); - resEntry.save(function(err, obj){ - if(err) return res.status(500).send("Error while saving"); - return res.status(200).send(obj); - }) - }); - }); - - app.get('/homebrew/api/remove/:id', function(req, res){ - HomebrewModel.find({editId : req.params.id}, function(err, objs){ - if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); - var resEntry = objs[0]; - resEntry.remove(function(err){ - if(err) return res.status(500).send("Error while removing"); - return res.status(200).send(); - }) - }); - }); - - //Removes all empty brews that are older than 3 days and that are shorter than a tweet - app.get('/homebrew/api/invalid', mw.adminOnly, function(req, res){ - var invalidBrewQuery = HomebrewModel.find({ - '$where' : "this.text.length < 140", - createdAt: { - $lt: Moment().subtract(3, 'days').toDate() - } - }); - - if(req.query.do_it){ - invalidBrewQuery.remove().exec((err, objs)=>{ - refreshCount(); - return res.send(200); - }) - }else{ - invalidBrewQuery.exec((err, objs)=>{ - if(err) console.log(err); - return res.json({ - count : objs.length - }) - }) - } - }); - - - app.get('/homebrew/api/search', mw.adminOnly, function(req, res){ - var page = req.query.page || 0; - var count = req.query.count || 20; - - var query = {}; - if(req.query && req.query.id){ - query = { - "$or" : [{ - editId : req.query.id - },{ - shareId : req.query.id - }] - }; - } - - HomebrewModel.find(query, { - text : 0 //omit the text - }, { - skip: page*count, - limit: count*1 - }, function(err, objs){ - if(err) console.log(err); - return res.json({ - page : page, - count : count, - total : homebrewTotal, - brews : objs - }); - - }); - }) - - - - - return app; +var _ = require('lodash'); +var Moment = require('moment'); +var HomebrewModel = require('./homebrew.model.js').model; + +var homebrewTotal = 0; +var refreshCount = function(){ + HomebrewModel.count({}, function(err, total){ + homebrewTotal = total; + }); +}; +refreshCount() + +var mw = { + adminOnly : function(req, res, next){ + if(req.query && req.query.admin_key == process.env.ADMIN_KEY){ + next(); + }else{ + return res.status(401).send('Access denied'); + } + } +}; + + +var getTopBrews = function(cb){ + HomebrewModel.find().sort({views: -1}).limit(5).exec(function(err, brews) { + cb(brews); + }); +} + + +module.exports = function(app){ + + app.get('/homebrew/top', function(req, res){ + getTopBrews(function(topBrews){ + return res.json(topBrews); + }); + }); + + app.post('/homebrew/api', function(req, res){ + var newHomebrew = new HomebrewModel(req.body); + newHomebrew.save(function(err, obj){ + if(err) return; + return res.json(obj); + }) + }); + + app.put('/homebrew/api/update/:id', function(req, res){ + HomebrewModel.find({editId : req.params.id}, function(err, objs){ + if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); + var resEntry = objs[0]; + resEntry.text = req.body.text; + resEntry.title = req.body.title; + resEntry.updatedAt = new Date(); + resEntry.save(function(err, obj){ + if(err) return res.status(500).send("Error while saving"); + return res.status(200).send(obj); + }) + }); + }); + + app.get('/homebrew/api/remove/:id', function(req, res){ + HomebrewModel.find({editId : req.params.id}, function(err, objs){ + if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); + var resEntry = objs[0]; + resEntry.remove(function(err){ + if(err) return res.status(500).send("Error while removing"); + return res.status(200).send(); + }) + }); + }); + + //Removes all empty brews that are older than 3 days and that are shorter than a tweet + app.get('/homebrew/api/invalid', mw.adminOnly, function(req, res){ + var invalidBrewQuery = HomebrewModel.find({ + '$where' : "this.text.length < 140", + createdAt: { + $lt: Moment().subtract(3, 'days').toDate() + } + }); + + if(req.query.do_it){ + invalidBrewQuery.remove().exec((err, objs)=>{ + refreshCount(); + return res.send(200); + }) + }else{ + invalidBrewQuery.exec((err, objs)=>{ + if(err) console.log(err); + return res.json({ + count : objs.length + }) + }) + } + }); + + + app.get('/homebrew/api/search', mw.adminOnly, function(req, res){ + var page = req.query.page || 0; + var count = req.query.count || 20; + + var query = {}; + if(req.query && req.query.id){ + query = { + "$or" : [{ + editId : req.query.id + },{ + shareId : req.query.id + }] + }; + } + + HomebrewModel.find(query, { + text : 0 //omit the text + }, { + skip: page*count, + limit: count*1 + }, function(err, objs){ + if(err) console.log(err); + return res.json({ + page : page, + count : count, + total : homebrewTotal, + brews : objs + }); + + }); + }) + + + + + return app; } \ No newline at end of file diff --git a/server/homebrew.model.js b/server/homebrew.model.js index d20b758..e7d89b9 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -1,24 +1,24 @@ -var mongoose = require('mongoose'); -var shortid = require('shortid'); -var _ = require('lodash'); - -var HomebrewSchema = mongoose.Schema({ - shareId : {type : String, default: shortid.generate, index: { unique: true }}, - editId : {type : String, default: shortid.generate, index: { unique: true }}, - title : {type : String, default : ""}, - text : {type : String, default : ""}, - - createdAt : { type: Date, default: Date.now }, - updatedAt : { type: Date, default: Date.now}, - lastViewed : { type: Date, default: Date.now}, - views : {type:Number, default:0} -}); - - - -var Homebrew = mongoose.model('Homebrew', HomebrewSchema); - -module.exports = { - schema : HomebrewSchema, - model : Homebrew, +var mongoose = require('mongoose'); +var shortid = require('shortid'); +var _ = require('lodash'); + +var HomebrewSchema = mongoose.Schema({ + shareId : {type : String, default: shortid.generate, index: { unique: true }}, + editId : {type : String, default: shortid.generate, index: { unique: true }}, + title : {type : String, default : ""}, + text : {type : String, default : ""}, + + createdAt : { type: Date, default: Date.now }, + updatedAt : { type: Date, default: Date.now}, + lastViewed : { type: Date, default: Date.now}, + views : {type:Number, default:0} +}); + + + +var Homebrew = mongoose.model('Homebrew', HomebrewSchema); + +module.exports = { + schema : HomebrewSchema, + model : Homebrew, } \ No newline at end of file diff --git a/server/homebrew.server.js b/server/homebrew.server.js index 7ea9099..27d6699 100644 --- a/server/homebrew.server.js +++ b/server/homebrew.server.js @@ -1,135 +1,135 @@ -var _ = require('lodash'); -var vitreumRender = require('vitreum/render'); -var HomebrewModel = require('./homebrew.model.js').model; - - - - -module.exports = function(app){ - - /* - app.get('/homebrew/new', function(req, res){ - var newHomebrew = new HomebrewModel(); - newHomebrew.save(function(err, obj){ - return res.redirect('/homebrew/edit/' + obj.editId); - }) - }) - */ - - - //Edit Page - app.get('/homebrew/edit/:id', function(req, res){ - HomebrewModel.find({editId : req.params.id}, function(err, objs){ - if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); - - var resObj = null; - var errObj = {text: "# oops\nCould not find the homebrew."} - if(objs.length){ - resObj = objs[0]; - } - - vitreumRender({ - page: './build/homebrew/bundle.dot', - globals:{}, - prerenderWith : './client/homebrew/homebrew.jsx', - initialProps: { - url: req.originalUrl, - brew : resObj || errObj - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); - }) - }); - - - //Share Page - app.get('/homebrew/share/:id', function(req, res){ - HomebrewModel.find({shareId : req.params.id}, function(err, objs){ - if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); - - var resObj = null; - var errObj = {text: "# oops\nCould not find the homebrew."} - - if(objs.length){ - resObj = objs[0]; - resObj.lastViewed = new Date(); - resObj.views = resObj.views + 1; - resObj.save(); - } - - vitreumRender({ - page: './build/homebrew/bundle.dot', - globals:{}, - prerenderWith : './client/homebrew/homebrew.jsx', - initialProps: { - url: req.originalUrl, - brew : resObj || errObj - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); - }) - }); - - //Print Page - var Markdown = require('marked'); - var PHBStyle = '' - app.get('/homebrew/print/:id', function(req, res){ - HomebrewModel.find({shareId : req.params.id}, function(err, objs){ - if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); - - var brew = null; - if(objs.length){ - brew = objs[0]; - } - - var content = _.map(brew.text.split('\\page'), function(pageText){ - return '
' + Markdown(pageText) + '
'; - }).join('\n'); - - var dialog = ''; - if(req.query && req.query.dialog) dialog = 'onload="window.print()"'; - - var title = '' + brew.title + ''; - var page = `${title} ${PHBStyle}${content}` - - return res.send(page) - }); - }); - - //Source page - String.prototype.replaceAll = function(s,r){return this.split(s).join(r)} - app.get('/homebrew/source/:id', function(req, res){ - HomebrewModel.find({shareId : req.params.id}, function(err, objs){ - if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); - var brew = null; - if(objs.length) brew = objs[0]; - var text = brew.text.replaceAll('<', '<').replaceAll('>', '>'); - return res.send(`
${text}
`); - }); - }); - - //Home and 404, etc. - var welcomeText = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg.txt', 'utf8'); - var changelogText = require('fs').readFileSync('./changelog.md', 'utf8'); - app.get('/homebrew*', function (req, res) { - vitreumRender({ - page: './build/homebrew/bundle.dot', - globals:{}, - prerenderWith : './client/homebrew/homebrew.jsx', - initialProps: { - url: req.originalUrl, - welcomeText : welcomeText, - changelog : changelogText - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); - }); - - return app; +var _ = require('lodash'); +var vitreumRender = require('vitreum/render'); +var HomebrewModel = require('./homebrew.model.js').model; + + + + +module.exports = function(app){ + + /* + app.get('/homebrew/new', function(req, res){ + var newHomebrew = new HomebrewModel(); + newHomebrew.save(function(err, obj){ + return res.redirect('/homebrew/edit/' + obj.editId); + }) + }) + */ + + + //Edit Page + app.get('/homebrew/edit/:id', function(req, res){ + HomebrewModel.find({editId : req.params.id}, function(err, objs){ + if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); + + var resObj = null; + var errObj = {text: "# oops\nCould not find the homebrew."} + if(objs.length){ + resObj = objs[0]; + } + + vitreumRender({ + page: './build/homebrew/bundle.dot', + globals:{}, + prerenderWith : './client/homebrew/homebrew.jsx', + initialProps: { + url: req.originalUrl, + brew : resObj || errObj + }, + clearRequireCache : !process.env.PRODUCTION, + }, function (err, page) { + return res.send(page) + }); + }) + }); + + + //Share Page + app.get('/homebrew/share/:id', function(req, res){ + HomebrewModel.find({shareId : req.params.id}, function(err, objs){ + if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); + + var resObj = null; + var errObj = {text: "# oops\nCould not find the homebrew."} + + if(objs.length){ + resObj = objs[0]; + resObj.lastViewed = new Date(); + resObj.views = resObj.views + 1; + resObj.save(); + } + + vitreumRender({ + page: './build/homebrew/bundle.dot', + globals:{}, + prerenderWith : './client/homebrew/homebrew.jsx', + initialProps: { + url: req.originalUrl, + brew : resObj || errObj + }, + clearRequireCache : !process.env.PRODUCTION, + }, function (err, page) { + return res.send(page) + }); + }) + }); + + //Print Page + var Markdown = require('marked'); + var PHBStyle = '' + app.get('/homebrew/print/:id', function(req, res){ + HomebrewModel.find({shareId : req.params.id}, function(err, objs){ + if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); + + var brew = null; + if(objs.length){ + brew = objs[0]; + } + + var content = _.map(brew.text.split('\\page'), function(pageText){ + return '
' + Markdown(pageText) + '
'; + }).join('\n'); + + var dialog = ''; + if(req.query && req.query.dialog) dialog = 'onload="window.print()"'; + + var title = '' + brew.title + ''; + var page = `${title} ${PHBStyle}${content}` + + return res.send(page) + }); + }); + + //Source page + String.prototype.replaceAll = function(s,r){return this.split(s).join(r)} + app.get('/homebrew/source/:id', function(req, res){ + HomebrewModel.find({shareId : req.params.id}, function(err, objs){ + if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); + var brew = null; + if(objs.length) brew = objs[0]; + var text = brew.text.replaceAll('<', '<').replaceAll('>', '>'); + return res.send(`
${text}
`); + }); + }); + + //Home and 404, etc. + var welcomeText = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg.txt', 'utf8'); + var changelogText = require('fs').readFileSync('./changelog.md', 'utf8'); + app.get('/homebrew*', function (req, res) { + vitreumRender({ + page: './build/homebrew/bundle.dot', + globals:{}, + prerenderWith : './client/homebrew/homebrew.jsx', + initialProps: { + url: req.originalUrl, + welcomeText : welcomeText, + changelog : changelogText + }, + clearRequireCache : !process.env.PRODUCTION, + }, function (err, page) { + return res.send(page) + }); + }); + + return app; } \ No newline at end of file diff --git a/shared/codemirror/addon/comment/comment.js b/shared/codemirror/addon/comment/comment.js index 2c4f975..df2c93e 100644 --- a/shared/codemirror/addon/comment/comment.js +++ b/shared/codemirror/addon/comment/comment.js @@ -1,203 +1,203 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var noOptions = {}; - var nonWS = /[^\s\u00a0]/; - var Pos = CodeMirror.Pos; - - function firstNonWS(str) { - var found = str.search(nonWS); - return found == -1 ? 0 : found; - } - - CodeMirror.commands.toggleComment = function(cm) { - cm.toggleComment(); - }; - - CodeMirror.defineExtension("toggleComment", function(options) { - if (!options) options = noOptions; - var cm = this; - var minLine = Infinity, ranges = this.listSelections(), mode = null; - for (var i = ranges.length - 1; i >= 0; i--) { - var from = ranges[i].from(), to = ranges[i].to(); - if (from.line >= minLine) continue; - if (to.line >= minLine) to = Pos(minLine, 0); - minLine = from.line; - if (mode == null) { - if (cm.uncomment(from, to, options)) mode = "un"; - else { cm.lineComment(from, to, options); mode = "line"; } - } else if (mode == "un") { - cm.uncomment(from, to, options); - } else { - cm.lineComment(from, to, options); - } - } - }); - - // Rough heuristic to try and detect lines that are part of multi-line string - function probablyInsideString(cm, pos, line) { - return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"`]/.test(line) - } - - CodeMirror.defineExtension("lineComment", function(from, to, options) { - if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); - var firstLine = self.getLine(from.line); - if (firstLine == null || probablyInsideString(self, from, firstLine)) return; - - var commentString = options.lineComment || mode.lineComment; - if (!commentString) { - if (options.blockCommentStart || mode.blockCommentStart) { - options.fullLines = true; - self.blockComment(from, to, options); - } - return; - } - - var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); - var pad = options.padding == null ? " " : options.padding; - var blankLines = options.commentBlankLines || from.line == to.line; - - self.operation(function() { - if (options.indent) { - var baseString = null; - for (var i = from.line; i < end; ++i) { - var line = self.getLine(i); - var whitespace = line.slice(0, firstNonWS(line)); - if (baseString == null || baseString.length > whitespace.length) { - baseString = whitespace; - } - } - for (var i = from.line; i < end; ++i) { - var line = self.getLine(i), cut = baseString.length; - if (!blankLines && !nonWS.test(line)) continue; - if (line.slice(0, cut) != baseString) cut = firstNonWS(line); - self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); - } - } else { - for (var i = from.line; i < end; ++i) { - if (blankLines || nonWS.test(self.getLine(i))) - self.replaceRange(commentString + pad, Pos(i, 0)); - } - } - }); - }); - - CodeMirror.defineExtension("blockComment", function(from, to, options) { - if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); - var startString = options.blockCommentStart || mode.blockCommentStart; - var endString = options.blockCommentEnd || mode.blockCommentEnd; - if (!startString || !endString) { - if ((options.lineComment || mode.lineComment) && options.fullLines != false) - self.lineComment(from, to, options); - return; - } - - var end = Math.min(to.line, self.lastLine()); - if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; - - var pad = options.padding == null ? " " : options.padding; - if (from.line > end) return; - - self.operation(function() { - if (options.fullLines != false) { - var lastLineHasText = nonWS.test(self.getLine(end)); - self.replaceRange(pad + endString, Pos(end)); - self.replaceRange(startString + pad, Pos(from.line, 0)); - var lead = options.blockCommentLead || mode.blockCommentLead; - if (lead != null) for (var i = from.line + 1; i <= end; ++i) - if (i != end || lastLineHasText) - self.replaceRange(lead + pad, Pos(i, 0)); - } else { - self.replaceRange(endString, to); - self.replaceRange(startString, from); - } - }); - }); - - CodeMirror.defineExtension("uncomment", function(from, to, options) { - if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); - var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end); - - // Try finding line comments - var lineString = options.lineComment || mode.lineComment, lines = []; - var pad = options.padding == null ? " " : options.padding, didSomething; - lineComment: { - if (!lineString) break lineComment; - for (var i = start; i <= end; ++i) { - var line = self.getLine(i); - var found = line.indexOf(lineString); - if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; - if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; - if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; - lines.push(line); - } - self.operation(function() { - for (var i = start; i <= end; ++i) { - var line = lines[i - start]; - var pos = line.indexOf(lineString), endPos = pos + lineString.length; - if (pos < 0) continue; - if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; - didSomething = true; - self.replaceRange("", Pos(i, pos), Pos(i, endPos)); - } - }); - if (didSomething) return true; - } - - // Try block comments - var startString = options.blockCommentStart || mode.blockCommentStart; - var endString = options.blockCommentEnd || mode.blockCommentEnd; - if (!startString || !endString) return false; - var lead = options.blockCommentLead || mode.blockCommentLead; - var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); - var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); - if (close == -1 && start != end) { - endLine = self.getLine(--end); - close = endLine.lastIndexOf(endString); - } - if (open == -1 || close == -1 || - !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || - !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) - return false; - - // Avoid killing block comments completely outside the selection. - // Positions of the last startString before the start of the selection, and the first endString after it. - var lastStart = startLine.lastIndexOf(startString, from.ch); - var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length); - if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false; - // Positions of the first endString after the end of the selection, and the last startString before it. - firstEnd = endLine.indexOf(endString, to.ch); - var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch); - lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart; - if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false; - - self.operation(function() { - self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), - Pos(end, close + endString.length)); - var openEnd = open + startString.length; - if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; - self.replaceRange("", Pos(start, open), Pos(start, openEnd)); - if (lead) for (var i = start + 1; i <= end; ++i) { - var line = self.getLine(i), found = line.indexOf(lead); - if (found == -1 || nonWS.test(line.slice(0, found))) continue; - var foundEnd = found + lead.length; - if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; - self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); - } - }); - return true; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var noOptions = {}; + var nonWS = /[^\s\u00a0]/; + var Pos = CodeMirror.Pos; + + function firstNonWS(str) { + var found = str.search(nonWS); + return found == -1 ? 0 : found; + } + + CodeMirror.commands.toggleComment = function(cm) { + cm.toggleComment(); + }; + + CodeMirror.defineExtension("toggleComment", function(options) { + if (!options) options = noOptions; + var cm = this; + var minLine = Infinity, ranges = this.listSelections(), mode = null; + for (var i = ranges.length - 1; i >= 0; i--) { + var from = ranges[i].from(), to = ranges[i].to(); + if (from.line >= minLine) continue; + if (to.line >= minLine) to = Pos(minLine, 0); + minLine = from.line; + if (mode == null) { + if (cm.uncomment(from, to, options)) mode = "un"; + else { cm.lineComment(from, to, options); mode = "line"; } + } else if (mode == "un") { + cm.uncomment(from, to, options); + } else { + cm.lineComment(from, to, options); + } + } + }); + + // Rough heuristic to try and detect lines that are part of multi-line string + function probablyInsideString(cm, pos, line) { + return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"`]/.test(line) + } + + CodeMirror.defineExtension("lineComment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var firstLine = self.getLine(from.line); + if (firstLine == null || probablyInsideString(self, from, firstLine)) return; + + var commentString = options.lineComment || mode.lineComment; + if (!commentString) { + if (options.blockCommentStart || mode.blockCommentStart) { + options.fullLines = true; + self.blockComment(from, to, options); + } + return; + } + + var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); + var pad = options.padding == null ? " " : options.padding; + var blankLines = options.commentBlankLines || from.line == to.line; + + self.operation(function() { + if (options.indent) { + var baseString = null; + for (var i = from.line; i < end; ++i) { + var line = self.getLine(i); + var whitespace = line.slice(0, firstNonWS(line)); + if (baseString == null || baseString.length > whitespace.length) { + baseString = whitespace; + } + } + for (var i = from.line; i < end; ++i) { + var line = self.getLine(i), cut = baseString.length; + if (!blankLines && !nonWS.test(line)) continue; + if (line.slice(0, cut) != baseString) cut = firstNonWS(line); + self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); + } + } else { + for (var i = from.line; i < end; ++i) { + if (blankLines || nonWS.test(self.getLine(i))) + self.replaceRange(commentString + pad, Pos(i, 0)); + } + } + }); + }); + + CodeMirror.defineExtension("blockComment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var startString = options.blockCommentStart || mode.blockCommentStart; + var endString = options.blockCommentEnd || mode.blockCommentEnd; + if (!startString || !endString) { + if ((options.lineComment || mode.lineComment) && options.fullLines != false) + self.lineComment(from, to, options); + return; + } + + var end = Math.min(to.line, self.lastLine()); + if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; + + var pad = options.padding == null ? " " : options.padding; + if (from.line > end) return; + + self.operation(function() { + if (options.fullLines != false) { + var lastLineHasText = nonWS.test(self.getLine(end)); + self.replaceRange(pad + endString, Pos(end)); + self.replaceRange(startString + pad, Pos(from.line, 0)); + var lead = options.blockCommentLead || mode.blockCommentLead; + if (lead != null) for (var i = from.line + 1; i <= end; ++i) + if (i != end || lastLineHasText) + self.replaceRange(lead + pad, Pos(i, 0)); + } else { + self.replaceRange(endString, to); + self.replaceRange(startString, from); + } + }); + }); + + CodeMirror.defineExtension("uncomment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end); + + // Try finding line comments + var lineString = options.lineComment || mode.lineComment, lines = []; + var pad = options.padding == null ? " " : options.padding, didSomething; + lineComment: { + if (!lineString) break lineComment; + for (var i = start; i <= end; ++i) { + var line = self.getLine(i); + var found = line.indexOf(lineString); + if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; + if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; + if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; + lines.push(line); + } + self.operation(function() { + for (var i = start; i <= end; ++i) { + var line = lines[i - start]; + var pos = line.indexOf(lineString), endPos = pos + lineString.length; + if (pos < 0) continue; + if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; + didSomething = true; + self.replaceRange("", Pos(i, pos), Pos(i, endPos)); + } + }); + if (didSomething) return true; + } + + // Try block comments + var startString = options.blockCommentStart || mode.blockCommentStart; + var endString = options.blockCommentEnd || mode.blockCommentEnd; + if (!startString || !endString) return false; + var lead = options.blockCommentLead || mode.blockCommentLead; + var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); + var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); + if (close == -1 && start != end) { + endLine = self.getLine(--end); + close = endLine.lastIndexOf(endString); + } + if (open == -1 || close == -1 || + !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || + !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) + return false; + + // Avoid killing block comments completely outside the selection. + // Positions of the last startString before the start of the selection, and the first endString after it. + var lastStart = startLine.lastIndexOf(startString, from.ch); + var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length); + if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false; + // Positions of the first endString after the end of the selection, and the last startString before it. + firstEnd = endLine.indexOf(endString, to.ch); + var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch); + lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart; + if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false; + + self.operation(function() { + self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), + Pos(end, close + endString.length)); + var openEnd = open + startString.length; + if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; + self.replaceRange("", Pos(start, open), Pos(start, openEnd)); + if (lead) for (var i = start + 1; i <= end; ++i) { + var line = self.getLine(i), found = line.indexOf(lead); + if (found == -1 || nonWS.test(line.slice(0, found))) continue; + var foundEnd = found + lead.length; + if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; + self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); + } + }); + return true; + }); +}); diff --git a/shared/codemirror/addon/comment/continuecomment.js b/shared/codemirror/addon/comment/continuecomment.js deleted file mode 100644 index b11d51e..0000000 --- a/shared/codemirror/addon/comment/continuecomment.js +++ /dev/null @@ -1,85 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - var modes = ["clike", "css", "javascript"]; - - for (var i = 0; i < modes.length; ++i) - CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "}); - - function continueComment(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - var ranges = cm.listSelections(), mode, inserts = []; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].head, token = cm.getTokenAt(pos); - if (token.type != "comment") return CodeMirror.Pass; - var modeHere = CodeMirror.innerMode(cm.getMode(), token.state).mode; - if (!mode) mode = modeHere; - else if (mode != modeHere) return CodeMirror.Pass; - - var insert = null; - if (mode.blockCommentStart && mode.blockCommentContinue) { - var end = token.string.indexOf(mode.blockCommentEnd); - var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found; - if (end != -1 && end == token.string.length - mode.blockCommentEnd.length && pos.ch >= end) { - // Comment ended, don't continue it - } else if (token.string.indexOf(mode.blockCommentStart) == 0) { - insert = full.slice(0, token.start); - if (!/^\s*$/.test(insert)) { - insert = ""; - for (var j = 0; j < token.start; ++j) insert += " "; - } - } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 && - found + mode.blockCommentContinue.length > token.start && - /^\s*$/.test(full.slice(0, found))) { - insert = full.slice(0, found); - } - if (insert != null) insert += mode.blockCommentContinue; - } - if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) { - var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); - if (found > -1) { - insert = line.slice(0, found); - if (/\S/.test(insert)) insert = null; - else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0]; - } - } - if (insert == null) return CodeMirror.Pass; - inserts[i] = "\n" + insert; - } - - cm.operation(function() { - for (var i = ranges.length - 1; i >= 0; i--) - cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert"); - }); - } - - function continueLineCommentEnabled(cm) { - var opt = cm.getOption("continueComments"); - if (opt && typeof opt == "object") - return opt.continueLineComment !== false; - return true; - } - - CodeMirror.defineOption("continueComments", null, function(cm, val, prev) { - if (prev && prev != CodeMirror.Init) - cm.removeKeyMap("continueComment"); - if (val) { - var key = "Enter"; - if (typeof val == "string") - key = val; - else if (typeof val == "object" && val.key) - key = val.key; - var map = {name: "continueComment"}; - map[key] = continueComment; - cm.addKeyMap(map); - } - }); -}); diff --git a/shared/codemirror/addon/dialog/dialog.css b/shared/codemirror/addon/dialog/dialog.css deleted file mode 100644 index 677c078..0000000 --- a/shared/codemirror/addon/dialog/dialog.css +++ /dev/null @@ -1,32 +0,0 @@ -.CodeMirror-dialog { - position: absolute; - left: 0; right: 0; - background: inherit; - z-index: 15; - padding: .1em .8em; - overflow: hidden; - color: inherit; -} - -.CodeMirror-dialog-top { - border-bottom: 1px solid #eee; - top: 0; -} - -.CodeMirror-dialog-bottom { - border-top: 1px solid #eee; - bottom: 0; -} - -.CodeMirror-dialog input { - border: none; - outline: none; - background: transparent; - width: 20em; - color: inherit; - font-family: monospace; -} - -.CodeMirror-dialog button { - font-size: 70%; -} diff --git a/shared/codemirror/addon/dialog/dialog.js b/shared/codemirror/addon/dialog/dialog.js index f10bb5b..825105b 100644 --- a/shared/codemirror/addon/dialog/dialog.js +++ b/shared/codemirror/addon/dialog/dialog.js @@ -1,157 +1,157 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Open simple dialogs on top of an editor. Relies on dialog.css. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - function dialogDiv(cm, template, bottom) { - var wrap = cm.getWrapperElement(); - var dialog; - dialog = wrap.appendChild(document.createElement("div")); - if (bottom) - dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; - else - dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; - - if (typeof template == "string") { - dialog.innerHTML = template; - } else { // Assuming it's a detached DOM element. - dialog.appendChild(template); - } - return dialog; - } - - function closeNotification(cm, newVal) { - if (cm.state.currentNotificationClose) - cm.state.currentNotificationClose(); - cm.state.currentNotificationClose = newVal; - } - - CodeMirror.defineExtension("openDialog", function(template, callback, options) { - if (!options) options = {}; - - closeNotification(this, null); - - var dialog = dialogDiv(this, template, options.bottom); - var closed = false, me = this; - function close(newVal) { - if (typeof newVal == 'string') { - inp.value = newVal; - } else { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); - - if (options.onClose) options.onClose(dialog); - } - } - - var inp = dialog.getElementsByTagName("input")[0], button; - if (inp) { - inp.focus(); - - if (options.value) { - inp.value = options.value; - if (options.selectValueOnOpen !== false) { - inp.select(); - } - } - - if (options.onInput) - CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); - if (options.onKeyUp) - CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); - - CodeMirror.on(inp, "keydown", function(e) { - if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } - if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { - inp.blur(); - CodeMirror.e_stop(e); - close(); - } - if (e.keyCode == 13) callback(inp.value, e); - }); - - if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); - } else if (button = dialog.getElementsByTagName("button")[0]) { - CodeMirror.on(button, "click", function() { - close(); - me.focus(); - }); - - if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); - - button.focus(); - } - return close; - }); - - CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { - closeNotification(this, null); - var dialog = dialogDiv(this, template, options && options.bottom); - var buttons = dialog.getElementsByTagName("button"); - var closed = false, me = this, blurring = 1; - function close() { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); - } - buttons[0].focus(); - for (var i = 0; i < buttons.length; ++i) { - var b = buttons[i]; - (function(callback) { - CodeMirror.on(b, "click", function(e) { - CodeMirror.e_preventDefault(e); - close(); - if (callback) callback(me); - }); - })(callbacks[i]); - CodeMirror.on(b, "blur", function() { - --blurring; - setTimeout(function() { if (blurring <= 0) close(); }, 200); - }); - CodeMirror.on(b, "focus", function() { ++blurring; }); - } - }); - - /* - * openNotification - * Opens a notification, that can be closed with an optional timer - * (default 5000ms timer) and always closes on click. - * - * If a notification is opened while another is opened, it will close the - * currently opened one and open the new one immediately. - */ - CodeMirror.defineExtension("openNotification", function(template, options) { - closeNotification(this, close); - var dialog = dialogDiv(this, template, options && options.bottom); - var closed = false, doneTimer; - var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; - - function close() { - if (closed) return; - closed = true; - clearTimeout(doneTimer); - dialog.parentNode.removeChild(dialog); - } - - CodeMirror.on(dialog, 'click', function(e) { - CodeMirror.e_preventDefault(e); - close(); - }); - - if (duration) - doneTimer = setTimeout(close, duration); - - return close; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Open simple dialogs on top of an editor. Relies on dialog.css. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + function dialogDiv(cm, template, bottom) { + var wrap = cm.getWrapperElement(); + var dialog; + dialog = wrap.appendChild(document.createElement("div")); + if (bottom) + dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; + else + dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; + + if (typeof template == "string") { + dialog.innerHTML = template; + } else { // Assuming it's a detached DOM element. + dialog.appendChild(template); + } + return dialog; + } + + function closeNotification(cm, newVal) { + if (cm.state.currentNotificationClose) + cm.state.currentNotificationClose(); + cm.state.currentNotificationClose = newVal; + } + + CodeMirror.defineExtension("openDialog", function(template, callback, options) { + if (!options) options = {}; + + closeNotification(this, null); + + var dialog = dialogDiv(this, template, options.bottom); + var closed = false, me = this; + function close(newVal) { + if (typeof newVal == 'string') { + inp.value = newVal; + } else { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + me.focus(); + + if (options.onClose) options.onClose(dialog); + } + } + + var inp = dialog.getElementsByTagName("input")[0], button; + if (inp) { + inp.focus(); + + if (options.value) { + inp.value = options.value; + if (options.selectValueOnOpen !== false) { + inp.select(); + } + } + + if (options.onInput) + CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); + if (options.onKeyUp) + CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); + + CodeMirror.on(inp, "keydown", function(e) { + if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } + if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { + inp.blur(); + CodeMirror.e_stop(e); + close(); + } + if (e.keyCode == 13) callback(inp.value, e); + }); + + if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); + } else if (button = dialog.getElementsByTagName("button")[0]) { + CodeMirror.on(button, "click", function() { + close(); + me.focus(); + }); + + if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); + + button.focus(); + } + return close; + }); + + CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { + closeNotification(this, null); + var dialog = dialogDiv(this, template, options && options.bottom); + var buttons = dialog.getElementsByTagName("button"); + var closed = false, me = this, blurring = 1; + function close() { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + me.focus(); + } + buttons[0].focus(); + for (var i = 0; i < buttons.length; ++i) { + var b = buttons[i]; + (function(callback) { + CodeMirror.on(b, "click", function(e) { + CodeMirror.e_preventDefault(e); + close(); + if (callback) callback(me); + }); + })(callbacks[i]); + CodeMirror.on(b, "blur", function() { + --blurring; + setTimeout(function() { if (blurring <= 0) close(); }, 200); + }); + CodeMirror.on(b, "focus", function() { ++blurring; }); + } + }); + + /* + * openNotification + * Opens a notification, that can be closed with an optional timer + * (default 5000ms timer) and always closes on click. + * + * If a notification is opened while another is opened, it will close the + * currently opened one and open the new one immediately. + */ + CodeMirror.defineExtension("openNotification", function(template, options) { + closeNotification(this, close); + var dialog = dialogDiv(this, template, options && options.bottom); + var closed = false, doneTimer; + var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; + + function close() { + if (closed) return; + closed = true; + clearTimeout(doneTimer); + dialog.parentNode.removeChild(dialog); + } + + CodeMirror.on(dialog, 'click', function(e) { + CodeMirror.e_preventDefault(e); + close(); + }); + + if (duration) + doneTimer = setTimeout(close, duration); + + return close; + }); +}); diff --git a/shared/codemirror/addon/display/autorefresh.js b/shared/codemirror/addon/display/autorefresh.js index 1e0e850..fb9346e 100644 --- a/shared/codemirror/addon/display/autorefresh.js +++ b/shared/codemirror/addon/display/autorefresh.js @@ -1,47 +1,47 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")) - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod) - else // Plain browser env - mod(CodeMirror) -})(function(CodeMirror) { - "use strict" - - CodeMirror.defineOption("autoRefresh", false, function(cm, val) { - if (cm.state.autoRefresh) { - stopListening(cm, cm.state.autoRefresh) - cm.state.autoRefresh = null - } - if (val && cm.display.wrapper.offsetHeight == 0) - startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250}) - }) - - function startListening(cm, state) { - function check() { - if (cm.display.wrapper.offsetHeight) { - stopListening(cm, state) - if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight) - cm.refresh() - } else { - state.timeout = setTimeout(check, state.delay) - } - } - state.timeout = setTimeout(check, state.delay) - state.hurry = function() { - clearTimeout(state.timeout) - state.timeout = setTimeout(check, 50) - } - CodeMirror.on(window, "mouseup", state.hurry) - CodeMirror.on(window, "keyup", state.hurry) - } - - function stopListening(_cm, state) { - clearTimeout(state.timeout) - CodeMirror.off(window, "mouseup", state.hurry) - CodeMirror.off(window, "keyup", state.hurry) - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")) + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod) + else // Plain browser env + mod(CodeMirror) +})(function(CodeMirror) { + "use strict" + + CodeMirror.defineOption("autoRefresh", false, function(cm, val) { + if (cm.state.autoRefresh) { + stopListening(cm, cm.state.autoRefresh) + cm.state.autoRefresh = null + } + if (val && cm.display.wrapper.offsetHeight == 0) + startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250}) + }) + + function startListening(cm, state) { + function check() { + if (cm.display.wrapper.offsetHeight) { + stopListening(cm, state) + if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight) + cm.refresh() + } else { + state.timeout = setTimeout(check, state.delay) + } + } + state.timeout = setTimeout(check, state.delay) + state.hurry = function() { + clearTimeout(state.timeout) + state.timeout = setTimeout(check, 50) + } + CodeMirror.on(window, "mouseup", state.hurry) + CodeMirror.on(window, "keyup", state.hurry) + } + + function stopListening(_cm, state) { + clearTimeout(state.timeout) + CodeMirror.off(window, "mouseup", state.hurry) + CodeMirror.off(window, "keyup", state.hurry) + } +}); diff --git a/shared/codemirror/addon/display/fullscreen.css b/shared/codemirror/addon/display/fullscreen.css index 437acd8..cbd5539 100644 --- a/shared/codemirror/addon/display/fullscreen.css +++ b/shared/codemirror/addon/display/fullscreen.css @@ -1,6 +1,6 @@ -.CodeMirror-fullscreen { - position: fixed; - top: 0; left: 0; right: 0; bottom: 0; - height: auto; - z-index: 9; -} +.CodeMirror-fullscreen { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + height: auto; + z-index: 9; +} diff --git a/shared/codemirror/addon/display/fullscreen.js b/shared/codemirror/addon/display/fullscreen.js index cd3673b..134e8ac 100644 --- a/shared/codemirror/addon/display/fullscreen.js +++ b/shared/codemirror/addon/display/fullscreen.js @@ -1,41 +1,41 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { - if (old == CodeMirror.Init) old = false; - if (!old == !val) return; - if (val) setFullscreen(cm); - else setNormal(cm); - }); - - function setFullscreen(cm) { - var wrap = cm.getWrapperElement(); - cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, - width: wrap.style.width, height: wrap.style.height}; - wrap.style.width = ""; - wrap.style.height = "auto"; - wrap.className += " CodeMirror-fullscreen"; - document.documentElement.style.overflow = "hidden"; - cm.refresh(); - } - - function setNormal(cm) { - var wrap = cm.getWrapperElement(); - wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); - document.documentElement.style.overflow = ""; - var info = cm.state.fullScreenRestore; - wrap.style.width = info.width; wrap.style.height = info.height; - window.scrollTo(info.scrollLeft, info.scrollTop); - cm.refresh(); - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { + if (old == CodeMirror.Init) old = false; + if (!old == !val) return; + if (val) setFullscreen(cm); + else setNormal(cm); + }); + + function setFullscreen(cm) { + var wrap = cm.getWrapperElement(); + cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, + width: wrap.style.width, height: wrap.style.height}; + wrap.style.width = ""; + wrap.style.height = "auto"; + wrap.className += " CodeMirror-fullscreen"; + document.documentElement.style.overflow = "hidden"; + cm.refresh(); + } + + function setNormal(cm) { + var wrap = cm.getWrapperElement(); + wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); + document.documentElement.style.overflow = ""; + var info = cm.state.fullScreenRestore; + wrap.style.width = info.width; wrap.style.height = info.height; + window.scrollTo(info.scrollLeft, info.scrollTop); + cm.refresh(); + } +}); diff --git a/shared/codemirror/addon/display/panel.js b/shared/codemirror/addon/display/panel.js index ba29484..34ccd61 100644 --- a/shared/codemirror/addon/display/panel.js +++ b/shared/codemirror/addon/display/panel.js @@ -1,112 +1,112 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - CodeMirror.defineExtension("addPanel", function(node, options) { - options = options || {}; - - if (!this.state.panels) initPanels(this); - - var info = this.state.panels; - var wrapper = info.wrapper; - var cmWrapper = this.getWrapperElement(); - - if (options.after instanceof Panel && !options.after.cleared) { - wrapper.insertBefore(node, options.before.node.nextSibling); - } else if (options.before instanceof Panel && !options.before.cleared) { - wrapper.insertBefore(node, options.before.node); - } else if (options.replace instanceof Panel && !options.replace.cleared) { - wrapper.insertBefore(node, options.replace.node); - options.replace.clear(); - } else if (options.position == "bottom") { - wrapper.appendChild(node); - } else if (options.position == "before-bottom") { - wrapper.insertBefore(node, cmWrapper.nextSibling); - } else if (options.position == "after-top") { - wrapper.insertBefore(node, cmWrapper); - } else { - wrapper.insertBefore(node, wrapper.firstChild); - } - - var height = (options && options.height) || node.offsetHeight; - this._setSize(null, info.heightLeft -= height); - info.panels++; - return new Panel(this, node, options, height); - }); - - function Panel(cm, node, options, height) { - this.cm = cm; - this.node = node; - this.options = options; - this.height = height; - this.cleared = false; - } - - Panel.prototype.clear = function() { - if (this.cleared) return; - this.cleared = true; - var info = this.cm.state.panels; - this.cm._setSize(null, info.heightLeft += this.height); - info.wrapper.removeChild(this.node); - if (--info.panels == 0) removePanels(this.cm); - }; - - Panel.prototype.changed = function(height) { - var newHeight = height == null ? this.node.offsetHeight : height; - var info = this.cm.state.panels; - this.cm._setSize(null, info.height += (newHeight - this.height)); - this.height = newHeight; - }; - - function initPanels(cm) { - var wrap = cm.getWrapperElement(); - var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle; - var height = parseInt(style.height); - var info = cm.state.panels = { - setHeight: wrap.style.height, - heightLeft: height, - panels: 0, - wrapper: document.createElement("div") - }; - wrap.parentNode.insertBefore(info.wrapper, wrap); - var hasFocus = cm.hasFocus(); - info.wrapper.appendChild(wrap); - if (hasFocus) cm.focus(); - - cm._setSize = cm.setSize; - if (height != null) cm.setSize = function(width, newHeight) { - if (newHeight == null) return this._setSize(width, newHeight); - info.setHeight = newHeight; - if (typeof newHeight != "number") { - var px = /^(\d+\.?\d*)px$/.exec(newHeight); - if (px) { - newHeight = Number(px[1]); - } else { - info.wrapper.style.height = newHeight; - newHeight = info.wrapper.offsetHeight; - info.wrapper.style.height = ""; - } - } - cm._setSize(width, info.heightLeft += (newHeight - height)); - height = newHeight; - }; - } - - function removePanels(cm) { - var info = cm.state.panels; - cm.state.panels = null; - - var wrap = cm.getWrapperElement(); - info.wrapper.parentNode.replaceChild(wrap, info.wrapper); - wrap.style.height = info.setHeight; - cm.setSize = cm._setSize; - cm.setSize(); - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineExtension("addPanel", function(node, options) { + options = options || {}; + + if (!this.state.panels) initPanels(this); + + var info = this.state.panels; + var wrapper = info.wrapper; + var cmWrapper = this.getWrapperElement(); + + if (options.after instanceof Panel && !options.after.cleared) { + wrapper.insertBefore(node, options.before.node.nextSibling); + } else if (options.before instanceof Panel && !options.before.cleared) { + wrapper.insertBefore(node, options.before.node); + } else if (options.replace instanceof Panel && !options.replace.cleared) { + wrapper.insertBefore(node, options.replace.node); + options.replace.clear(); + } else if (options.position == "bottom") { + wrapper.appendChild(node); + } else if (options.position == "before-bottom") { + wrapper.insertBefore(node, cmWrapper.nextSibling); + } else if (options.position == "after-top") { + wrapper.insertBefore(node, cmWrapper); + } else { + wrapper.insertBefore(node, wrapper.firstChild); + } + + var height = (options && options.height) || node.offsetHeight; + this._setSize(null, info.heightLeft -= height); + info.panels++; + return new Panel(this, node, options, height); + }); + + function Panel(cm, node, options, height) { + this.cm = cm; + this.node = node; + this.options = options; + this.height = height; + this.cleared = false; + } + + Panel.prototype.clear = function() { + if (this.cleared) return; + this.cleared = true; + var info = this.cm.state.panels; + this.cm._setSize(null, info.heightLeft += this.height); + info.wrapper.removeChild(this.node); + if (--info.panels == 0) removePanels(this.cm); + }; + + Panel.prototype.changed = function(height) { + var newHeight = height == null ? this.node.offsetHeight : height; + var info = this.cm.state.panels; + this.cm._setSize(null, info.height += (newHeight - this.height)); + this.height = newHeight; + }; + + function initPanels(cm) { + var wrap = cm.getWrapperElement(); + var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle; + var height = parseInt(style.height); + var info = cm.state.panels = { + setHeight: wrap.style.height, + heightLeft: height, + panels: 0, + wrapper: document.createElement("div") + }; + wrap.parentNode.insertBefore(info.wrapper, wrap); + var hasFocus = cm.hasFocus(); + info.wrapper.appendChild(wrap); + if (hasFocus) cm.focus(); + + cm._setSize = cm.setSize; + if (height != null) cm.setSize = function(width, newHeight) { + if (newHeight == null) return this._setSize(width, newHeight); + info.setHeight = newHeight; + if (typeof newHeight != "number") { + var px = /^(\d+\.?\d*)px$/.exec(newHeight); + if (px) { + newHeight = Number(px[1]); + } else { + info.wrapper.style.height = newHeight; + newHeight = info.wrapper.offsetHeight; + info.wrapper.style.height = ""; + } + } + cm._setSize(width, info.heightLeft += (newHeight - height)); + height = newHeight; + }; + } + + function removePanels(cm) { + var info = cm.state.panels; + cm.state.panels = null; + + var wrap = cm.getWrapperElement(); + info.wrapper.parentNode.replaceChild(wrap, info.wrapper); + wrap.style.height = info.setHeight; + cm.setSize = cm._setSize; + cm.setSize(); + } +}); diff --git a/shared/codemirror/addon/display/placeholder.js b/shared/codemirror/addon/display/placeholder.js index 2f8b1f8..e7fcfc3 100644 --- a/shared/codemirror/addon/display/placeholder.js +++ b/shared/codemirror/addon/display/placeholder.js @@ -1,62 +1,62 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - CodeMirror.defineOption("placeholder", "", function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.on("blur", onBlur); - cm.on("change", onChange); - cm.on("swapDoc", onChange); - onChange(cm); - } else if (!val && prev) { - cm.off("blur", onBlur); - cm.off("change", onChange); - cm.off("swapDoc", onChange); - clearPlaceholder(cm); - var wrapper = cm.getWrapperElement(); - wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); - } - - if (val && !cm.hasFocus()) onBlur(cm); - }); - - function clearPlaceholder(cm) { - if (cm.state.placeholder) { - cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); - cm.state.placeholder = null; - } - } - function setPlaceholder(cm) { - clearPlaceholder(cm); - var elt = cm.state.placeholder = document.createElement("pre"); - elt.style.cssText = "height: 0; overflow: visible"; - elt.className = "CodeMirror-placeholder"; - var placeHolder = cm.getOption("placeholder") - if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder) - elt.appendChild(placeHolder) - cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); - } - - function onBlur(cm) { - if (isEmpty(cm)) setPlaceholder(cm); - } - function onChange(cm) { - var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); - wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); - - if (empty) setPlaceholder(cm); - else clearPlaceholder(cm); - } - - function isEmpty(cm) { - return (cm.lineCount() === 1) && (cm.getLine(0) === ""); - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("placeholder", "", function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.on("blur", onBlur); + cm.on("change", onChange); + cm.on("swapDoc", onChange); + onChange(cm); + } else if (!val && prev) { + cm.off("blur", onBlur); + cm.off("change", onChange); + cm.off("swapDoc", onChange); + clearPlaceholder(cm); + var wrapper = cm.getWrapperElement(); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); + } + + if (val && !cm.hasFocus()) onBlur(cm); + }); + + function clearPlaceholder(cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); + cm.state.placeholder = null; + } + } + function setPlaceholder(cm) { + clearPlaceholder(cm); + var elt = cm.state.placeholder = document.createElement("pre"); + elt.style.cssText = "height: 0; overflow: visible"; + elt.className = "CodeMirror-placeholder"; + var placeHolder = cm.getOption("placeholder") + if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder) + elt.appendChild(placeHolder) + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); + } + + function onBlur(cm) { + if (isEmpty(cm)) setPlaceholder(cm); + } + function onChange(cm) { + var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); + + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + } + + function isEmpty(cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === ""); + } +}); diff --git a/shared/codemirror/addon/display/rulers.js b/shared/codemirror/addon/display/rulers.js index 01f6566..2224977 100644 --- a/shared/codemirror/addon/display/rulers.js +++ b/shared/codemirror/addon/display/rulers.js @@ -1,63 +1,63 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("rulers", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - clearRulers(cm); - cm.off("refresh", refreshRulers); - } - if (val && val.length) { - setRulers(cm); - cm.on("refresh", refreshRulers); - } - }); - - function clearRulers(cm) { - for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) { - var node = cm.display.lineSpace.childNodes[i]; - if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className)) - node.parentNode.removeChild(node); - } - } - - function setRulers(cm) { - var val = cm.getOption("rulers"); - var cw = cm.defaultCharWidth(); - var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left; - var minH = cm.display.scroller.offsetHeight + 30; - for (var i = 0; i < val.length; i++) { - var elt = document.createElement("div"); - elt.className = "CodeMirror-ruler"; - var col, conf = val[i]; - if (typeof conf == "number") { - col = conf; - } else { - col = conf.column; - if (conf.className) elt.className += " " + conf.className; - if (conf.color) elt.style.borderColor = conf.color; - if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle; - if (conf.width) elt.style.borderLeftWidth = conf.width; - } - elt.style.left = (left + col * cw) + "px"; - elt.style.top = "-50px"; - elt.style.bottom = "-20px"; - elt.style.minHeight = minH + "px"; - cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv); - } - } - - function refreshRulers(cm) { - clearRulers(cm); - setRulers(cm); - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("rulers", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + clearRulers(cm); + cm.off("refresh", refreshRulers); + } + if (val && val.length) { + setRulers(cm); + cm.on("refresh", refreshRulers); + } + }); + + function clearRulers(cm) { + for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) { + var node = cm.display.lineSpace.childNodes[i]; + if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className)) + node.parentNode.removeChild(node); + } + } + + function setRulers(cm) { + var val = cm.getOption("rulers"); + var cw = cm.defaultCharWidth(); + var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left; + var minH = cm.display.scroller.offsetHeight + 30; + for (var i = 0; i < val.length; i++) { + var elt = document.createElement("div"); + elt.className = "CodeMirror-ruler"; + var col, conf = val[i]; + if (typeof conf == "number") { + col = conf; + } else { + col = conf.column; + if (conf.className) elt.className += " " + conf.className; + if (conf.color) elt.style.borderColor = conf.color; + if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle; + if (conf.width) elt.style.borderLeftWidth = conf.width; + } + elt.style.left = (left + col * cw) + "px"; + elt.style.top = "-50px"; + elt.style.bottom = "-20px"; + elt.style.minHeight = minH + "px"; + cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv); + } + } + + function refreshRulers(cm) { + clearRulers(cm); + setRulers(cm); + } +}); diff --git a/shared/codemirror/addon/edit/closebrackets.js b/shared/codemirror/addon/edit/closebrackets.js index 3eb9d8e..dee9e1e 100644 --- a/shared/codemirror/addon/edit/closebrackets.js +++ b/shared/codemirror/addon/edit/closebrackets.js @@ -1,195 +1,195 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - var defaults = { - pairs: "()[]{}''\"\"", - triples: "", - explode: "[]{}" - }; - - var Pos = CodeMirror.Pos; - - CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.removeKeyMap(keyMap); - cm.state.closeBrackets = null; - } - if (val) { - cm.state.closeBrackets = val; - cm.addKeyMap(keyMap); - } - }); - - function getOption(conf, name) { - if (name == "pairs" && typeof conf == "string") return conf; - if (typeof conf == "object" && conf[name] != null) return conf[name]; - return defaults[name]; - } - - var bind = defaults.pairs + "`"; - var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; - for (var i = 0; i < bind.length; i++) - keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i)); - - function handler(ch) { - return function(cm) { return handleChar(cm, ch); }; - } - - function getConfig(cm) { - var deflt = cm.state.closeBrackets; - if (!deflt) return null; - var mode = cm.getModeAt(cm.getCursor()); - return mode.closeBrackets || deflt; - } - - function handleBackspace(cm) { - var conf = getConfig(cm); - if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; - - var pairs = getOption(conf, "pairs"); - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var around = charsAround(cm, ranges[i].head); - if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; - } - for (var i = ranges.length - 1; i >= 0; i--) { - var cur = ranges[i].head; - cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); - } - } - - function handleEnter(cm) { - var conf = getConfig(cm); - var explode = conf && getOption(conf, "explode"); - if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; - - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var around = charsAround(cm, ranges[i].head); - if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; - } - cm.operation(function() { - cm.replaceSelection("\n\n", null); - cm.execCommand("goCharLeft"); - ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var line = ranges[i].head.line; - cm.indentLine(line, null, true); - cm.indentLine(line + 1, null, true); - } - }); - } - - function contractSelection(sel) { - var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; - return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), - head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))}; - } - - function handleChar(cm, ch) { - var conf = getConfig(cm); - if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; - - var pairs = getOption(conf, "pairs"); - var pos = pairs.indexOf(ch); - if (pos == -1) return CodeMirror.Pass; - var triples = getOption(conf, "triples"); - - var identical = pairs.charAt(pos + 1) == ch; - var ranges = cm.listSelections(); - var opening = pos % 2 == 0; - - var type, next; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i], cur = range.head, curType; - var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); - if (opening && !range.empty()) { - curType = "surround"; - } else if ((identical || !opening) && next == ch) { - if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) - curType = "skipThree"; - else - curType = "skip"; - } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && - cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && - (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { - curType = "addFour"; - } else if (identical) { - if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; - else return CodeMirror.Pass; - } else if (opening && (cm.getLine(cur.line).length == cur.ch || - isClosingBracket(next, pairs) || - /\s/.test(next))) { - curType = "both"; - } else { - return CodeMirror.Pass; - } - if (!type) type = curType; - else if (type != curType) return CodeMirror.Pass; - } - - var left = pos % 2 ? pairs.charAt(pos - 1) : ch; - var right = pos % 2 ? ch : pairs.charAt(pos + 1); - cm.operation(function() { - if (type == "skip") { - cm.execCommand("goCharRight"); - } else if (type == "skipThree") { - for (var i = 0; i < 3; i++) - cm.execCommand("goCharRight"); - } else if (type == "surround") { - var sels = cm.getSelections(); - for (var i = 0; i < sels.length; i++) - sels[i] = left + sels[i] + right; - cm.replaceSelections(sels, "around"); - sels = cm.listSelections().slice(); - for (var i = 0; i < sels.length; i++) - sels[i] = contractSelection(sels[i]); - cm.setSelections(sels); - } else if (type == "both") { - cm.replaceSelection(left + right, null); - cm.triggerElectric(left + right); - cm.execCommand("goCharLeft"); - } else if (type == "addFour") { - cm.replaceSelection(left + left + left + left, "before"); - cm.execCommand("goCharRight"); - } - }); - } - - function isClosingBracket(ch, pairs) { - var pos = pairs.lastIndexOf(ch); - return pos > -1 && pos % 2 == 1; - } - - function charsAround(cm, pos) { - var str = cm.getRange(Pos(pos.line, pos.ch - 1), - Pos(pos.line, pos.ch + 1)); - return str.length == 2 ? str : null; - } - - // Project the token type that will exists after the given char is - // typed, and use it to determine whether it would cause the start - // of a string token. - function enteringString(cm, pos, ch) { - var line = cm.getLine(pos.line); - var token = cm.getTokenAt(pos); - if (/\bstring2?\b/.test(token.type)) return false; - var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); - stream.pos = stream.start = token.start; - for (;;) { - var type1 = cm.getMode().token(stream, token.state); - if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); - stream.start = stream.pos; - } - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var defaults = { + pairs: "()[]{}''\"\"", + triples: "", + explode: "[]{}" + }; + + var Pos = CodeMirror.Pos; + + CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.removeKeyMap(keyMap); + cm.state.closeBrackets = null; + } + if (val) { + cm.state.closeBrackets = val; + cm.addKeyMap(keyMap); + } + }); + + function getOption(conf, name) { + if (name == "pairs" && typeof conf == "string") return conf; + if (typeof conf == "object" && conf[name] != null) return conf[name]; + return defaults[name]; + } + + var bind = defaults.pairs + "`"; + var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; + for (var i = 0; i < bind.length; i++) + keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i)); + + function handler(ch) { + return function(cm) { return handleChar(cm, ch); }; + } + + function getConfig(cm) { + var deflt = cm.state.closeBrackets; + if (!deflt) return null; + var mode = cm.getModeAt(cm.getCursor()); + return mode.closeBrackets || deflt; + } + + function handleBackspace(cm) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + for (var i = ranges.length - 1; i >= 0; i--) { + var cur = ranges[i].head; + cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); + } + } + + function handleEnter(cm) { + var conf = getConfig(cm); + var explode = conf && getOption(conf, "explode"); + if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; + + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + cm.operation(function() { + cm.replaceSelection("\n\n", null); + cm.execCommand("goCharLeft"); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var line = ranges[i].head.line; + cm.indentLine(line, null, true); + cm.indentLine(line + 1, null, true); + } + }); + } + + function contractSelection(sel) { + var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; + return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), + head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))}; + } + + function handleChar(cm, ch) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var pos = pairs.indexOf(ch); + if (pos == -1) return CodeMirror.Pass; + var triples = getOption(conf, "triples"); + + var identical = pairs.charAt(pos + 1) == ch; + var ranges = cm.listSelections(); + var opening = pos % 2 == 0; + + var type, next; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], cur = range.head, curType; + var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); + if (opening && !range.empty()) { + curType = "surround"; + } else if ((identical || !opening) && next == ch) { + if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) + curType = "skipThree"; + else + curType = "skip"; + } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && + (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { + curType = "addFour"; + } else if (identical) { + if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; + else return CodeMirror.Pass; + } else if (opening && (cm.getLine(cur.line).length == cur.ch || + isClosingBracket(next, pairs) || + /\s/.test(next))) { + curType = "both"; + } else { + return CodeMirror.Pass; + } + if (!type) type = curType; + else if (type != curType) return CodeMirror.Pass; + } + + var left = pos % 2 ? pairs.charAt(pos - 1) : ch; + var right = pos % 2 ? ch : pairs.charAt(pos + 1); + cm.operation(function() { + if (type == "skip") { + cm.execCommand("goCharRight"); + } else if (type == "skipThree") { + for (var i = 0; i < 3; i++) + cm.execCommand("goCharRight"); + } else if (type == "surround") { + var sels = cm.getSelections(); + for (var i = 0; i < sels.length; i++) + sels[i] = left + sels[i] + right; + cm.replaceSelections(sels, "around"); + sels = cm.listSelections().slice(); + for (var i = 0; i < sels.length; i++) + sels[i] = contractSelection(sels[i]); + cm.setSelections(sels); + } else if (type == "both") { + cm.replaceSelection(left + right, null); + cm.triggerElectric(left + right); + cm.execCommand("goCharLeft"); + } else if (type == "addFour") { + cm.replaceSelection(left + left + left + left, "before"); + cm.execCommand("goCharRight"); + } + }); + } + + function isClosingBracket(ch, pairs) { + var pos = pairs.lastIndexOf(ch); + return pos > -1 && pos % 2 == 1; + } + + function charsAround(cm, pos) { + var str = cm.getRange(Pos(pos.line, pos.ch - 1), + Pos(pos.line, pos.ch + 1)); + return str.length == 2 ? str : null; + } + + // Project the token type that will exists after the given char is + // typed, and use it to determine whether it would cause the start + // of a string token. + function enteringString(cm, pos, ch) { + var line = cm.getLine(pos.line); + var token = cm.getTokenAt(pos); + if (/\bstring2?\b/.test(token.type)) return false; + var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); + stream.pos = stream.start = token.start; + for (;;) { + var type1 = cm.getMode().token(stream, token.state); + if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); + stream.start = stream.pos; + } + } +}); diff --git a/shared/codemirror/addon/edit/closetag.js b/shared/codemirror/addon/edit/closetag.js index a518da3..7ef0e5f 100644 --- a/shared/codemirror/addon/edit/closetag.js +++ b/shared/codemirror/addon/edit/closetag.js @@ -1,169 +1,169 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -/** - * Tag-closer extension for CodeMirror. - * - * This extension adds an "autoCloseTags" option that can be set to - * either true to get the default behavior, or an object to further - * configure its behavior. - * - * These are supported options: - * - * `whenClosing` (default true) - * Whether to autoclose when the '/' of a closing tag is typed. - * `whenOpening` (default true) - * Whether to autoclose the tag when the final '>' of an opening - * tag is typed. - * `dontCloseTags` (default is empty tags for HTML, none for XML) - * An array of tag names that should not be autoclosed. - * `indentTags` (default is block tags for HTML, none for XML) - * An array of tag names that should, when opened, cause a - * blank line to be added inside the tag, and the blank line and - * closing line to be indented. - * - * See demos/closetag.html for a usage example. - */ - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../fold/xml-fold")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../fold/xml-fold"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { - if (old != CodeMirror.Init && old) - cm.removeKeyMap("autoCloseTags"); - if (!val) return; - var map = {name: "autoCloseTags"}; - if (typeof val != "object" || val.whenClosing) - map["'/'"] = function(cm) { return autoCloseSlash(cm); }; - if (typeof val != "object" || val.whenOpening) - map["'>'"] = function(cm) { return autoCloseGT(cm); }; - cm.addKeyMap(map); - }); - - var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", - "source", "track", "wbr"]; - var htmlIndent = ["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"]; - - function autoCloseGT(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - var ranges = cm.listSelections(), replacements = []; - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var pos = ranges[i].head, tok = cm.getTokenAt(pos); - var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; - if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; - - var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; - var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); - var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); - - var tagName = state.tagName; - if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); - var lowerTagName = tagName.toLowerCase(); - // Don't process the '>' at the end of an end-tag or self-closing tag - if (!tagName || - tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || - tok.type == "tag" && state.type == "closeTag" || - tok.string.indexOf("/") == (tok.string.length - 1) || // match something like - dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 || - closingTagExists(cm, tagName, pos, state, true)) - return CodeMirror.Pass; - - var indent = indentTags && indexOf(indentTags, lowerTagName) > -1; - replacements[i] = {indent: indent, - text: ">" + (indent ? "\n\n" : "") + "", - newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)}; - } - - for (var i = ranges.length - 1; i >= 0; i--) { - var info = replacements[i]; - cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert"); - var sel = cm.listSelections().slice(0); - sel[i] = {head: info.newPos, anchor: info.newPos}; - cm.setSelections(sel); - if (info.indent) { - cm.indentLine(info.newPos.line, null, true); - cm.indentLine(info.newPos.line + 1, null, true); - } - } - } - - function autoCloseCurrent(cm, typingSlash) { - var ranges = cm.listSelections(), replacements = []; - var head = typingSlash ? "/" : "") replacement += ">"; - replacements[i] = replacement; - } - cm.replaceSelections(replacements); - ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) - if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line) - cm.indentLine(ranges[i].head.line); - } - - function autoCloseSlash(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - return autoCloseCurrent(cm, true); - } - - CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); }; - - 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; - } - - // If xml-fold is loaded, we use its functionality to try and verify - // whether a given tag is actually unclosed. - function closingTagExists(cm, tagName, pos, state, newTag) { - if (!CodeMirror.scanForClosingTag) return false; - var end = Math.min(cm.lastLine() + 1, pos.line + 500); - var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end); - if (!nextClose || nextClose.tag != tagName) return false; - var cx = state.context; - // If the immediate wrapping context contains onCx instances of - // the same tag, a closing tag only exists if there are at least - // that many closing tags of that type following. - for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx; - pos = nextClose.to; - for (var i = 1; i < onCx; i++) { - var next = CodeMirror.scanForClosingTag(cm, pos, null, end); - if (!next || next.tag != tagName) return false; - pos = next.to; - } - return true; - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Tag-closer extension for CodeMirror. + * + * This extension adds an "autoCloseTags" option that can be set to + * either true to get the default behavior, or an object to further + * configure its behavior. + * + * These are supported options: + * + * `whenClosing` (default true) + * Whether to autoclose when the '/' of a closing tag is typed. + * `whenOpening` (default true) + * Whether to autoclose the tag when the final '>' of an opening + * tag is typed. + * `dontCloseTags` (default is empty tags for HTML, none for XML) + * An array of tag names that should not be autoclosed. + * `indentTags` (default is block tags for HTML, none for XML) + * An array of tag names that should, when opened, cause a + * blank line to be added inside the tag, and the blank line and + * closing line to be indented. + * + * See demos/closetag.html for a usage example. + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../fold/xml-fold")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../fold/xml-fold"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { + if (old != CodeMirror.Init && old) + cm.removeKeyMap("autoCloseTags"); + if (!val) return; + var map = {name: "autoCloseTags"}; + if (typeof val != "object" || val.whenClosing) + map["'/'"] = function(cm) { return autoCloseSlash(cm); }; + if (typeof val != "object" || val.whenOpening) + map["'>'"] = function(cm) { return autoCloseGT(cm); }; + cm.addKeyMap(map); + }); + + var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", + "source", "track", "wbr"]; + var htmlIndent = ["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"]; + + function autoCloseGT(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), replacements = []; + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var pos = ranges[i].head, tok = cm.getTokenAt(pos); + var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; + if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; + + var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; + var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); + var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); + + var tagName = state.tagName; + if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); + var lowerTagName = tagName.toLowerCase(); + // Don't process the '>' at the end of an end-tag or self-closing tag + if (!tagName || + tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || + tok.type == "tag" && state.type == "closeTag" || + tok.string.indexOf("/") == (tok.string.length - 1) || // match something like + dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 || + closingTagExists(cm, tagName, pos, state, true)) + return CodeMirror.Pass; + + var indent = indentTags && indexOf(indentTags, lowerTagName) > -1; + replacements[i] = {indent: indent, + text: ">" + (indent ? "\n\n" : "") + "", + newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)}; + } + + for (var i = ranges.length - 1; i >= 0; i--) { + var info = replacements[i]; + cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert"); + var sel = cm.listSelections().slice(0); + sel[i] = {head: info.newPos, anchor: info.newPos}; + cm.setSelections(sel); + if (info.indent) { + cm.indentLine(info.newPos.line, null, true); + cm.indentLine(info.newPos.line + 1, null, true); + } + } + } + + function autoCloseCurrent(cm, typingSlash) { + var ranges = cm.listSelections(), replacements = []; + var head = typingSlash ? "/" : "") replacement += ">"; + replacements[i] = replacement; + } + cm.replaceSelections(replacements); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) + if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line) + cm.indentLine(ranges[i].head.line); + } + + function autoCloseSlash(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + return autoCloseCurrent(cm, true); + } + + CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); }; + + 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; + } + + // If xml-fold is loaded, we use its functionality to try and verify + // whether a given tag is actually unclosed. + function closingTagExists(cm, tagName, pos, state, newTag) { + if (!CodeMirror.scanForClosingTag) return false; + var end = Math.min(cm.lastLine() + 1, pos.line + 500); + var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end); + if (!nextClose || nextClose.tag != tagName) return false; + var cx = state.context; + // If the immediate wrapping context contains onCx instances of + // the same tag, a closing tag only exists if there are at least + // that many closing tags of that type following. + for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx; + pos = nextClose.to; + for (var i = 1; i < onCx; i++) { + var next = CodeMirror.scanForClosingTag(cm, pos, null, end); + if (!next || next.tag != tagName) return false; + pos = next.to; + } + return true; + } +}); diff --git a/shared/codemirror/addon/edit/continuelist.js b/shared/codemirror/addon/edit/continuelist.js index df5179f..a2c812b 100644 --- a/shared/codemirror/addon/edit/continuelist.js +++ b/shared/codemirror/addon/edit/continuelist.js @@ -1,51 +1,51 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\s*)/, - emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)[.)])(\s*)$/, - unorderedListRE = /[*+-]\s/; - - CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - var ranges = cm.listSelections(), replacements = []; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].head; - var eolState = cm.getStateAfter(pos.line); - var inList = eolState.list !== false; - var inQuote = eolState.quote !== 0; - - var line = cm.getLine(pos.line), match = listRE.exec(line); - if (!ranges[i].empty() || (!inList && !inQuote) || !match) { - cm.execCommand("newlineAndIndent"); - return; - } - if (emptyListRE.test(line)) { - cm.replaceRange("", { - line: pos.line, ch: 0 - }, { - line: pos.line, ch: pos.ch + 1 - }); - replacements[i] = "\n"; - } else { - var indent = match[1], after = match[5]; - var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0 - ? match[2] - : (parseInt(match[3], 10) + 1) + match[4]; - - replacements[i] = "\n" + indent + bullet + after; - } - } - - cm.replaceSelections(replacements); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\s*)/, + emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)[.)])(\s*)$/, + unorderedListRE = /[*+-]\s/; + + CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), replacements = []; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head; + var eolState = cm.getStateAfter(pos.line); + var inList = eolState.list !== false; + var inQuote = eolState.quote !== 0; + + var line = cm.getLine(pos.line), match = listRE.exec(line); + if (!ranges[i].empty() || (!inList && !inQuote) || !match) { + cm.execCommand("newlineAndIndent"); + return; + } + if (emptyListRE.test(line)) { + cm.replaceRange("", { + line: pos.line, ch: 0 + }, { + line: pos.line, ch: pos.ch + 1 + }); + replacements[i] = "\n"; + } else { + var indent = match[1], after = match[5]; + var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0 + ? match[2] + : (parseInt(match[3], 10) + 1) + match[4]; + + replacements[i] = "\n" + indent + bullet + after; + } + } + + cm.replaceSelections(replacements); + }; +}); diff --git a/shared/codemirror/addon/edit/matchbrackets.js b/shared/codemirror/addon/edit/matchbrackets.js index 70e1ae1..fb04dc3 100644 --- a/shared/codemirror/addon/edit/matchbrackets.js +++ b/shared/codemirror/addon/edit/matchbrackets.js @@ -1,120 +1,120 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && - (document.documentMode == null || document.documentMode < 8); - - var Pos = CodeMirror.Pos; - - var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; - - function findMatchingBracket(cm, where, strict, config) { - var line = cm.getLineHandle(where.line), pos = where.ch - 1; - var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; - if (!match) return null; - var dir = match.charAt(1) == ">" ? 1 : -1; - if (strict && (dir > 0) != (pos == where.ch)) return null; - var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); - - var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); - if (found == null) return null; - return {from: Pos(where.line, pos), to: found && found.pos, - match: found && found.ch == match.charAt(0), forward: dir > 0}; - } - - // bracketRegex is used to specify which type of bracket to scan - // should be a regexp, e.g. /[[\]]/ - // - // Note: If "where" is on an open bracket, then this bracket is ignored. - // - // Returns false when no bracket was found, null when it reached - // maxScanLines and gave up - function scanForBracket(cm, where, dir, style, config) { - var maxScanLen = (config && config.maxScanLineLength) || 10000; - var maxScanLines = (config && config.maxScanLines) || 1000; - - var stack = []; - var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; - var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) - : Math.max(cm.firstLine() - 1, where.line - maxScanLines); - for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { - var line = cm.getLine(lineNo); - if (!line) continue; - var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; - if (line.length > maxScanLen) continue; - if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); - for (; pos != end; pos += dir) { - var ch = line.charAt(pos); - if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { - var match = matching[ch]; - if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); - else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; - else stack.pop(); - } - } - } - return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; - } - - function matchBrackets(cm, autoclear, config) { - // Disable brace matching in long lines, since it'll cause hugely slow updates - var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; - var marks = [], ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); - if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { - var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; - marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); - if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) - marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); - } - } - - if (marks.length) { - // Kludge to work around the IE bug from issue #1193, where text - // input stops going to the textare whever this fires. - if (ie_lt8 && cm.state.focused) cm.focus(); - - var clear = function() { - cm.operation(function() { - for (var i = 0; i < marks.length; i++) marks[i].clear(); - }); - }; - if (autoclear) setTimeout(clear, 800); - else return clear; - } - } - - var currentlyHighlighted = null; - function doMatchBrackets(cm) { - cm.operation(function() { - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} - currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); - }); - } - - CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) - cm.off("cursorActivity", doMatchBrackets); - if (val) { - cm.state.matchBrackets = typeof val == "object" ? val : {}; - cm.on("cursorActivity", doMatchBrackets); - } - }); - - CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); - CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ - return findMatchingBracket(this, pos, strict, config); - }); - CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ - return scanForBracket(this, pos, dir, style, config); - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && + (document.documentMode == null || document.documentMode < 8); + + var Pos = CodeMirror.Pos; + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + + function findMatchingBracket(cm, where, strict, config) { + var line = cm.getLineHandle(where.line), pos = where.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return null; + var dir = match.charAt(1) == ">" ? 1 : -1; + if (strict && (dir > 0) != (pos == where.ch)) return null; + var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); + + var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); + if (found == null) return null; + return {from: Pos(where.line, pos), to: found && found.pos, + match: found && found.ch == match.charAt(0), forward: dir > 0}; + } + + // bracketRegex is used to specify which type of bracket to scan + // should be a regexp, e.g. /[[\]]/ + // + // Note: If "where" is on an open bracket, then this bracket is ignored. + // + // Returns false when no bracket was found, null when it reached + // maxScanLines and gave up + function scanForBracket(cm, where, dir, style, config) { + var maxScanLen = (config && config.maxScanLineLength) || 10000; + var maxScanLines = (config && config.maxScanLines) || 1000; + + var stack = []; + var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; + var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) + : Math.max(cm.firstLine() - 1, where.line - maxScanLines); + for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { + var line = cm.getLine(lineNo); + if (!line) continue; + var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; + if (line.length > maxScanLen) continue; + if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); + for (; pos != end; pos += dir) { + var ch = line.charAt(pos); + if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { + var match = matching[ch]; + if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); + else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; + else stack.pop(); + } + } + } + return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; + } + + function matchBrackets(cm, autoclear, config) { + // Disable brace matching in long lines, since it'll cause hugely slow updates + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var marks = [], ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); + if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { + var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); + if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) + marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); + } + } + + if (marks.length) { + // Kludge to work around the IE bug from issue #1193, where text + // input stops going to the textare whever this fires. + if (ie_lt8 && cm.state.focused) cm.focus(); + + var clear = function() { + cm.operation(function() { + for (var i = 0; i < marks.length; i++) marks[i].clear(); + }); + }; + if (autoclear) setTimeout(clear, 800); + else return clear; + } + } + + var currentlyHighlighted = null; + function doMatchBrackets(cm) { + cm.operation(function() { + if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + }); + } + + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) + cm.off("cursorActivity", doMatchBrackets); + if (val) { + cm.state.matchBrackets = typeof val == "object" ? val : {}; + cm.on("cursorActivity", doMatchBrackets); + } + }); + + CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); + CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ + return findMatchingBracket(this, pos, strict, config); + }); + CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ + return scanForBracket(this, pos, dir, style, config); + }); +}); diff --git a/shared/codemirror/addon/edit/matchtags.js b/shared/codemirror/addon/edit/matchtags.js index fb1911a..4fdb3b3 100644 --- a/shared/codemirror/addon/edit/matchtags.js +++ b/shared/codemirror/addon/edit/matchtags.js @@ -1,66 +1,66 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../fold/xml-fold")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../fold/xml-fold"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("matchTags", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.off("cursorActivity", doMatchTags); - cm.off("viewportChange", maybeUpdateMatch); - clear(cm); - } - if (val) { - cm.state.matchBothTags = typeof val == "object" && val.bothTags; - cm.on("cursorActivity", doMatchTags); - cm.on("viewportChange", maybeUpdateMatch); - doMatchTags(cm); - } - }); - - function clear(cm) { - if (cm.state.tagHit) cm.state.tagHit.clear(); - if (cm.state.tagOther) cm.state.tagOther.clear(); - cm.state.tagHit = cm.state.tagOther = null; - } - - function doMatchTags(cm) { - cm.state.failedTagMatch = false; - cm.operation(function() { - clear(cm); - if (cm.somethingSelected()) return; - var cur = cm.getCursor(), range = cm.getViewport(); - range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); - var match = CodeMirror.findMatchingTag(cm, cur, range); - if (!match) return; - if (cm.state.matchBothTags) { - var hit = match.at == "open" ? match.open : match.close; - if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); - } - var other = match.at == "close" ? match.open : match.close; - if (other) - cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); - else - cm.state.failedTagMatch = true; - }); - } - - function maybeUpdateMatch(cm) { - if (cm.state.failedTagMatch) doMatchTags(cm); - } - - CodeMirror.commands.toMatchingTag = function(cm) { - var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); - if (found) { - var other = found.at == "close" ? found.open : found.close; - if (other) cm.extendSelection(other.to, other.from); - } - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../fold/xml-fold")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../fold/xml-fold"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("matchTags", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.off("cursorActivity", doMatchTags); + cm.off("viewportChange", maybeUpdateMatch); + clear(cm); + } + if (val) { + cm.state.matchBothTags = typeof val == "object" && val.bothTags; + cm.on("cursorActivity", doMatchTags); + cm.on("viewportChange", maybeUpdateMatch); + doMatchTags(cm); + } + }); + + function clear(cm) { + if (cm.state.tagHit) cm.state.tagHit.clear(); + if (cm.state.tagOther) cm.state.tagOther.clear(); + cm.state.tagHit = cm.state.tagOther = null; + } + + function doMatchTags(cm) { + cm.state.failedTagMatch = false; + cm.operation(function() { + clear(cm); + if (cm.somethingSelected()) return; + var cur = cm.getCursor(), range = cm.getViewport(); + range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); + var match = CodeMirror.findMatchingTag(cm, cur, range); + if (!match) return; + if (cm.state.matchBothTags) { + var hit = match.at == "open" ? match.open : match.close; + if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); + } + var other = match.at == "close" ? match.open : match.close; + if (other) + cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); + else + cm.state.failedTagMatch = true; + }); + } + + function maybeUpdateMatch(cm) { + if (cm.state.failedTagMatch) doMatchTags(cm); + } + + CodeMirror.commands.toMatchingTag = function(cm) { + var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); + if (found) { + var other = found.at == "close" ? found.open : found.close; + if (other) cm.extendSelection(other.to, other.from); + } + }; +}); diff --git a/shared/codemirror/addon/edit/trailingspace.js b/shared/codemirror/addon/edit/trailingspace.js index fa7b56b..b12c761 100644 --- a/shared/codemirror/addon/edit/trailingspace.js +++ b/shared/codemirror/addon/edit/trailingspace.js @@ -1,27 +1,27 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { - if (prev == CodeMirror.Init) prev = false; - if (prev && !val) - cm.removeOverlay("trailingspace"); - else if (!prev && val) - cm.addOverlay({ - token: function(stream) { - for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} - if (i > stream.pos) { stream.pos = i; return null; } - stream.pos = l; - return "trailingspace"; - }, - name: "trailingspace" - }); - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { + if (prev == CodeMirror.Init) prev = false; + if (prev && !val) + cm.removeOverlay("trailingspace"); + else if (!prev && val) + cm.addOverlay({ + token: function(stream) { + for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} + if (i > stream.pos) { stream.pos = i; return null; } + stream.pos = l; + return "trailingspace"; + }, + name: "trailingspace" + }); + }); +}); diff --git a/shared/codemirror/addon/fold/brace-fold.js b/shared/codemirror/addon/fold/brace-fold.js index 1605f6c..4f60eaf 100644 --- a/shared/codemirror/addon/fold/brace-fold.js +++ b/shared/codemirror/addon/fold/brace-fold.js @@ -1,105 +1,105 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("fold", "brace", function(cm, start) { - var line = start.line, lineText = cm.getLine(line); - var startCh, tokenType; - - function findOpening(openCh) { - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); - if (found == -1) { - if (pass == 1) break; - pass = 1; - at = lineText.length; - continue; - } - if (pass == 1 && found < start.ch) break; - tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); - if (!/^(comment|string)/.test(tokenType)) return found + 1; - at = found - 1; - } - } - - var startToken = "{", endToken = "}", startCh = findOpening("{"); - if (startCh == null) { - startToken = "[", endToken = "]"; - startCh = findOpening("["); - } - - if (startCh == null) return; - var count = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { - if (pos == nextOpen) ++count; - else if (!--count) { end = i; endCh = pos; break outer; } - } - ++pos; - } - } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); - -CodeMirror.registerHelper("fold", "import", function(cm, start) { - function hasImport(line) { - if (line < cm.firstLine() || line > cm.lastLine()) return null; - var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); - if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); - if (start.type != "keyword" || start.string != "import") return null; - // Now find closing semicolon, return its position - for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { - var text = cm.getLine(i), semi = text.indexOf(";"); - if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; - } - } - - var start = start.line, has = hasImport(start), prev; - if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) - return null; - for (var end = has.end;;) { - var next = hasImport(end.line + 1); - if (next == null) break; - end = next.end; - } - return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; -}); - -CodeMirror.registerHelper("fold", "include", function(cm, start) { - function hasInclude(line) { - if (line < cm.firstLine() || line > cm.lastLine()) return null; - var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); - if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); - if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; - } - - var start = start.line, has = hasInclude(start); - if (has == null || hasInclude(start - 1) != null) return null; - for (var end = start;;) { - var next = hasInclude(end + 1); - if (next == null) break; - ++end; - } - return {from: CodeMirror.Pos(start, has + 1), - to: cm.clipPos(CodeMirror.Pos(end))}; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("fold", "brace", function(cm, start) { + var line = start.line, lineText = cm.getLine(line); + var startCh, tokenType; + + function findOpening(openCh) { + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); + if (found == -1) { + if (pass == 1) break; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) break; + tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); + if (!/^(comment|string)/.test(tokenType)) return found + 1; + at = found - 1; + } + } + + var startToken = "{", endToken = "}", startCh = findOpening("{"); + if (startCh == null) { + startToken = "[", endToken = "]"; + startCh = findOpening("["); + } + + if (startCh == null) return; + var count = 1, lastLine = cm.lastLine(), end, endCh; + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { + if (pos == nextOpen) ++count; + else if (!--count) { end = i; endCh = pos; break outer; } + } + ++pos; + } + } + if (end == null || line == end && endCh == startCh) return; + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; +}); + +CodeMirror.registerHelper("fold", "import", function(cm, start) { + function hasImport(line) { + if (line < cm.firstLine() || line > cm.lastLine()) return null; + var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); + if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); + if (start.type != "keyword" || start.string != "import") return null; + // Now find closing semicolon, return its position + for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { + var text = cm.getLine(i), semi = text.indexOf(";"); + if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; + } + } + + var start = start.line, has = hasImport(start), prev; + if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) + return null; + for (var end = has.end;;) { + var next = hasImport(end.line + 1); + if (next == null) break; + end = next.end; + } + return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; +}); + +CodeMirror.registerHelper("fold", "include", function(cm, start) { + function hasInclude(line) { + if (line < cm.firstLine() || line > cm.lastLine()) return null; + var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); + if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); + if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; + } + + var start = start.line, has = hasInclude(start); + if (has == null || hasInclude(start - 1) != null) return null; + for (var end = start;;) { + var next = hasInclude(end + 1); + if (next == null) break; + ++end; + } + return {from: CodeMirror.Pos(start, has + 1), + to: cm.clipPos(CodeMirror.Pos(end))}; +}); + +}); diff --git a/shared/codemirror/addon/fold/comment-fold.js b/shared/codemirror/addon/fold/comment-fold.js index 60fa3e4..759cca3 100644 --- a/shared/codemirror/addon/fold/comment-fold.js +++ b/shared/codemirror/addon/fold/comment-fold.js @@ -1,59 +1,59 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { - return mode.blockCommentStart && mode.blockCommentEnd; -}, function(cm, start) { - var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; - if (!startToken || !endToken) return; - var line = start.line, lineText = cm.getLine(line); - - var startCh; - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); - if (found == -1) { - if (pass == 1) return; - pass = 1; - at = lineText.length; - continue; - } - if (pass == 1 && found < start.ch) return; - if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) && - (lineText.slice(found - endToken.length, found) == endToken || - !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) { - startCh = found + startToken.length; - break; - } - at = found - 1; - } - - var depth = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (pos == nextOpen) ++depth; - else if (!--depth) { end = i; endCh = pos; break outer; } - ++pos; - } - } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { + return mode.blockCommentStart && mode.blockCommentEnd; +}, function(cm, start) { + var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; + if (!startToken || !endToken) return; + var line = start.line, lineText = cm.getLine(line); + + var startCh; + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); + if (found == -1) { + if (pass == 1) return; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) return; + if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) && + (lineText.slice(found - endToken.length, found) == endToken || + !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) { + startCh = found + startToken.length; + break; + } + at = found - 1; + } + + var depth = 1, lastLine = cm.lastLine(), end, endCh; + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (pos == nextOpen) ++depth; + else if (!--depth) { end = i; endCh = pos; break outer; } + ++pos; + } + } + if (end == null || line == end && endCh == startCh) return; + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; +}); + +}); diff --git a/shared/codemirror/addon/fold/foldcode.js b/shared/codemirror/addon/fold/foldcode.js index 62911f9..5509705 100644 --- a/shared/codemirror/addon/fold/foldcode.js +++ b/shared/codemirror/addon/fold/foldcode.js @@ -1,149 +1,149 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function doFold(cm, pos, options, force) { - if (options && options.call) { - var finder = options; - options = null; - } else { - var finder = getOption(cm, options, "rangeFinder"); - } - if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); - var minSize = getOption(cm, options, "minFoldSize"); - - function getRange(allowFolded) { - var range = finder(cm, pos); - if (!range || range.to.line - range.from.line < minSize) return null; - var marks = cm.findMarksAt(range.from); - for (var i = 0; i < marks.length; ++i) { - if (marks[i].__isFold && force !== "fold") { - if (!allowFolded) return null; - range.cleared = true; - marks[i].clear(); - } - } - return range; - } - - var range = getRange(true); - if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) { - pos = CodeMirror.Pos(pos.line - 1, 0); - range = getRange(false); - } - if (!range || range.cleared || force === "unfold") return; - - var myWidget = makeWidget(cm, options); - CodeMirror.on(myWidget, "mousedown", function(e) { - myRange.clear(); - CodeMirror.e_preventDefault(e); - }); - var myRange = cm.markText(range.from, range.to, { - replacedWith: myWidget, - clearOnEnter: true, - __isFold: true - }); - myRange.on("clear", function(from, to) { - CodeMirror.signal(cm, "unfold", cm, from, to); - }); - CodeMirror.signal(cm, "fold", cm, range.from, range.to); - } - - function makeWidget(cm, options) { - var widget = getOption(cm, options, "widget"); - if (typeof widget == "string") { - var text = document.createTextNode(widget); - widget = document.createElement("span"); - widget.appendChild(text); - widget.className = "CodeMirror-foldmarker"; - } - return widget; - } - - // Clumsy backwards-compatible interface - CodeMirror.newFoldFunction = function(rangeFinder, widget) { - return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; - }; - - // New-style interface - CodeMirror.defineExtension("foldCode", function(pos, options, force) { - doFold(this, pos, options, force); - }); - - CodeMirror.defineExtension("isFolded", function(pos) { - var marks = this.findMarksAt(pos); - for (var i = 0; i < marks.length; ++i) - if (marks[i].__isFold) return true; - }); - - CodeMirror.commands.toggleFold = function(cm) { - cm.foldCode(cm.getCursor()); - }; - CodeMirror.commands.fold = function(cm) { - cm.foldCode(cm.getCursor(), null, "fold"); - }; - CodeMirror.commands.unfold = function(cm) { - cm.foldCode(cm.getCursor(), null, "unfold"); - }; - CodeMirror.commands.foldAll = function(cm) { - cm.operation(function() { - for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) - cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); - }); - }; - CodeMirror.commands.unfoldAll = function(cm) { - cm.operation(function() { - for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) - cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); - }); - }; - - CodeMirror.registerHelper("fold", "combine", function() { - var funcs = Array.prototype.slice.call(arguments, 0); - return function(cm, start) { - for (var i = 0; i < funcs.length; ++i) { - var found = funcs[i](cm, start); - if (found) return found; - } - }; - }); - - CodeMirror.registerHelper("fold", "auto", function(cm, start) { - var helpers = cm.getHelpers(start, "fold"); - for (var i = 0; i < helpers.length; i++) { - var cur = helpers[i](cm, start); - if (cur) return cur; - } - }); - - var defaultOptions = { - rangeFinder: CodeMirror.fold.auto, - widget: "\u2194", - minFoldSize: 0, - scanUp: false - }; - - CodeMirror.defineOption("foldOptions", null); - - function getOption(cm, options, name) { - if (options && options[name] !== undefined) - return options[name]; - var editorOptions = cm.options.foldOptions; - if (editorOptions && editorOptions[name] !== undefined) - return editorOptions[name]; - return defaultOptions[name]; - } - - CodeMirror.defineExtension("foldOption", function(options, name) { - return getOption(this, options, name); - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function doFold(cm, pos, options, force) { + if (options && options.call) { + var finder = options; + options = null; + } else { + var finder = getOption(cm, options, "rangeFinder"); + } + if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); + var minSize = getOption(cm, options, "minFoldSize"); + + function getRange(allowFolded) { + var range = finder(cm, pos); + if (!range || range.to.line - range.from.line < minSize) return null; + var marks = cm.findMarksAt(range.from); + for (var i = 0; i < marks.length; ++i) { + if (marks[i].__isFold && force !== "fold") { + if (!allowFolded) return null; + range.cleared = true; + marks[i].clear(); + } + } + return range; + } + + var range = getRange(true); + if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) { + pos = CodeMirror.Pos(pos.line - 1, 0); + range = getRange(false); + } + if (!range || range.cleared || force === "unfold") return; + + var myWidget = makeWidget(cm, options); + CodeMirror.on(myWidget, "mousedown", function(e) { + myRange.clear(); + CodeMirror.e_preventDefault(e); + }); + var myRange = cm.markText(range.from, range.to, { + replacedWith: myWidget, + clearOnEnter: true, + __isFold: true + }); + myRange.on("clear", function(from, to) { + CodeMirror.signal(cm, "unfold", cm, from, to); + }); + CodeMirror.signal(cm, "fold", cm, range.from, range.to); + } + + function makeWidget(cm, options) { + var widget = getOption(cm, options, "widget"); + if (typeof widget == "string") { + var text = document.createTextNode(widget); + widget = document.createElement("span"); + widget.appendChild(text); + widget.className = "CodeMirror-foldmarker"; + } + return widget; + } + + // Clumsy backwards-compatible interface + CodeMirror.newFoldFunction = function(rangeFinder, widget) { + return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; + }; + + // New-style interface + CodeMirror.defineExtension("foldCode", function(pos, options, force) { + doFold(this, pos, options, force); + }); + + CodeMirror.defineExtension("isFolded", function(pos) { + var marks = this.findMarksAt(pos); + for (var i = 0; i < marks.length; ++i) + if (marks[i].__isFold) return true; + }); + + CodeMirror.commands.toggleFold = function(cm) { + cm.foldCode(cm.getCursor()); + }; + CodeMirror.commands.fold = function(cm) { + cm.foldCode(cm.getCursor(), null, "fold"); + }; + CodeMirror.commands.unfold = function(cm) { + cm.foldCode(cm.getCursor(), null, "unfold"); + }; + CodeMirror.commands.foldAll = function(cm) { + cm.operation(function() { + for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) + cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); + }); + }; + CodeMirror.commands.unfoldAll = function(cm) { + cm.operation(function() { + for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) + cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); + }); + }; + + CodeMirror.registerHelper("fold", "combine", function() { + var funcs = Array.prototype.slice.call(arguments, 0); + return function(cm, start) { + for (var i = 0; i < funcs.length; ++i) { + var found = funcs[i](cm, start); + if (found) return found; + } + }; + }); + + CodeMirror.registerHelper("fold", "auto", function(cm, start) { + var helpers = cm.getHelpers(start, "fold"); + for (var i = 0; i < helpers.length; i++) { + var cur = helpers[i](cm, start); + if (cur) return cur; + } + }); + + var defaultOptions = { + rangeFinder: CodeMirror.fold.auto, + widget: "\u2194", + minFoldSize: 0, + scanUp: false + }; + + CodeMirror.defineOption("foldOptions", null); + + function getOption(cm, options, name) { + if (options && options[name] !== undefined) + return options[name]; + var editorOptions = cm.options.foldOptions; + if (editorOptions && editorOptions[name] !== undefined) + return editorOptions[name]; + return defaultOptions[name]; + } + + CodeMirror.defineExtension("foldOption", function(options, name) { + return getOption(this, options, name); + }); +}); diff --git a/shared/codemirror/addon/fold/foldgutter.css b/shared/codemirror/addon/fold/foldgutter.css index ad19ae2..3655e7d 100644 --- a/shared/codemirror/addon/fold/foldgutter.css +++ b/shared/codemirror/addon/fold/foldgutter.css @@ -1,20 +1,20 @@ -.CodeMirror-foldmarker { - color: blue; - text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; - font-family: arial; - line-height: .3; - cursor: pointer; -} -.CodeMirror-foldgutter { - width: .7em; -} -.CodeMirror-foldgutter-open, -.CodeMirror-foldgutter-folded { - cursor: pointer; -} -.CodeMirror-foldgutter-open:after { - content: "\25BE"; -} -.CodeMirror-foldgutter-folded:after { - content: "\25B8"; -} +.CodeMirror-foldmarker { + color: blue; + text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; + font-family: arial; + line-height: .3; + cursor: pointer; +} +.CodeMirror-foldgutter { + width: .7em; +} +.CodeMirror-foldgutter-open, +.CodeMirror-foldgutter-folded { + cursor: pointer; +} +.CodeMirror-foldgutter-open:after { + content: "\25BE"; +} +.CodeMirror-foldgutter-folded:after { + content: "\25B8"; +} diff --git a/shared/codemirror/addon/fold/foldgutter.js b/shared/codemirror/addon/fold/foldgutter.js index f101e26..875bac2 100644 --- a/shared/codemirror/addon/fold/foldgutter.js +++ b/shared/codemirror/addon/fold/foldgutter.js @@ -1,146 +1,146 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./foldcode")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./foldcode"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.clearGutter(cm.state.foldGutter.options.gutter); - cm.state.foldGutter = null; - cm.off("gutterClick", onGutterClick); - cm.off("change", onChange); - cm.off("viewportChange", onViewportChange); - cm.off("fold", onFold); - cm.off("unfold", onFold); - cm.off("swapDoc", onChange); - } - if (val) { - cm.state.foldGutter = new State(parseOptions(val)); - updateInViewport(cm); - cm.on("gutterClick", onGutterClick); - cm.on("change", onChange); - cm.on("viewportChange", onViewportChange); - cm.on("fold", onFold); - cm.on("unfold", onFold); - cm.on("swapDoc", onChange); - } - }); - - var Pos = CodeMirror.Pos; - - function State(options) { - this.options = options; - this.from = this.to = 0; - } - - function parseOptions(opts) { - if (opts === true) opts = {}; - if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; - if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; - if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; - return opts; - } - - function isFolded(cm, line) { - var marks = cm.findMarksAt(Pos(line)); - for (var i = 0; i < marks.length; ++i) - if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i]; - } - - function marker(spec) { - if (typeof spec == "string") { - var elt = document.createElement("div"); - elt.className = spec + " CodeMirror-guttermarker-subtle"; - return elt; - } else { - return spec.cloneNode(true); - } - } - - function updateFoldInfo(cm, from, to) { - var opts = cm.state.foldGutter.options, cur = from; - var minSize = cm.foldOption(opts, "minFoldSize"); - var func = cm.foldOption(opts, "rangeFinder"); - cm.eachLine(from, to, function(line) { - var mark = null; - if (isFolded(cm, cur)) { - mark = marker(opts.indicatorFolded); - } else { - var pos = Pos(cur, 0); - var range = func && func(cm, pos); - if (range && range.to.line - range.from.line >= minSize) - mark = marker(opts.indicatorOpen); - } - cm.setGutterMarker(line, opts.gutter, mark); - ++cur; - }); - } - - function updateInViewport(cm) { - var vp = cm.getViewport(), state = cm.state.foldGutter; - if (!state) return; - cm.operation(function() { - updateFoldInfo(cm, vp.from, vp.to); - }); - state.from = vp.from; state.to = vp.to; - } - - function onGutterClick(cm, line, gutter) { - var state = cm.state.foldGutter; - if (!state) return; - var opts = state.options; - if (gutter != opts.gutter) return; - var folded = isFolded(cm, line); - if (folded) folded.clear(); - else cm.foldCode(Pos(line, 0), opts.rangeFinder); - } - - function onChange(cm) { - var state = cm.state.foldGutter; - if (!state) return; - var opts = state.options; - state.from = state.to = 0; - clearTimeout(state.changeUpdate); - state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); - } - - function onViewportChange(cm) { - var state = cm.state.foldGutter; - if (!state) return; - var opts = state.options; - clearTimeout(state.changeUpdate); - state.changeUpdate = setTimeout(function() { - var vp = cm.getViewport(); - if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { - updateInViewport(cm); - } else { - cm.operation(function() { - if (vp.from < state.from) { - updateFoldInfo(cm, vp.from, state.from); - state.from = vp.from; - } - if (vp.to > state.to) { - updateFoldInfo(cm, state.to, vp.to); - state.to = vp.to; - } - }); - } - }, opts.updateViewportTimeSpan || 400); - } - - function onFold(cm, from) { - var state = cm.state.foldGutter; - if (!state) return; - var line = from.line; - if (line >= state.from && line < state.to) - updateFoldInfo(cm, line, line + 1); - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./foldcode")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./foldcode"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.clearGutter(cm.state.foldGutter.options.gutter); + cm.state.foldGutter = null; + cm.off("gutterClick", onGutterClick); + cm.off("change", onChange); + cm.off("viewportChange", onViewportChange); + cm.off("fold", onFold); + cm.off("unfold", onFold); + cm.off("swapDoc", onChange); + } + if (val) { + cm.state.foldGutter = new State(parseOptions(val)); + updateInViewport(cm); + cm.on("gutterClick", onGutterClick); + cm.on("change", onChange); + cm.on("viewportChange", onViewportChange); + cm.on("fold", onFold); + cm.on("unfold", onFold); + cm.on("swapDoc", onChange); + } + }); + + var Pos = CodeMirror.Pos; + + function State(options) { + this.options = options; + this.from = this.to = 0; + } + + function parseOptions(opts) { + if (opts === true) opts = {}; + if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; + if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; + if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; + return opts; + } + + function isFolded(cm, line) { + var marks = cm.findMarksAt(Pos(line)); + for (var i = 0; i < marks.length; ++i) + if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i]; + } + + function marker(spec) { + if (typeof spec == "string") { + var elt = document.createElement("div"); + elt.className = spec + " CodeMirror-guttermarker-subtle"; + return elt; + } else { + return spec.cloneNode(true); + } + } + + function updateFoldInfo(cm, from, to) { + var opts = cm.state.foldGutter.options, cur = from; + var minSize = cm.foldOption(opts, "minFoldSize"); + var func = cm.foldOption(opts, "rangeFinder"); + cm.eachLine(from, to, function(line) { + var mark = null; + if (isFolded(cm, cur)) { + mark = marker(opts.indicatorFolded); + } else { + var pos = Pos(cur, 0); + var range = func && func(cm, pos); + if (range && range.to.line - range.from.line >= minSize) + mark = marker(opts.indicatorOpen); + } + cm.setGutterMarker(line, opts.gutter, mark); + ++cur; + }); + } + + function updateInViewport(cm) { + var vp = cm.getViewport(), state = cm.state.foldGutter; + if (!state) return; + cm.operation(function() { + updateFoldInfo(cm, vp.from, vp.to); + }); + state.from = vp.from; state.to = vp.to; + } + + function onGutterClick(cm, line, gutter) { + var state = cm.state.foldGutter; + if (!state) return; + var opts = state.options; + if (gutter != opts.gutter) return; + var folded = isFolded(cm, line); + if (folded) folded.clear(); + else cm.foldCode(Pos(line, 0), opts.rangeFinder); + } + + function onChange(cm) { + var state = cm.state.foldGutter; + if (!state) return; + var opts = state.options; + state.from = state.to = 0; + clearTimeout(state.changeUpdate); + state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); + } + + function onViewportChange(cm) { + var state = cm.state.foldGutter; + if (!state) return; + var opts = state.options; + clearTimeout(state.changeUpdate); + state.changeUpdate = setTimeout(function() { + var vp = cm.getViewport(); + if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { + updateInViewport(cm); + } else { + cm.operation(function() { + if (vp.from < state.from) { + updateFoldInfo(cm, vp.from, state.from); + state.from = vp.from; + } + if (vp.to > state.to) { + updateFoldInfo(cm, state.to, vp.to); + state.to = vp.to; + } + }); + } + }, opts.updateViewportTimeSpan || 400); + } + + function onFold(cm, from) { + var state = cm.state.foldGutter; + if (!state) return; + var line = from.line; + if (line >= state.from && line < state.to) + updateFoldInfo(cm, line, line + 1); + } +}); diff --git a/shared/codemirror/addon/fold/indent-fold.js b/shared/codemirror/addon/fold/indent-fold.js index e29f15e..c3cfb8a 100644 --- a/shared/codemirror/addon/fold/indent-fold.js +++ b/shared/codemirror/addon/fold/indent-fold.js @@ -1,44 +1,44 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("fold", "indent", function(cm, start) { - var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); - if (!/\S/.test(firstLine)) return; - var getIndent = function(line) { - return CodeMirror.countColumn(line, null, tabSize); - }; - var myIndent = getIndent(firstLine); - var lastLineInFold = null; - // Go through lines until we find a line that definitely doesn't belong in - // the block we're folding, or to the end. - for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { - var curLine = cm.getLine(i); - var curIndent = getIndent(curLine); - if (curIndent > myIndent) { - // Lines with a greater indent are considered part of the block. - lastLineInFold = i; - } else if (!/\S/.test(curLine)) { - // Empty lines might be breaks within the block we're trying to fold. - } else { - // A non-empty line at an indent equal to or less than ours marks the - // start of another block. - break; - } - } - if (lastLineInFold) return { - from: CodeMirror.Pos(start.line, firstLine.length), - to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) - }; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("fold", "indent", function(cm, start) { + var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); + if (!/\S/.test(firstLine)) return; + var getIndent = function(line) { + return CodeMirror.countColumn(line, null, tabSize); + }; + var myIndent = getIndent(firstLine); + var lastLineInFold = null; + // Go through lines until we find a line that definitely doesn't belong in + // the block we're folding, or to the end. + for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { + var curLine = cm.getLine(i); + var curIndent = getIndent(curLine); + if (curIndent > myIndent) { + // Lines with a greater indent are considered part of the block. + lastLineInFold = i; + } else if (!/\S/.test(curLine)) { + // Empty lines might be breaks within the block we're trying to fold. + } else { + // A non-empty line at an indent equal to or less than ours marks the + // start of another block. + break; + } + } + if (lastLineInFold) return { + from: CodeMirror.Pos(start.line, firstLine.length), + to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) + }; +}); + +}); diff --git a/shared/codemirror/addon/fold/markdown-fold.js b/shared/codemirror/addon/fold/markdown-fold.js index ce84c94..c11b028 100644 --- a/shared/codemirror/addon/fold/markdown-fold.js +++ b/shared/codemirror/addon/fold/markdown-fold.js @@ -1,49 +1,49 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("fold", "markdown", function(cm, start) { - var maxDepth = 100; - - function isHeader(lineNo) { - var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0)); - return tokentype && /\bheader\b/.test(tokentype); - } - - function headerLevel(lineNo, line, nextLine) { - var match = line && line.match(/^#+/); - if (match && isHeader(lineNo)) return match[0].length; - match = nextLine && nextLine.match(/^[=\-]+\s*$/); - if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2; - return maxDepth; - } - - var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1); - var level = headerLevel(start.line, firstLine, nextLine); - if (level === maxDepth) return undefined; - - var lastLineNo = cm.lastLine(); - var end = start.line, nextNextLine = cm.getLine(end + 2); - while (end < lastLineNo) { - if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break; - ++end; - nextLine = nextNextLine; - nextNextLine = cm.getLine(end + 2); - } - - return { - from: CodeMirror.Pos(start.line, firstLine.length), - to: CodeMirror.Pos(end, cm.getLine(end).length) - }; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("fold", "markdown", function(cm, start) { + var maxDepth = 100; + + function isHeader(lineNo) { + var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0)); + return tokentype && /\bheader\b/.test(tokentype); + } + + function headerLevel(lineNo, line, nextLine) { + var match = line && line.match(/^#+/); + if (match && isHeader(lineNo)) return match[0].length; + match = nextLine && nextLine.match(/^[=\-]+\s*$/); + if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2; + return maxDepth; + } + + var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1); + var level = headerLevel(start.line, firstLine, nextLine); + if (level === maxDepth) return undefined; + + var lastLineNo = cm.lastLine(); + var end = start.line, nextNextLine = cm.getLine(end + 2); + while (end < lastLineNo) { + if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break; + ++end; + nextLine = nextNextLine; + nextNextLine = cm.getLine(end + 2); + } + + return { + from: CodeMirror.Pos(start.line, firstLine.length), + to: CodeMirror.Pos(end, cm.getLine(end).length) + }; +}); + +}); diff --git a/shared/codemirror/addon/fold/xml-fold.js b/shared/codemirror/addon/fold/xml-fold.js index 504727f..c6353c1 100644 --- a/shared/codemirror/addon/fold/xml-fold.js +++ b/shared/codemirror/addon/fold/xml-fold.js @@ -1,182 +1,182 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var Pos = CodeMirror.Pos; - function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } - - 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 xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); - - function Iter(cm, line, ch, range) { - this.line = line; this.ch = ch; - this.cm = cm; this.text = cm.getLine(line); - this.min = range ? range.from : cm.firstLine(); - this.max = range ? range.to - 1 : cm.lastLine(); - } - - function tagAt(iter, ch) { - var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); - return type && /\btag\b/.test(type); - } - - function nextLine(iter) { - if (iter.line >= iter.max) return; - iter.ch = 0; - iter.text = iter.cm.getLine(++iter.line); - return true; - } - function prevLine(iter) { - if (iter.line <= iter.min) return; - iter.text = iter.cm.getLine(--iter.line); - iter.ch = iter.text.length; - return true; - } - - function toTagEnd(iter) { - for (;;) { - var gt = iter.text.indexOf(">", iter.ch); - if (gt == -1) { if (nextLine(iter)) continue; else return; } - if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } - var lastSlash = iter.text.lastIndexOf("/", gt); - var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); - iter.ch = gt + 1; - return selfClose ? "selfClose" : "regular"; - } - } - function toTagStart(iter) { - for (;;) { - var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; - if (lt == -1) { if (prevLine(iter)) continue; else return; } - if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } - xmlTagStart.lastIndex = lt; - iter.ch = lt; - var match = xmlTagStart.exec(iter.text); - if (match && match.index == lt) return match; - } - } - - function toNextTag(iter) { - for (;;) { - xmlTagStart.lastIndex = iter.ch; - var found = xmlTagStart.exec(iter.text); - if (!found) { if (nextLine(iter)) continue; else return; } - if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } - iter.ch = found.index + found[0].length; - return found; - } - } - function toPrevTag(iter) { - for (;;) { - var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; - if (gt == -1) { if (prevLine(iter)) continue; else return; } - if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } - var lastSlash = iter.text.lastIndexOf("/", gt); - var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); - iter.ch = gt + 1; - return selfClose ? "selfClose" : "regular"; - } - } - - function findMatchingClose(iter, tag) { - var stack = []; - for (;;) { - var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); - if (!next || !(end = toTagEnd(iter))) return; - if (end == "selfClose") continue; - if (next[1]) { // closing tag - for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { - stack.length = i; - break; - } - if (i < 0 && (!tag || tag == next[2])) return { - tag: next[2], - from: Pos(startLine, startCh), - to: Pos(iter.line, iter.ch) - }; - } else { // opening tag - stack.push(next[2]); - } - } - } - function findMatchingOpen(iter, tag) { - var stack = []; - for (;;) { - var prev = toPrevTag(iter); - if (!prev) return; - if (prev == "selfClose") { toTagStart(iter); continue; } - var endLine = iter.line, endCh = iter.ch; - var start = toTagStart(iter); - if (!start) return; - if (start[1]) { // closing tag - stack.push(start[2]); - } else { // opening tag - for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { - stack.length = i; - break; - } - if (i < 0 && (!tag || tag == start[2])) return { - tag: start[2], - from: Pos(iter.line, iter.ch), - to: Pos(endLine, endCh) - }; - } - } - } - - CodeMirror.registerHelper("fold", "xml", function(cm, start) { - var iter = new Iter(cm, start.line, 0); - for (;;) { - var openTag = toNextTag(iter), end; - if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; - if (!openTag[1] && end != "selfClose") { - var start = Pos(iter.line, iter.ch); - var close = findMatchingClose(iter, openTag[2]); - return close && {from: start, to: close.from}; - } - } - }); - CodeMirror.findMatchingTag = function(cm, pos, range) { - var iter = new Iter(cm, pos.line, pos.ch, range); - if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; - var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); - var start = end && toTagStart(iter); - if (!end || !start || cmp(iter, pos) > 0) return; - var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; - if (end == "selfClose") return {open: here, close: null, at: "open"}; - - if (start[1]) { // closing tag - return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; - } else { // opening tag - iter = new Iter(cm, to.line, to.ch, range); - return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; - } - }; - - CodeMirror.findEnclosingTag = function(cm, pos, range) { - var iter = new Iter(cm, pos.line, pos.ch, range); - for (;;) { - var open = findMatchingOpen(iter); - if (!open) break; - var forward = new Iter(cm, pos.line, pos.ch, range); - var close = findMatchingClose(forward, open.tag); - if (close) return {open: open, close: close}; - } - }; - - // Used by addon/edit/closetag.js - CodeMirror.scanForClosingTag = function(cm, pos, name, end) { - var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); - return findMatchingClose(iter, name); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var Pos = CodeMirror.Pos; + function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } + + 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 xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); + + function Iter(cm, line, ch, range) { + this.line = line; this.ch = ch; + this.cm = cm; this.text = cm.getLine(line); + this.min = range ? range.from : cm.firstLine(); + this.max = range ? range.to - 1 : cm.lastLine(); + } + + function tagAt(iter, ch) { + var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); + return type && /\btag\b/.test(type); + } + + function nextLine(iter) { + if (iter.line >= iter.max) return; + iter.ch = 0; + iter.text = iter.cm.getLine(++iter.line); + return true; + } + function prevLine(iter) { + if (iter.line <= iter.min) return; + iter.text = iter.cm.getLine(--iter.line); + iter.ch = iter.text.length; + return true; + } + + function toTagEnd(iter) { + for (;;) { + var gt = iter.text.indexOf(">", iter.ch); + if (gt == -1) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + function toTagStart(iter) { + for (;;) { + var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; + if (lt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } + xmlTagStart.lastIndex = lt; + iter.ch = lt; + var match = xmlTagStart.exec(iter.text); + if (match && match.index == lt) return match; + } + } + + function toNextTag(iter) { + for (;;) { + xmlTagStart.lastIndex = iter.ch; + var found = xmlTagStart.exec(iter.text); + if (!found) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } + iter.ch = found.index + found[0].length; + return found; + } + } + function toPrevTag(iter) { + for (;;) { + var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; + if (gt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + + function findMatchingClose(iter, tag) { + var stack = []; + for (;;) { + var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); + if (!next || !(end = toTagEnd(iter))) return; + if (end == "selfClose") continue; + if (next[1]) { // closing tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == next[2])) return { + tag: next[2], + from: Pos(startLine, startCh), + to: Pos(iter.line, iter.ch) + }; + } else { // opening tag + stack.push(next[2]); + } + } + } + function findMatchingOpen(iter, tag) { + var stack = []; + for (;;) { + var prev = toPrevTag(iter); + if (!prev) return; + if (prev == "selfClose") { toTagStart(iter); continue; } + var endLine = iter.line, endCh = iter.ch; + var start = toTagStart(iter); + if (!start) return; + if (start[1]) { // closing tag + stack.push(start[2]); + } else { // opening tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == start[2])) return { + tag: start[2], + from: Pos(iter.line, iter.ch), + to: Pos(endLine, endCh) + }; + } + } + } + + CodeMirror.registerHelper("fold", "xml", function(cm, start) { + var iter = new Iter(cm, start.line, 0); + for (;;) { + var openTag = toNextTag(iter), end; + if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; + if (!openTag[1] && end != "selfClose") { + var start = Pos(iter.line, iter.ch); + var close = findMatchingClose(iter, openTag[2]); + return close && {from: start, to: close.from}; + } + } + }); + CodeMirror.findMatchingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; + var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); + var start = end && toTagStart(iter); + if (!end || !start || cmp(iter, pos) > 0) return; + var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; + if (end == "selfClose") return {open: here, close: null, at: "open"}; + + if (start[1]) { // closing tag + return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; + } else { // opening tag + iter = new Iter(cm, to.line, to.ch, range); + return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; + } + }; + + CodeMirror.findEnclosingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + for (;;) { + var open = findMatchingOpen(iter); + if (!open) break; + var forward = new Iter(cm, pos.line, pos.ch, range); + var close = findMatchingClose(forward, open.tag); + if (close) return {open: open, close: close}; + } + }; + + // Used by addon/edit/closetag.js + CodeMirror.scanForClosingTag = function(cm, pos, name, end) { + var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); + return findMatchingClose(iter, name); + }; +}); diff --git a/shared/codemirror/addon/hint/anyword-hint.js b/shared/codemirror/addon/hint/anyword-hint.js index dae78e2..64f53ff 100644 --- a/shared/codemirror/addon/hint/anyword-hint.js +++ b/shared/codemirror/addon/hint/anyword-hint.js @@ -1,41 +1,41 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var WORD = /[\w$]+/, RANGE = 500; - - CodeMirror.registerHelper("hint", "anyword", function(editor, options) { - var word = options && options.word || WORD; - var range = options && options.range || RANGE; - var cur = editor.getCursor(), curLine = editor.getLine(cur.line); - var end = cur.ch, start = end; - while (start && word.test(curLine.charAt(start - 1))) --start; - var curWord = start != end && curLine.slice(start, end); - - var list = options && options.list || [], seen = {}; - var re = new RegExp(word.source, "g"); - for (var dir = -1; dir <= 1; dir += 2) { - var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; - for (; line != endLine; line += dir) { - var text = editor.getLine(line), m; - while (m = re.exec(text)) { - if (line == cur.line && m[0] === curWord) continue; - if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) { - seen[m[0]] = true; - list.push(m[0]); - } - } - } - } - return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var WORD = /[\w$]+/, RANGE = 500; + + CodeMirror.registerHelper("hint", "anyword", function(editor, options) { + var word = options && options.word || WORD; + var range = options && options.range || RANGE; + var cur = editor.getCursor(), curLine = editor.getLine(cur.line); + var end = cur.ch, start = end; + while (start && word.test(curLine.charAt(start - 1))) --start; + var curWord = start != end && curLine.slice(start, end); + + var list = options && options.list || [], seen = {}; + var re = new RegExp(word.source, "g"); + for (var dir = -1; dir <= 1; dir += 2) { + var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; + for (; line != endLine; line += dir) { + var text = editor.getLine(line), m; + while (m = re.exec(text)) { + if (line == cur.line && m[0] === curWord) continue; + if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) { + seen[m[0]] = true; + list.push(m[0]); + } + } + } + } + return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; + }); +}); diff --git a/shared/codemirror/addon/hint/css-hint.js b/shared/codemirror/addon/hint/css-hint.js index 2264272..b28cff3 100644 --- a/shared/codemirror/addon/hint/css-hint.js +++ b/shared/codemirror/addon/hint/css-hint.js @@ -1,60 +1,60 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../../mode/css/css")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../../mode/css/css"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, - "first-letter": 1, "first-line": 1, "first-child": 1, - before: 1, after: 1, lang: 1}; - - CodeMirror.registerHelper("hint", "css", function(cm) { - var cur = cm.getCursor(), token = cm.getTokenAt(cur); - var inner = CodeMirror.innerMode(cm.getMode(), token.state); - if (inner.mode.name != "css") return; - - if (token.type == "keyword" && "!important".indexOf(token.string) == 0) - return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start), - to: CodeMirror.Pos(cur.line, token.end)}; - - var start = token.start, end = cur.ch, word = token.string.slice(0, end - start); - if (/[^\w$_-]/.test(word)) { - word = ""; start = end = cur.ch; - } - - var spec = CodeMirror.resolveMode("text/css"); - - var result = []; - function add(keywords) { - for (var name in keywords) - if (!word || name.lastIndexOf(word, 0) == 0) - result.push(name); - } - - var st = inner.state.state; - if (st == "pseudo" || token.type == "variable-3") { - add(pseudoClasses); - } else if (st == "block" || st == "maybeprop") { - add(spec.propertyKeywords); - } else if (st == "prop" || st == "parens" || st == "at" || st == "params") { - add(spec.valueKeywords); - add(spec.colorKeywords); - } else if (st == "media" || st == "media_parens") { - add(spec.mediaTypes); - add(spec.mediaFeatures); - } - - if (result.length) return { - list: result, - from: CodeMirror.Pos(cur.line, start), - to: CodeMirror.Pos(cur.line, end) - }; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../mode/css/css")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../mode/css/css"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, + "first-letter": 1, "first-line": 1, "first-child": 1, + before: 1, after: 1, lang: 1}; + + CodeMirror.registerHelper("hint", "css", function(cm) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var inner = CodeMirror.innerMode(cm.getMode(), token.state); + if (inner.mode.name != "css") return; + + if (token.type == "keyword" && "!important".indexOf(token.string) == 0) + return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end)}; + + var start = token.start, end = cur.ch, word = token.string.slice(0, end - start); + if (/[^\w$_-]/.test(word)) { + word = ""; start = end = cur.ch; + } + + var spec = CodeMirror.resolveMode("text/css"); + + var result = []; + function add(keywords) { + for (var name in keywords) + if (!word || name.lastIndexOf(word, 0) == 0) + result.push(name); + } + + var st = inner.state.state; + if (st == "pseudo" || token.type == "variable-3") { + add(pseudoClasses); + } else if (st == "block" || st == "maybeprop") { + add(spec.propertyKeywords); + } else if (st == "prop" || st == "parens" || st == "at" || st == "params") { + add(spec.valueKeywords); + add(spec.colorKeywords); + } else if (st == "media" || st == "media_parens") { + add(spec.mediaTypes); + add(spec.mediaFeatures); + } + + if (result.length) return { + list: result, + from: CodeMirror.Pos(cur.line, start), + to: CodeMirror.Pos(cur.line, end) + }; + }); +}); diff --git a/shared/codemirror/addon/hint/html-hint.js b/shared/codemirror/addon/hint/html-hint.js index c6769bc..23238b1 100644 --- a/shared/codemirror/addon/hint/html-hint.js +++ b/shared/codemirror/addon/hint/html-hint.js @@ -1,348 +1,348 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./xml-hint")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./xml-hint"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "); - var targets = ["_blank", "_self", "_top", "_parent"]; - var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; - var methods = ["get", "post", "put", "delete"]; - var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; - var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech", - "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait", - "orientation:landscape", "device-height: [X]", "device-width: [X]"]; - var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags - - var data = { - a: { - attrs: { - href: null, ping: null, type: null, - media: media, - target: targets, - hreflang: langs - } - }, - abbr: s, - acronym: s, - address: s, - applet: s, - area: { - attrs: { - alt: null, coords: null, href: null, target: null, ping: null, - media: media, hreflang: langs, type: null, - shape: ["default", "rect", "circle", "poly"] - } - }, - article: s, - aside: s, - audio: { - attrs: { - src: null, mediagroup: null, - crossorigin: ["anonymous", "use-credentials"], - preload: ["none", "metadata", "auto"], - autoplay: ["", "autoplay"], - loop: ["", "loop"], - controls: ["", "controls"] - } - }, - b: s, - base: { attrs: { href: null, target: targets } }, - basefont: s, - bdi: s, - bdo: s, - big: s, - blockquote: { attrs: { cite: null } }, - body: s, - br: s, - button: { - attrs: { - form: null, formaction: null, name: null, value: null, - autofocus: ["", "autofocus"], - disabled: ["", "autofocus"], - formenctype: encs, - formmethod: methods, - formnovalidate: ["", "novalidate"], - formtarget: targets, - type: ["submit", "reset", "button"] - } - }, - canvas: { attrs: { width: null, height: null } }, - caption: s, - center: s, - cite: s, - code: s, - col: { attrs: { span: null } }, - colgroup: { attrs: { span: null } }, - command: { - attrs: { - type: ["command", "checkbox", "radio"], - label: null, icon: null, radiogroup: null, command: null, title: null, - disabled: ["", "disabled"], - checked: ["", "checked"] - } - }, - data: { attrs: { value: null } }, - datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } }, - datalist: { attrs: { data: null } }, - dd: s, - del: { attrs: { cite: null, datetime: null } }, - details: { attrs: { open: ["", "open"] } }, - dfn: s, - dir: s, - div: s, - dl: s, - dt: s, - em: s, - embed: { attrs: { src: null, type: null, width: null, height: null } }, - eventsource: { attrs: { src: null } }, - fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } }, - figcaption: s, - figure: s, - font: s, - footer: s, - form: { - attrs: { - action: null, name: null, - "accept-charset": charsets, - autocomplete: ["on", "off"], - enctype: encs, - method: methods, - novalidate: ["", "novalidate"], - target: targets - } - }, - frame: s, - frameset: s, - h1: s, h2: s, h3: s, h4: s, h5: s, h6: s, - head: { - attrs: {}, - children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] - }, - header: s, - hgroup: s, - hr: s, - html: { - attrs: { manifest: null }, - children: ["head", "body"] - }, - i: s, - iframe: { - attrs: { - src: null, srcdoc: null, name: null, width: null, height: null, - sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], - seamless: ["", "seamless"] - } - }, - img: { - attrs: { - alt: null, src: null, ismap: null, usemap: null, width: null, height: null, - crossorigin: ["anonymous", "use-credentials"] - } - }, - input: { - attrs: { - alt: null, dirname: null, form: null, formaction: null, - height: null, list: null, max: null, maxlength: null, min: null, - name: null, pattern: null, placeholder: null, size: null, src: null, - step: null, value: null, width: null, - accept: ["audio/*", "video/*", "image/*"], - autocomplete: ["on", "off"], - autofocus: ["", "autofocus"], - checked: ["", "checked"], - disabled: ["", "disabled"], - formenctype: encs, - formmethod: methods, - formnovalidate: ["", "novalidate"], - formtarget: targets, - multiple: ["", "multiple"], - readonly: ["", "readonly"], - required: ["", "required"], - type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", - "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", - "file", "submit", "image", "reset", "button"] - } - }, - ins: { attrs: { cite: null, datetime: null } }, - kbd: s, - keygen: { - attrs: { - challenge: null, form: null, name: null, - autofocus: ["", "autofocus"], - disabled: ["", "disabled"], - keytype: ["RSA"] - } - }, - label: { attrs: { "for": null, form: null } }, - legend: s, - li: { attrs: { value: null } }, - link: { - attrs: { - href: null, type: null, - hreflang: langs, - media: media, - sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] - } - }, - map: { attrs: { name: null } }, - mark: s, - menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, - meta: { - attrs: { - content: null, - charset: charsets, - name: ["viewport", "application-name", "author", "description", "generator", "keywords"], - "http-equiv": ["content-language", "content-type", "default-style", "refresh"] - } - }, - meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, - nav: s, - noframes: s, - noscript: s, - object: { - attrs: { - data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, - typemustmatch: ["", "typemustmatch"] - } - }, - ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } }, - optgroup: { attrs: { disabled: ["", "disabled"], label: null } }, - option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } }, - output: { attrs: { "for": null, form: null, name: null } }, - p: s, - param: { attrs: { name: null, value: null } }, - pre: s, - progress: { attrs: { value: null, max: null } }, - q: { attrs: { cite: null } }, - rp: s, - rt: s, - ruby: s, - s: s, - samp: s, - script: { - attrs: { - type: ["text/javascript"], - src: null, - async: ["", "async"], - defer: ["", "defer"], - charset: charsets - } - }, - section: s, - select: { - attrs: { - form: null, name: null, size: null, - autofocus: ["", "autofocus"], - disabled: ["", "disabled"], - multiple: ["", "multiple"] - } - }, - small: s, - source: { attrs: { src: null, type: null, media: null } }, - span: s, - strike: s, - strong: s, - style: { - attrs: { - type: ["text/css"], - media: media, - scoped: null - } - }, - sub: s, - summary: s, - sup: s, - table: s, - tbody: s, - td: { attrs: { colspan: null, rowspan: null, headers: null } }, - textarea: { - attrs: { - dirname: null, form: null, maxlength: null, name: null, placeholder: null, - rows: null, cols: null, - autofocus: ["", "autofocus"], - disabled: ["", "disabled"], - readonly: ["", "readonly"], - required: ["", "required"], - wrap: ["soft", "hard"] - } - }, - tfoot: s, - th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, - thead: s, - time: { attrs: { datetime: null } }, - title: s, - tr: s, - track: { - attrs: { - src: null, label: null, "default": null, - kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], - srclang: langs - } - }, - tt: s, - u: s, - ul: s, - "var": s, - video: { - attrs: { - src: null, poster: null, width: null, height: null, - crossorigin: ["anonymous", "use-credentials"], - preload: ["auto", "metadata", "none"], - autoplay: ["", "autoplay"], - mediagroup: ["movie"], - muted: ["", "muted"], - controls: ["", "controls"] - } - }, - wbr: s - }; - - var globalAttrs = { - accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], - "class": null, - contenteditable: ["true", "false"], - contextmenu: null, - dir: ["ltr", "rtl", "auto"], - draggable: ["true", "false", "auto"], - dropzone: ["copy", "move", "link", "string:", "file:"], - hidden: ["hidden"], - id: null, - inert: ["inert"], - itemid: null, - itemprop: null, - itemref: null, - itemscope: ["itemscope"], - itemtype: null, - lang: ["en", "es"], - spellcheck: ["true", "false"], - style: null, - tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], - title: null, - translate: ["yes", "no"], - onclick: null, - rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"] - }; - function populate(obj) { - for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr)) - obj.attrs[attr] = globalAttrs[attr]; - } - - populate(s); - for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s) - populate(data[tag]); - - CodeMirror.htmlSchema = data; - function htmlHint(cm, options) { - var local = {schemaInfo: data}; - if (options) for (var opt in options) local[opt] = options[opt]; - return CodeMirror.hint.xml(cm, local); - } - CodeMirror.registerHelper("hint", "html", htmlHint); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./xml-hint")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./xml-hint"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "); + var targets = ["_blank", "_self", "_top", "_parent"]; + var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; + var methods = ["get", "post", "put", "delete"]; + var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; + var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech", + "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait", + "orientation:landscape", "device-height: [X]", "device-width: [X]"]; + var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags + + var data = { + a: { + attrs: { + href: null, ping: null, type: null, + media: media, + target: targets, + hreflang: langs + } + }, + abbr: s, + acronym: s, + address: s, + applet: s, + area: { + attrs: { + alt: null, coords: null, href: null, target: null, ping: null, + media: media, hreflang: langs, type: null, + shape: ["default", "rect", "circle", "poly"] + } + }, + article: s, + aside: s, + audio: { + attrs: { + src: null, mediagroup: null, + crossorigin: ["anonymous", "use-credentials"], + preload: ["none", "metadata", "auto"], + autoplay: ["", "autoplay"], + loop: ["", "loop"], + controls: ["", "controls"] + } + }, + b: s, + base: { attrs: { href: null, target: targets } }, + basefont: s, + bdi: s, + bdo: s, + big: s, + blockquote: { attrs: { cite: null } }, + body: s, + br: s, + button: { + attrs: { + form: null, formaction: null, name: null, value: null, + autofocus: ["", "autofocus"], + disabled: ["", "autofocus"], + formenctype: encs, + formmethod: methods, + formnovalidate: ["", "novalidate"], + formtarget: targets, + type: ["submit", "reset", "button"] + } + }, + canvas: { attrs: { width: null, height: null } }, + caption: s, + center: s, + cite: s, + code: s, + col: { attrs: { span: null } }, + colgroup: { attrs: { span: null } }, + command: { + attrs: { + type: ["command", "checkbox", "radio"], + label: null, icon: null, radiogroup: null, command: null, title: null, + disabled: ["", "disabled"], + checked: ["", "checked"] + } + }, + data: { attrs: { value: null } }, + datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } }, + datalist: { attrs: { data: null } }, + dd: s, + del: { attrs: { cite: null, datetime: null } }, + details: { attrs: { open: ["", "open"] } }, + dfn: s, + dir: s, + div: s, + dl: s, + dt: s, + em: s, + embed: { attrs: { src: null, type: null, width: null, height: null } }, + eventsource: { attrs: { src: null } }, + fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } }, + figcaption: s, + figure: s, + font: s, + footer: s, + form: { + attrs: { + action: null, name: null, + "accept-charset": charsets, + autocomplete: ["on", "off"], + enctype: encs, + method: methods, + novalidate: ["", "novalidate"], + target: targets + } + }, + frame: s, + frameset: s, + h1: s, h2: s, h3: s, h4: s, h5: s, h6: s, + head: { + attrs: {}, + children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] + }, + header: s, + hgroup: s, + hr: s, + html: { + attrs: { manifest: null }, + children: ["head", "body"] + }, + i: s, + iframe: { + attrs: { + src: null, srcdoc: null, name: null, width: null, height: null, + sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], + seamless: ["", "seamless"] + } + }, + img: { + attrs: { + alt: null, src: null, ismap: null, usemap: null, width: null, height: null, + crossorigin: ["anonymous", "use-credentials"] + } + }, + input: { + attrs: { + alt: null, dirname: null, form: null, formaction: null, + height: null, list: null, max: null, maxlength: null, min: null, + name: null, pattern: null, placeholder: null, size: null, src: null, + step: null, value: null, width: null, + accept: ["audio/*", "video/*", "image/*"], + autocomplete: ["on", "off"], + autofocus: ["", "autofocus"], + checked: ["", "checked"], + disabled: ["", "disabled"], + formenctype: encs, + formmethod: methods, + formnovalidate: ["", "novalidate"], + formtarget: targets, + multiple: ["", "multiple"], + readonly: ["", "readonly"], + required: ["", "required"], + type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", + "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", + "file", "submit", "image", "reset", "button"] + } + }, + ins: { attrs: { cite: null, datetime: null } }, + kbd: s, + keygen: { + attrs: { + challenge: null, form: null, name: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + keytype: ["RSA"] + } + }, + label: { attrs: { "for": null, form: null } }, + legend: s, + li: { attrs: { value: null } }, + link: { + attrs: { + href: null, type: null, + hreflang: langs, + media: media, + sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] + } + }, + map: { attrs: { name: null } }, + mark: s, + menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, + meta: { + attrs: { + content: null, + charset: charsets, + name: ["viewport", "application-name", "author", "description", "generator", "keywords"], + "http-equiv": ["content-language", "content-type", "default-style", "refresh"] + } + }, + meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, + nav: s, + noframes: s, + noscript: s, + object: { + attrs: { + data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, + typemustmatch: ["", "typemustmatch"] + } + }, + ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } }, + optgroup: { attrs: { disabled: ["", "disabled"], label: null } }, + option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } }, + output: { attrs: { "for": null, form: null, name: null } }, + p: s, + param: { attrs: { name: null, value: null } }, + pre: s, + progress: { attrs: { value: null, max: null } }, + q: { attrs: { cite: null } }, + rp: s, + rt: s, + ruby: s, + s: s, + samp: s, + script: { + attrs: { + type: ["text/javascript"], + src: null, + async: ["", "async"], + defer: ["", "defer"], + charset: charsets + } + }, + section: s, + select: { + attrs: { + form: null, name: null, size: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + multiple: ["", "multiple"] + } + }, + small: s, + source: { attrs: { src: null, type: null, media: null } }, + span: s, + strike: s, + strong: s, + style: { + attrs: { + type: ["text/css"], + media: media, + scoped: null + } + }, + sub: s, + summary: s, + sup: s, + table: s, + tbody: s, + td: { attrs: { colspan: null, rowspan: null, headers: null } }, + textarea: { + attrs: { + dirname: null, form: null, maxlength: null, name: null, placeholder: null, + rows: null, cols: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + readonly: ["", "readonly"], + required: ["", "required"], + wrap: ["soft", "hard"] + } + }, + tfoot: s, + th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, + thead: s, + time: { attrs: { datetime: null } }, + title: s, + tr: s, + track: { + attrs: { + src: null, label: null, "default": null, + kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], + srclang: langs + } + }, + tt: s, + u: s, + ul: s, + "var": s, + video: { + attrs: { + src: null, poster: null, width: null, height: null, + crossorigin: ["anonymous", "use-credentials"], + preload: ["auto", "metadata", "none"], + autoplay: ["", "autoplay"], + mediagroup: ["movie"], + muted: ["", "muted"], + controls: ["", "controls"] + } + }, + wbr: s + }; + + var globalAttrs = { + accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], + "class": null, + contenteditable: ["true", "false"], + contextmenu: null, + dir: ["ltr", "rtl", "auto"], + draggable: ["true", "false", "auto"], + dropzone: ["copy", "move", "link", "string:", "file:"], + hidden: ["hidden"], + id: null, + inert: ["inert"], + itemid: null, + itemprop: null, + itemref: null, + itemscope: ["itemscope"], + itemtype: null, + lang: ["en", "es"], + spellcheck: ["true", "false"], + style: null, + tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], + title: null, + translate: ["yes", "no"], + onclick: null, + rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"] + }; + function populate(obj) { + for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr)) + obj.attrs[attr] = globalAttrs[attr]; + } + + populate(s); + for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s) + populate(data[tag]); + + CodeMirror.htmlSchema = data; + function htmlHint(cm, options) { + var local = {schemaInfo: data}; + if (options) for (var opt in options) local[opt] = options[opt]; + return CodeMirror.hint.xml(cm, local); + } + CodeMirror.registerHelper("hint", "html", htmlHint); +}); diff --git a/shared/codemirror/addon/hint/javascript-hint.js b/shared/codemirror/addon/hint/javascript-hint.js index 7bcbf4a..dbee8b8 100644 --- a/shared/codemirror/addon/hint/javascript-hint.js +++ b/shared/codemirror/addon/hint/javascript-hint.js @@ -1,146 +1,146 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - var Pos = CodeMirror.Pos; - - function forEach(arr, f) { - for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); - } - - function arrayContains(arr, item) { - if (!Array.prototype.indexOf) { - var i = arr.length; - while (i--) { - if (arr[i] === item) { - return true; - } - } - return false; - } - return arr.indexOf(item) != -1; - } - - function scriptHint(editor, keywords, getToken, options) { - // Find the token at the cursor - var cur = editor.getCursor(), token = getToken(editor, cur); - if (/\b(?:string|comment)\b/.test(token.type)) return; - token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; - - // If it's not a 'word-style' token, ignore the token. - if (!/^[\w$_]*$/.test(token.string)) { - token = {start: cur.ch, end: cur.ch, string: "", state: token.state, - type: token.string == "." ? "property" : null}; - } else if (token.end > cur.ch) { - token.end = cur.ch; - token.string = token.string.slice(0, cur.ch - token.start); - } - - var tprop = token; - // If it is a property, find out what it is a property of. - while (tprop.type == "property") { - tprop = getToken(editor, Pos(cur.line, tprop.start)); - if (tprop.string != ".") return; - tprop = getToken(editor, Pos(cur.line, tprop.start)); - if (!context) var context = []; - context.push(tprop); - } - return {list: getCompletions(token, context, keywords, options), - from: Pos(cur.line, token.start), - to: Pos(cur.line, token.end)}; - } - - function javascriptHint(editor, options) { - return scriptHint(editor, javascriptKeywords, - function (e, cur) {return e.getTokenAt(cur);}, - options); - }; - CodeMirror.registerHelper("hint", "javascript", javascriptHint); - - function getCoffeeScriptToken(editor, cur) { - // This getToken, it is for coffeescript, imitates the behavior of - // getTokenAt method in javascript.js, that is, returning "property" - // type and treat "." as indepenent token. - var token = editor.getTokenAt(cur); - if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { - token.end = token.start; - token.string = '.'; - token.type = "property"; - } - else if (/^\.[\w$_]*$/.test(token.string)) { - token.type = "property"; - token.start++; - token.string = token.string.replace(/\./, ''); - } - return token; - } - - function coffeescriptHint(editor, options) { - return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); - } - CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); - - var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + - "toUpperCase toLowerCase split concat match replace search").split(" "); - var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + - "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); - var funcProps = "prototype apply call bind".split(" "); - var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + - "if in instanceof new null return switch throw true try typeof var void while with").split(" "); - var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + - "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); - - function getCompletions(token, context, keywords, options) { - var found = [], start = token.string, global = options && options.globalScope || window; - function maybeAdd(str) { - if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); - } - function gatherCompletions(obj) { - if (typeof obj == "string") forEach(stringProps, maybeAdd); - else if (obj instanceof Array) forEach(arrayProps, maybeAdd); - else if (obj instanceof Function) forEach(funcProps, maybeAdd); - for (var name in obj) maybeAdd(name); - } - - if (context && context.length) { - // If this is a property, see if it belongs to some object we can - // find in the current environment. - var obj = context.pop(), base; - if (obj.type && obj.type.indexOf("variable") === 0) { - if (options && options.additionalContext) - base = options.additionalContext[obj.string]; - if (!options || options.useGlobalScope !== false) - base = base || global[obj.string]; - } else if (obj.type == "string") { - base = ""; - } else if (obj.type == "atom") { - base = 1; - } else if (obj.type == "function") { - if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && - (typeof global.jQuery == 'function')) - base = global.jQuery(); - else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function')) - base = global._(); - } - while (base != null && context.length) - base = base[context.pop().string]; - if (base != null) gatherCompletions(base); - } else { - // If not, just look in the global object and any local scope - // (reading into JS mode internals to get at the local and global variables) - for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); - for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); - if (!options || options.useGlobalScope !== false) - gatherCompletions(global); - forEach(keywords, maybeAdd); - } - return found; - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var Pos = CodeMirror.Pos; + + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, keywords, getToken, options) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur); + if (/\b(?:string|comment)\b/.test(token.type)) return; + token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; + + // If it's not a 'word-style' token, ignore the token. + if (!/^[\w$_]*$/.test(token.string)) { + token = {start: cur.ch, end: cur.ch, string: "", state: token.state, + type: token.string == "." ? "property" : null}; + } else if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + + var tprop = token; + // If it is a property, find out what it is a property of. + while (tprop.type == "property") { + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.string != ".") return; + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (!context) var context = []; + context.push(tprop); + } + return {list: getCompletions(token, context, keywords, options), + from: Pos(cur.line, token.start), + to: Pos(cur.line, token.end)}; + } + + function javascriptHint(editor, options) { + return scriptHint(editor, javascriptKeywords, + function (e, cur) {return e.getTokenAt(cur);}, + options); + }; + CodeMirror.registerHelper("hint", "javascript", javascriptHint); + + function getCoffeeScriptToken(editor, cur) { + // This getToken, it is for coffeescript, imitates the behavior of + // getTokenAt method in javascript.js, that is, returning "property" + // type and treat "." as indepenent token. + var token = editor.getTokenAt(cur); + if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { + token.end = token.start; + token.string = '.'; + token.type = "property"; + } + else if (/^\.[\w$_]*$/.test(token.string)) { + token.type = "property"; + token.start++; + token.string = token.string.replace(/\./, ''); + } + return token; + } + + function coffeescriptHint(editor, options) { + return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); + } + CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); + + var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + + "toUpperCase toLowerCase split concat match replace search").split(" "); + var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + + "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); + var funcProps = "prototype apply call bind".split(" "); + var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + + "if in instanceof new null return switch throw true try typeof var void while with").split(" "); + var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + + "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); + + function getCompletions(token, context, keywords, options) { + var found = [], start = token.string, global = options && options.globalScope || window; + function maybeAdd(str) { + if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); + } + function gatherCompletions(obj) { + if (typeof obj == "string") forEach(stringProps, maybeAdd); + else if (obj instanceof Array) forEach(arrayProps, maybeAdd); + else if (obj instanceof Function) forEach(funcProps, maybeAdd); + for (var name in obj) maybeAdd(name); + } + + if (context && context.length) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + if (obj.type && obj.type.indexOf("variable") === 0) { + if (options && options.additionalContext) + base = options.additionalContext[obj.string]; + if (!options || options.useGlobalScope !== false) + base = base || global[obj.string]; + } else if (obj.type == "string") { + base = ""; + } else if (obj.type == "atom") { + base = 1; + } else if (obj.type == "function") { + if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && + (typeof global.jQuery == 'function')) + base = global.jQuery(); + else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function')) + base = global._(); + } + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } else { + // If not, just look in the global object and any local scope + // (reading into JS mode internals to get at the local and global variables) + for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); + for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); + if (!options || options.useGlobalScope !== false) + gatherCompletions(global); + forEach(keywords, maybeAdd); + } + return found; + } +}); diff --git a/shared/codemirror/addon/hint/show-hint.css b/shared/codemirror/addon/hint/show-hint.css index 924e638..e38bfb6 100644 --- a/shared/codemirror/addon/hint/show-hint.css +++ b/shared/codemirror/addon/hint/show-hint.css @@ -1,38 +1,38 @@ -.CodeMirror-hints { - position: absolute; - z-index: 10; - overflow: hidden; - list-style: none; - - margin: 0; - padding: 2px; - - -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - border-radius: 3px; - border: 1px solid silver; - - background: white; - font-size: 90%; - font-family: monospace; - - max-height: 20em; - overflow-y: auto; -} - -.CodeMirror-hint { - margin: 0; - padding: 0 4px; - border-radius: 2px; - max-width: 19em; - overflow: hidden; - white-space: pre; - color: black; - cursor: pointer; -} - -li.CodeMirror-hint-active { - background: #08f; - color: white; -} +.CodeMirror-hints { + position: absolute; + z-index: 10; + overflow: hidden; + list-style: none; + + margin: 0; + padding: 2px; + + -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + border-radius: 3px; + border: 1px solid silver; + + background: white; + font-size: 90%; + font-family: monospace; + + max-height: 20em; + overflow-y: auto; +} + +.CodeMirror-hint { + margin: 0; + padding: 0 4px; + border-radius: 2px; + max-width: 19em; + overflow: hidden; + white-space: pre; + color: black; + cursor: pointer; +} + +li.CodeMirror-hint-active { + background: #08f; + color: white; +} diff --git a/shared/codemirror/addon/hint/show-hint.js b/shared/codemirror/addon/hint/show-hint.js index f426b5c..2589fc6 100644 --- a/shared/codemirror/addon/hint/show-hint.js +++ b/shared/codemirror/addon/hint/show-hint.js @@ -1,434 +1,434 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var HINT_ELEMENT_CLASS = "CodeMirror-hint"; - var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; - - // This is the old interface, kept around for now to stay - // backwards-compatible. - CodeMirror.showHint = function(cm, getHints, options) { - if (!getHints) return cm.showHint(options); - if (options && options.async) getHints.async = true; - var newOpts = {hint: getHints}; - if (options) for (var prop in options) newOpts[prop] = options[prop]; - return cm.showHint(newOpts); - }; - - CodeMirror.defineExtension("showHint", function(options) { - options = parseOptions(this, this.getCursor("start"), options); - var selections = this.listSelections() - if (selections.length > 1) return; - // By default, don't allow completion when something is selected. - // A hint function can have a `supportsSelection` property to - // indicate that it can handle selections. - if (this.somethingSelected()) { - if (!options.hint.supportsSelection) return; - // Don't try with cross-line selections - for (var i = 0; i < selections.length; i++) - if (selections[i].head.line != selections[i].anchor.line) return; - } - - if (this.state.completionActive) this.state.completionActive.close(); - var completion = this.state.completionActive = new Completion(this, options); - if (!completion.options.hint) return; - - CodeMirror.signal(this, "startCompletion", this); - completion.update(true); - }); - - function Completion(cm, options) { - this.cm = cm; - this.options = options; - this.widget = null; - this.debounce = 0; - this.tick = 0; - this.startPos = this.cm.getCursor("start"); - this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; - - var self = this; - cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); }); - } - - var requestAnimationFrame = window.requestAnimationFrame || function(fn) { - return setTimeout(fn, 1000/60); - }; - var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; - - Completion.prototype = { - close: function() { - if (!this.active()) return; - this.cm.state.completionActive = null; - this.tick = null; - this.cm.off("cursorActivity", this.activityFunc); - - if (this.widget && this.data) CodeMirror.signal(this.data, "close"); - if (this.widget) this.widget.close(); - CodeMirror.signal(this.cm, "endCompletion", this.cm); - }, - - active: function() { - return this.cm.state.completionActive == this; - }, - - pick: function(data, i) { - var completion = data.list[i]; - if (completion.hint) completion.hint(this.cm, data, completion); - else this.cm.replaceRange(getText(completion), completion.from || data.from, - completion.to || data.to, "complete"); - CodeMirror.signal(data, "pick", completion); - this.close(); - }, - - cursorActivity: function() { - if (this.debounce) { - cancelAnimationFrame(this.debounce); - this.debounce = 0; - } - - var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); - if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || - pos.ch < this.startPos.ch || this.cm.somethingSelected() || - (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { - this.close(); - } else { - var self = this; - this.debounce = requestAnimationFrame(function() {self.update();}); - if (this.widget) this.widget.disable(); - } - }, - - update: function(first) { - if (this.tick == null) return - var self = this, myTick = ++this.tick - fetchHints(this.options.hint, this.cm, this.options, function(data) { - if (self.tick == myTick) self.finishUpdate(data, first) - }) - }, - - finishUpdate: function(data, first) { - if (this.data) CodeMirror.signal(this.data, "update"); - - var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); - if (this.widget) this.widget.close(); - - if (data && this.data && isNewCompletion(this.data, data)) return; - this.data = data; - - if (data && data.list.length) { - if (picked && data.list.length == 1) { - this.pick(data, 0); - } else { - this.widget = new Widget(this, data); - CodeMirror.signal(data, "shown"); - } - } - } - }; - - function isNewCompletion(old, nw) { - var moved = CodeMirror.cmpPos(nw.from, old.from) - return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch - } - - function parseOptions(cm, pos, options) { - var editor = cm.options.hintOptions; - var out = {}; - for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; - if (editor) for (var prop in editor) - if (editor[prop] !== undefined) out[prop] = editor[prop]; - if (options) for (var prop in options) - if (options[prop] !== undefined) out[prop] = options[prop]; - if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos) - return out; - } - - function getText(completion) { - if (typeof completion == "string") return completion; - else return completion.text; - } - - function buildKeyMap(completion, handle) { - var baseMap = { - Up: function() {handle.moveFocus(-1);}, - Down: function() {handle.moveFocus(1);}, - PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);}, - PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);}, - Home: function() {handle.setFocus(0);}, - End: function() {handle.setFocus(handle.length - 1);}, - Enter: handle.pick, - Tab: handle.pick, - Esc: handle.close - }; - var custom = completion.options.customKeys; - var ourMap = custom ? {} : baseMap; - function addBinding(key, val) { - var bound; - if (typeof val != "string") - bound = function(cm) { return val(cm, handle); }; - // This mechanism is deprecated - else if (baseMap.hasOwnProperty(val)) - bound = baseMap[val]; - else - bound = val; - ourMap[key] = bound; - } - if (custom) - for (var key in custom) if (custom.hasOwnProperty(key)) - addBinding(key, custom[key]); - var extra = completion.options.extraKeys; - if (extra) - for (var key in extra) if (extra.hasOwnProperty(key)) - addBinding(key, extra[key]); - return ourMap; - } - - function getHintElement(hintsElement, el) { - while (el && el != hintsElement) { - if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; - el = el.parentNode; - } - } - - function Widget(completion, data) { - this.completion = completion; - this.data = data; - this.picked = false; - var widget = this, cm = completion.cm; - - var hints = this.hints = document.createElement("ul"); - hints.className = "CodeMirror-hints"; - this.selectedHint = data.selectedHint || 0; - - var completions = data.list; - for (var i = 0; i < completions.length; ++i) { - var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; - var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); - if (cur.className != null) className = cur.className + " " + className; - elt.className = className; - if (cur.render) cur.render(elt, data, cur); - else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); - elt.hintId = i; - } - - var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); - var left = pos.left, top = pos.bottom, below = true; - hints.style.left = left + "px"; - hints.style.top = top + "px"; - // 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); - var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); - (completion.options.container || document.body).appendChild(hints); - var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; - if (overlapY > 0) { - var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); - if (curTop - height > 0) { // Fits above cursor - hints.style.top = (top = pos.top - height) + "px"; - below = false; - } else if (height > winH) { - hints.style.height = (winH - 5) + "px"; - hints.style.top = (top = pos.bottom - box.top) + "px"; - var cursor = cm.getCursor(); - if (data.from.ch != cursor.ch) { - pos = cm.cursorCoords(cursor); - hints.style.left = (left = pos.left) + "px"; - box = hints.getBoundingClientRect(); - } - } - } - var overlapX = box.right - winW; - if (overlapX > 0) { - if (box.right - box.left > winW) { - hints.style.width = (winW - 5) + "px"; - overlapX -= (box.right - box.left) - winW; - } - hints.style.left = (left = pos.left - overlapX) + "px"; - } - - cm.addKeyMap(this.keyMap = buildKeyMap(completion, { - moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, - setFocus: function(n) { widget.changeActive(n); }, - menuSize: function() { return widget.screenAmount(); }, - length: completions.length, - close: function() { completion.close(); }, - pick: function() { widget.pick(); }, - data: data - })); - - if (completion.options.closeOnUnfocus) { - var closingOnBlur; - cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); - cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); - } - - var startScroll = cm.getScrollInfo(); - cm.on("scroll", this.onScroll = function() { - var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); - var newTop = top + startScroll.top - curScroll.top; - var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); - if (!below) point += hints.offsetHeight; - if (point <= editor.top || point >= editor.bottom) return completion.close(); - hints.style.top = newTop + "px"; - hints.style.left = (left + startScroll.left - curScroll.left) + "px"; - }); - - CodeMirror.on(hints, "dblclick", function(e) { - var t = getHintElement(hints, e.target || e.srcElement); - if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} - }); - - CodeMirror.on(hints, "click", function(e) { - var t = getHintElement(hints, e.target || e.srcElement); - if (t && t.hintId != null) { - widget.changeActive(t.hintId); - if (completion.options.completeOnSingleClick) widget.pick(); - } - }); - - CodeMirror.on(hints, "mousedown", function() { - setTimeout(function(){cm.focus();}, 20); - }); - - CodeMirror.signal(data, "select", completions[0], hints.firstChild); - return true; - } - - Widget.prototype = { - close: function() { - if (this.completion.widget != this) return; - this.completion.widget = null; - this.hints.parentNode.removeChild(this.hints); - this.completion.cm.removeKeyMap(this.keyMap); - - var cm = this.completion.cm; - if (this.completion.options.closeOnUnfocus) { - cm.off("blur", this.onBlur); - cm.off("focus", this.onFocus); - } - cm.off("scroll", this.onScroll); - }, - - disable: function() { - this.completion.cm.removeKeyMap(this.keyMap); - var widget = this; - this.keyMap = {Enter: function() { widget.picked = true; }}; - this.completion.cm.addKeyMap(this.keyMap); - }, - - pick: function() { - this.completion.pick(this.data, this.selectedHint); - }, - - changeActive: function(i, avoidWrap) { - if (i >= this.data.list.length) - i = avoidWrap ? this.data.list.length - 1 : 0; - else if (i < 0) - i = avoidWrap ? 0 : this.data.list.length - 1; - if (this.selectedHint == i) return; - var node = this.hints.childNodes[this.selectedHint]; - node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); - node = this.hints.childNodes[this.selectedHint = i]; - node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; - if (node.offsetTop < this.hints.scrollTop) - this.hints.scrollTop = node.offsetTop - 3; - else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) - this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; - CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); - }, - - screenAmount: function() { - return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; - } - }; - - function applicableHelpers(cm, helpers) { - if (!cm.somethingSelected()) return helpers - var result = [] - for (var i = 0; i < helpers.length; i++) - if (helpers[i].supportsSelection) result.push(helpers[i]) - return result - } - - function fetchHints(hint, cm, options, callback) { - if (hint.async) { - hint(cm, callback, options) - } else { - var result = hint(cm, options) - if (result && result.then) result.then(callback) - else callback(result) - } - } - - function resolveAutoHints(cm, pos) { - var helpers = cm.getHelpers(pos, "hint"), words - if (helpers.length) { - var resolved = function(cm, callback, options) { - var app = applicableHelpers(cm, helpers); - function run(i) { - if (i == app.length) return callback(null) - fetchHints(app[i], cm, options, function(result) { - if (result && result.list.length > 0) callback(result) - else run(i + 1) - }) - } - run(0) - } - resolved.async = true - resolved.supportsSelection = true - return resolved - } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { - return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) } - } else if (CodeMirror.hint.anyword) { - return function(cm, options) { return CodeMirror.hint.anyword(cm, options) } - } else { - return function() {} - } - } - - CodeMirror.registerHelper("hint", "auto", { - resolve: resolveAutoHints - }); - - CodeMirror.registerHelper("hint", "fromList", function(cm, options) { - var cur = cm.getCursor(), token = cm.getTokenAt(cur); - var to = CodeMirror.Pos(cur.line, token.end); - if (token.string && /\w/.test(token.string[token.string.length - 1])) { - var term = token.string, from = CodeMirror.Pos(cur.line, token.start); - } else { - var term = "", from = to; - } - var found = []; - for (var i = 0; i < options.words.length; i++) { - var word = options.words[i]; - if (word.slice(0, term.length) == term) - found.push(word); - } - - if (found.length) return {list: found, from: from, to: to}; - }); - - CodeMirror.commands.autocomplete = CodeMirror.showHint; - - var defaultOptions = { - hint: CodeMirror.hint.auto, - completeSingle: true, - alignWithWord: true, - closeCharacters: /[\s()\[\]{};:>,]/, - closeOnUnfocus: true, - completeOnSingleClick: true, - container: null, - customKeys: null, - extraKeys: null - }; - - CodeMirror.defineOption("hintOptions", null); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var HINT_ELEMENT_CLASS = "CodeMirror-hint"; + var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; + + // This is the old interface, kept around for now to stay + // backwards-compatible. + CodeMirror.showHint = function(cm, getHints, options) { + if (!getHints) return cm.showHint(options); + if (options && options.async) getHints.async = true; + var newOpts = {hint: getHints}; + if (options) for (var prop in options) newOpts[prop] = options[prop]; + return cm.showHint(newOpts); + }; + + CodeMirror.defineExtension("showHint", function(options) { + options = parseOptions(this, this.getCursor("start"), options); + var selections = this.listSelections() + if (selections.length > 1) return; + // By default, don't allow completion when something is selected. + // A hint function can have a `supportsSelection` property to + // indicate that it can handle selections. + if (this.somethingSelected()) { + if (!options.hint.supportsSelection) return; + // Don't try with cross-line selections + for (var i = 0; i < selections.length; i++) + if (selections[i].head.line != selections[i].anchor.line) return; + } + + if (this.state.completionActive) this.state.completionActive.close(); + var completion = this.state.completionActive = new Completion(this, options); + if (!completion.options.hint) return; + + CodeMirror.signal(this, "startCompletion", this); + completion.update(true); + }); + + function Completion(cm, options) { + this.cm = cm; + this.options = options; + this.widget = null; + this.debounce = 0; + this.tick = 0; + this.startPos = this.cm.getCursor("start"); + this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; + + var self = this; + cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); }); + } + + var requestAnimationFrame = window.requestAnimationFrame || function(fn) { + return setTimeout(fn, 1000/60); + }; + var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; + + Completion.prototype = { + close: function() { + if (!this.active()) return; + this.cm.state.completionActive = null; + this.tick = null; + this.cm.off("cursorActivity", this.activityFunc); + + if (this.widget && this.data) CodeMirror.signal(this.data, "close"); + if (this.widget) this.widget.close(); + CodeMirror.signal(this.cm, "endCompletion", this.cm); + }, + + active: function() { + return this.cm.state.completionActive == this; + }, + + pick: function(data, i) { + var completion = data.list[i]; + if (completion.hint) completion.hint(this.cm, data, completion); + else this.cm.replaceRange(getText(completion), completion.from || data.from, + completion.to || data.to, "complete"); + CodeMirror.signal(data, "pick", completion); + this.close(); + }, + + cursorActivity: function() { + if (this.debounce) { + cancelAnimationFrame(this.debounce); + this.debounce = 0; + } + + var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); + if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || + pos.ch < this.startPos.ch || this.cm.somethingSelected() || + (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { + this.close(); + } else { + var self = this; + this.debounce = requestAnimationFrame(function() {self.update();}); + if (this.widget) this.widget.disable(); + } + }, + + update: function(first) { + if (this.tick == null) return + var self = this, myTick = ++this.tick + fetchHints(this.options.hint, this.cm, this.options, function(data) { + if (self.tick == myTick) self.finishUpdate(data, first) + }) + }, + + finishUpdate: function(data, first) { + if (this.data) CodeMirror.signal(this.data, "update"); + + var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); + if (this.widget) this.widget.close(); + + if (data && this.data && isNewCompletion(this.data, data)) return; + this.data = data; + + if (data && data.list.length) { + if (picked && data.list.length == 1) { + this.pick(data, 0); + } else { + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); + } + } + } + }; + + function isNewCompletion(old, nw) { + var moved = CodeMirror.cmpPos(nw.from, old.from) + return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch + } + + function parseOptions(cm, pos, options) { + var editor = cm.options.hintOptions; + var out = {}; + for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; + if (editor) for (var prop in editor) + if (editor[prop] !== undefined) out[prop] = editor[prop]; + if (options) for (var prop in options) + if (options[prop] !== undefined) out[prop] = options[prop]; + if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos) + return out; + } + + function getText(completion) { + if (typeof completion == "string") return completion; + else return completion.text; + } + + function buildKeyMap(completion, handle) { + var baseMap = { + Up: function() {handle.moveFocus(-1);}, + Down: function() {handle.moveFocus(1);}, + PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);}, + PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);}, + Home: function() {handle.setFocus(0);}, + End: function() {handle.setFocus(handle.length - 1);}, + Enter: handle.pick, + Tab: handle.pick, + Esc: handle.close + }; + var custom = completion.options.customKeys; + var ourMap = custom ? {} : baseMap; + function addBinding(key, val) { + var bound; + if (typeof val != "string") + bound = function(cm) { return val(cm, handle); }; + // This mechanism is deprecated + else if (baseMap.hasOwnProperty(val)) + bound = baseMap[val]; + else + bound = val; + ourMap[key] = bound; + } + if (custom) + for (var key in custom) if (custom.hasOwnProperty(key)) + addBinding(key, custom[key]); + var extra = completion.options.extraKeys; + if (extra) + for (var key in extra) if (extra.hasOwnProperty(key)) + addBinding(key, extra[key]); + return ourMap; + } + + function getHintElement(hintsElement, el) { + while (el && el != hintsElement) { + if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; + el = el.parentNode; + } + } + + function Widget(completion, data) { + this.completion = completion; + this.data = data; + this.picked = false; + var widget = this, cm = completion.cm; + + var hints = this.hints = document.createElement("ul"); + hints.className = "CodeMirror-hints"; + this.selectedHint = data.selectedHint || 0; + + var completions = data.list; + for (var i = 0; i < completions.length; ++i) { + var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; + var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + if (cur.render) cur.render(elt, data, cur); + else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); + elt.hintId = i; + } + + var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); + var left = pos.left, top = pos.bottom, below = true; + hints.style.left = left + "px"; + hints.style.top = top + "px"; + // 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); + var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); + (completion.options.container || document.body).appendChild(hints); + var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; + if (overlapY > 0) { + var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); + if (curTop - height > 0) { // Fits above cursor + hints.style.top = (top = pos.top - height) + "px"; + below = false; + } else if (height > winH) { + hints.style.height = (winH - 5) + "px"; + hints.style.top = (top = pos.bottom - box.top) + "px"; + var cursor = cm.getCursor(); + if (data.from.ch != cursor.ch) { + pos = cm.cursorCoords(cursor); + hints.style.left = (left = pos.left) + "px"; + box = hints.getBoundingClientRect(); + } + } + } + var overlapX = box.right - winW; + if (overlapX > 0) { + if (box.right - box.left > winW) { + hints.style.width = (winW - 5) + "px"; + overlapX -= (box.right - box.left) - winW; + } + hints.style.left = (left = pos.left - overlapX) + "px"; + } + + cm.addKeyMap(this.keyMap = buildKeyMap(completion, { + moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, + setFocus: function(n) { widget.changeActive(n); }, + menuSize: function() { return widget.screenAmount(); }, + length: completions.length, + close: function() { completion.close(); }, + pick: function() { widget.pick(); }, + data: data + })); + + if (completion.options.closeOnUnfocus) { + var closingOnBlur; + cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); + cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); + } + + var startScroll = cm.getScrollInfo(); + cm.on("scroll", this.onScroll = function() { + var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + var newTop = top + startScroll.top - curScroll.top; + var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); + if (!below) point += hints.offsetHeight; + if (point <= editor.top || point >= editor.bottom) return completion.close(); + hints.style.top = newTop + "px"; + hints.style.left = (left + startScroll.left - curScroll.left) + "px"; + }); + + CodeMirror.on(hints, "dblclick", function(e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} + }); + + CodeMirror.on(hints, "click", function(e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + if (completion.options.completeOnSingleClick) widget.pick(); + } + }); + + CodeMirror.on(hints, "mousedown", function() { + setTimeout(function(){cm.focus();}, 20); + }); + + CodeMirror.signal(data, "select", completions[0], hints.firstChild); + return true; + } + + Widget.prototype = { + close: function() { + if (this.completion.widget != this) return; + this.completion.widget = null; + this.hints.parentNode.removeChild(this.hints); + this.completion.cm.removeKeyMap(this.keyMap); + + var cm = this.completion.cm; + if (this.completion.options.closeOnUnfocus) { + cm.off("blur", this.onBlur); + cm.off("focus", this.onFocus); + } + cm.off("scroll", this.onScroll); + }, + + disable: function() { + this.completion.cm.removeKeyMap(this.keyMap); + var widget = this; + this.keyMap = {Enter: function() { widget.picked = true; }}; + this.completion.cm.addKeyMap(this.keyMap); + }, + + pick: function() { + this.completion.pick(this.data, this.selectedHint); + }, + + changeActive: function(i, avoidWrap) { + if (i >= this.data.list.length) + i = avoidWrap ? this.data.list.length - 1 : 0; + else if (i < 0) + i = avoidWrap ? 0 : this.data.list.length - 1; + if (this.selectedHint == i) return; + var node = this.hints.childNodes[this.selectedHint]; + node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + node = this.hints.childNodes[this.selectedHint = i]; + node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; + if (node.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node.offsetTop - 3; + else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; + CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); + }, + + screenAmount: function() { + return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; + } + }; + + function applicableHelpers(cm, helpers) { + if (!cm.somethingSelected()) return helpers + var result = [] + for (var i = 0; i < helpers.length; i++) + if (helpers[i].supportsSelection) result.push(helpers[i]) + return result + } + + function fetchHints(hint, cm, options, callback) { + if (hint.async) { + hint(cm, callback, options) + } else { + var result = hint(cm, options) + if (result && result.then) result.then(callback) + else callback(result) + } + } + + function resolveAutoHints(cm, pos) { + var helpers = cm.getHelpers(pos, "hint"), words + if (helpers.length) { + var resolved = function(cm, callback, options) { + var app = applicableHelpers(cm, helpers); + function run(i) { + if (i == app.length) return callback(null) + fetchHints(app[i], cm, options, function(result) { + if (result && result.list.length > 0) callback(result) + else run(i + 1) + }) + } + run(0) + } + resolved.async = true + resolved.supportsSelection = true + return resolved + } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { + return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) } + } else if (CodeMirror.hint.anyword) { + return function(cm, options) { return CodeMirror.hint.anyword(cm, options) } + } else { + return function() {} + } + } + + CodeMirror.registerHelper("hint", "auto", { + resolve: resolveAutoHints + }); + + CodeMirror.registerHelper("hint", "fromList", function(cm, options) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var to = CodeMirror.Pos(cur.line, token.end); + if (token.string && /\w/.test(token.string[token.string.length - 1])) { + var term = token.string, from = CodeMirror.Pos(cur.line, token.start); + } else { + var term = "", from = to; + } + var found = []; + for (var i = 0; i < options.words.length; i++) { + var word = options.words[i]; + if (word.slice(0, term.length) == term) + found.push(word); + } + + if (found.length) return {list: found, from: from, to: to}; + }); + + CodeMirror.commands.autocomplete = CodeMirror.showHint; + + var defaultOptions = { + hint: CodeMirror.hint.auto, + completeSingle: true, + alignWithWord: true, + closeCharacters: /[\s()\[\]{};:>,]/, + closeOnUnfocus: true, + completeOnSingleClick: true, + container: null, + customKeys: null, + extraKeys: null + }; + + CodeMirror.defineOption("hintOptions", null); +}); diff --git a/shared/codemirror/addon/hint/sql-hint.js b/shared/codemirror/addon/hint/sql-hint.js index 62c4f68..ddd4854 100644 --- a/shared/codemirror/addon/hint/sql-hint.js +++ b/shared/codemirror/addon/hint/sql-hint.js @@ -1,281 +1,281 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../../mode/sql/sql")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../../mode/sql/sql"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var tables; - var defaultTable; - var keywords; - var CONS = { - QUERY_DIV: ";", - ALIAS_KEYWORD: "AS" - }; - var Pos = CodeMirror.Pos; - - function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" } - - function getKeywords(editor) { - var mode = editor.doc.modeOption; - if (mode === "sql") mode = "text/x-sql"; - return CodeMirror.resolveMode(mode).keywords; - } - - function getText(item) { - return typeof item == "string" ? item : item.text; - } - - function wrapTable(name, value) { - if (isArray(value)) value = {columns: value} - if (!value.text) value.text = name - return value - } - - function parseTables(input) { - var result = {} - if (isArray(input)) { - for (var i = input.length - 1; i >= 0; i--) { - var item = input[i] - result[getText(item).toUpperCase()] = wrapTable(getText(item), item) - } - } else if (input) { - for (var name in input) - result[name.toUpperCase()] = wrapTable(name, input[name]) - } - return result - } - - function getTable(name) { - return tables[name.toUpperCase()] - } - - function shallowClone(object) { - var result = {}; - for (var key in object) if (object.hasOwnProperty(key)) - result[key] = object[key]; - return result; - } - - function match(string, word) { - var len = string.length; - var sub = getText(word).substr(0, len); - return string.toUpperCase() === sub.toUpperCase(); - } - - function addMatches(result, search, wordlist, formatter) { - if (isArray(wordlist)) { - for (var i = 0; i < wordlist.length; i++) - if (match(search, wordlist[i])) result.push(formatter(wordlist[i])) - } else { - for (var word in wordlist) if (wordlist.hasOwnProperty(word)) { - var val = wordlist[word] - if (!val || val === true) - val = word - else - val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text - if (match(search, val)) result.push(formatter(val)) - } - } - } - - function cleanName(name) { - // Get rid name from backticks(`) and preceding dot(.) - if (name.charAt(0) == ".") { - name = name.substr(1); - } - return name.replace(/`/g, ""); - } - - function insertBackticks(name) { - var nameParts = getText(name).split("."); - for (var i = 0; i < nameParts.length; i++) - nameParts[i] = "`" + nameParts[i] + "`"; - var escaped = nameParts.join("."); - if (typeof name == "string") return escaped; - name = shallowClone(name); - name.text = escaped; - return name; - } - - function nameCompletion(cur, token, result, editor) { - // Try to complete table, column names and return start position of completion - var useBacktick = false; - var nameParts = []; - var start = token.start; - var cont = true; - while (cont) { - cont = (token.string.charAt(0) == "."); - useBacktick = useBacktick || (token.string.charAt(0) == "`"); - - start = token.start; - nameParts.unshift(cleanName(token.string)); - - token = editor.getTokenAt(Pos(cur.line, token.start)); - if (token.string == ".") { - cont = true; - token = editor.getTokenAt(Pos(cur.line, token.start)); - } - } - - // Try to complete table names - var string = nameParts.join("."); - addMatches(result, string, tables, function(w) { - return useBacktick ? insertBackticks(w) : w; - }); - - // Try to complete columns from defaultTable - addMatches(result, string, defaultTable, function(w) { - return useBacktick ? insertBackticks(w) : w; - }); - - // Try to complete columns - string = nameParts.pop(); - var table = nameParts.join("."); - - var alias = false; - var aliasTable = table; - // Check if table is available. If not, find table by Alias - if (!getTable(table)) { - var oldTable = table; - table = findTableByAlias(table, editor); - if (table !== oldTable) alias = true; - } - - var columns = getTable(table); - if (columns && columns.columns) - columns = columns.columns; - - if (columns) { - addMatches(result, string, columns, function(w) { - var tableInsert = table; - if (alias == true) tableInsert = aliasTable; - if (typeof w == "string") { - w = tableInsert + "." + w; - } else { - w = shallowClone(w); - w.text = tableInsert + "." + w.text; - } - return useBacktick ? insertBackticks(w) : w; - }); - } - - return start; - } - - function eachWord(lineText, f) { - if (!lineText) return; - var excepted = /[,;]/g; - var words = lineText.split(" "); - for (var i = 0; i < words.length; i++) { - f(words[i]?words[i].replace(excepted, '') : ''); - } - } - - function convertCurToNumber(cur) { - // max characters of a line is 999,999. - return cur.line + cur.ch / Math.pow(10, 6); - } - - function convertNumberToCur(num) { - return Pos(Math.floor(num), +num.toString().split('.').pop()); - } - - function findTableByAlias(alias, editor) { - var doc = editor.doc; - var fullQuery = doc.getValue(); - var aliasUpperCase = alias.toUpperCase(); - var previousWord = ""; - var table = ""; - var separator = []; - var validRange = { - start: Pos(0, 0), - end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length) - }; - - //add separator - var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV); - while(indexOfSeparator != -1) { - separator.push(doc.posFromIndex(indexOfSeparator)); - indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1); - } - separator.unshift(Pos(0, 0)); - separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length)); - - //find valid range - var prevItem = 0; - var current = convertCurToNumber(editor.getCursor()); - for (var i = 0; i < separator.length; i++) { - var _v = convertCurToNumber(separator[i]); - if (current > prevItem && current <= _v) { - validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) }; - break; - } - prevItem = _v; - } - - var query = doc.getRange(validRange.start, validRange.end, false); - - for (var i = 0; i < query.length; i++) { - var lineText = query[i]; - eachWord(lineText, function(word) { - var wordUpperCase = word.toUpperCase(); - if (wordUpperCase === aliasUpperCase && getTable(previousWord)) - table = previousWord; - if (wordUpperCase !== CONS.ALIAS_KEYWORD) - previousWord = word; - }); - if (table) break; - } - return table; - } - - CodeMirror.registerHelper("hint", "sql", function(editor, options) { - tables = parseTables(options && options.tables) - var defaultTableName = options && options.defaultTable; - var disableKeywords = options && options.disableKeywords; - defaultTable = defaultTableName && getTable(defaultTableName); - keywords = keywords || getKeywords(editor); - - if (defaultTableName && !defaultTable) - defaultTable = findTableByAlias(defaultTableName, editor); - - defaultTable = defaultTable || []; - - if (defaultTable.columns) - defaultTable = defaultTable.columns; - - var cur = editor.getCursor(); - var result = []; - var token = editor.getTokenAt(cur), start, end, search; - if (token.end > cur.ch) { - token.end = cur.ch; - token.string = token.string.slice(0, cur.ch - token.start); - } - - if (token.string.match(/^[.`\w@]\w*$/)) { - search = token.string; - start = token.start; - end = token.end; - } else { - start = end = cur.ch; - search = ""; - } - if (search.charAt(0) == "." || search.charAt(0) == "`") { - start = nameCompletion(cur, token, result, editor); - } else { - addMatches(result, search, tables, function(w) {return w;}); - addMatches(result, search, defaultTable, function(w) {return w;}); - if (!disableKeywords) - addMatches(result, search, keywords, function(w) {return w.toUpperCase();}); - } - - return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)}; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../mode/sql/sql")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../mode/sql/sql"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var tables; + var defaultTable; + var keywords; + var CONS = { + QUERY_DIV: ";", + ALIAS_KEYWORD: "AS" + }; + var Pos = CodeMirror.Pos; + + function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" } + + function getKeywords(editor) { + var mode = editor.doc.modeOption; + if (mode === "sql") mode = "text/x-sql"; + return CodeMirror.resolveMode(mode).keywords; + } + + function getText(item) { + return typeof item == "string" ? item : item.text; + } + + function wrapTable(name, value) { + if (isArray(value)) value = {columns: value} + if (!value.text) value.text = name + return value + } + + function parseTables(input) { + var result = {} + if (isArray(input)) { + for (var i = input.length - 1; i >= 0; i--) { + var item = input[i] + result[getText(item).toUpperCase()] = wrapTable(getText(item), item) + } + } else if (input) { + for (var name in input) + result[name.toUpperCase()] = wrapTable(name, input[name]) + } + return result + } + + function getTable(name) { + return tables[name.toUpperCase()] + } + + function shallowClone(object) { + var result = {}; + for (var key in object) if (object.hasOwnProperty(key)) + result[key] = object[key]; + return result; + } + + function match(string, word) { + var len = string.length; + var sub = getText(word).substr(0, len); + return string.toUpperCase() === sub.toUpperCase(); + } + + function addMatches(result, search, wordlist, formatter) { + if (isArray(wordlist)) { + for (var i = 0; i < wordlist.length; i++) + if (match(search, wordlist[i])) result.push(formatter(wordlist[i])) + } else { + for (var word in wordlist) if (wordlist.hasOwnProperty(word)) { + var val = wordlist[word] + if (!val || val === true) + val = word + else + val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text + if (match(search, val)) result.push(formatter(val)) + } + } + } + + function cleanName(name) { + // Get rid name from backticks(`) and preceding dot(.) + if (name.charAt(0) == ".") { + name = name.substr(1); + } + return name.replace(/`/g, ""); + } + + function insertBackticks(name) { + var nameParts = getText(name).split("."); + for (var i = 0; i < nameParts.length; i++) + nameParts[i] = "`" + nameParts[i] + "`"; + var escaped = nameParts.join("."); + if (typeof name == "string") return escaped; + name = shallowClone(name); + name.text = escaped; + return name; + } + + function nameCompletion(cur, token, result, editor) { + // Try to complete table, column names and return start position of completion + var useBacktick = false; + var nameParts = []; + var start = token.start; + var cont = true; + while (cont) { + cont = (token.string.charAt(0) == "."); + useBacktick = useBacktick || (token.string.charAt(0) == "`"); + + start = token.start; + nameParts.unshift(cleanName(token.string)); + + token = editor.getTokenAt(Pos(cur.line, token.start)); + if (token.string == ".") { + cont = true; + token = editor.getTokenAt(Pos(cur.line, token.start)); + } + } + + // Try to complete table names + var string = nameParts.join("."); + addMatches(result, string, tables, function(w) { + return useBacktick ? insertBackticks(w) : w; + }); + + // Try to complete columns from defaultTable + addMatches(result, string, defaultTable, function(w) { + return useBacktick ? insertBackticks(w) : w; + }); + + // Try to complete columns + string = nameParts.pop(); + var table = nameParts.join("."); + + var alias = false; + var aliasTable = table; + // Check if table is available. If not, find table by Alias + if (!getTable(table)) { + var oldTable = table; + table = findTableByAlias(table, editor); + if (table !== oldTable) alias = true; + } + + var columns = getTable(table); + if (columns && columns.columns) + columns = columns.columns; + + if (columns) { + addMatches(result, string, columns, function(w) { + var tableInsert = table; + if (alias == true) tableInsert = aliasTable; + if (typeof w == "string") { + w = tableInsert + "." + w; + } else { + w = shallowClone(w); + w.text = tableInsert + "." + w.text; + } + return useBacktick ? insertBackticks(w) : w; + }); + } + + return start; + } + + function eachWord(lineText, f) { + if (!lineText) return; + var excepted = /[,;]/g; + var words = lineText.split(" "); + for (var i = 0; i < words.length; i++) { + f(words[i]?words[i].replace(excepted, '') : ''); + } + } + + function convertCurToNumber(cur) { + // max characters of a line is 999,999. + return cur.line + cur.ch / Math.pow(10, 6); + } + + function convertNumberToCur(num) { + return Pos(Math.floor(num), +num.toString().split('.').pop()); + } + + function findTableByAlias(alias, editor) { + var doc = editor.doc; + var fullQuery = doc.getValue(); + var aliasUpperCase = alias.toUpperCase(); + var previousWord = ""; + var table = ""; + var separator = []; + var validRange = { + start: Pos(0, 0), + end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length) + }; + + //add separator + var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV); + while(indexOfSeparator != -1) { + separator.push(doc.posFromIndex(indexOfSeparator)); + indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1); + } + separator.unshift(Pos(0, 0)); + separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length)); + + //find valid range + var prevItem = 0; + var current = convertCurToNumber(editor.getCursor()); + for (var i = 0; i < separator.length; i++) { + var _v = convertCurToNumber(separator[i]); + if (current > prevItem && current <= _v) { + validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) }; + break; + } + prevItem = _v; + } + + var query = doc.getRange(validRange.start, validRange.end, false); + + for (var i = 0; i < query.length; i++) { + var lineText = query[i]; + eachWord(lineText, function(word) { + var wordUpperCase = word.toUpperCase(); + if (wordUpperCase === aliasUpperCase && getTable(previousWord)) + table = previousWord; + if (wordUpperCase !== CONS.ALIAS_KEYWORD) + previousWord = word; + }); + if (table) break; + } + return table; + } + + CodeMirror.registerHelper("hint", "sql", function(editor, options) { + tables = parseTables(options && options.tables) + var defaultTableName = options && options.defaultTable; + var disableKeywords = options && options.disableKeywords; + defaultTable = defaultTableName && getTable(defaultTableName); + keywords = keywords || getKeywords(editor); + + if (defaultTableName && !defaultTable) + defaultTable = findTableByAlias(defaultTableName, editor); + + defaultTable = defaultTable || []; + + if (defaultTable.columns) + defaultTable = defaultTable.columns; + + var cur = editor.getCursor(); + var result = []; + var token = editor.getTokenAt(cur), start, end, search; + if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + + if (token.string.match(/^[.`\w@]\w*$/)) { + search = token.string; + start = token.start; + end = token.end; + } else { + start = end = cur.ch; + search = ""; + } + if (search.charAt(0) == "." || search.charAt(0) == "`") { + start = nameCompletion(cur, token, result, editor); + } else { + addMatches(result, search, tables, function(w) {return w;}); + addMatches(result, search, defaultTable, function(w) {return w;}); + if (!disableKeywords) + addMatches(result, search, keywords, function(w) {return w.toUpperCase();}); + } + + return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)}; + }); +}); diff --git a/shared/codemirror/addon/hint/xml-hint.js b/shared/codemirror/addon/hint/xml-hint.js index 9b9baa0..e1af5a6 100644 --- a/shared/codemirror/addon/hint/xml-hint.js +++ b/shared/codemirror/addon/hint/xml-hint.js @@ -1,110 +1,110 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var Pos = CodeMirror.Pos; - - function getHints(cm, options) { - var tags = options && options.schemaInfo; - var quote = (options && options.quoteChar) || '"'; - if (!tags) return; - var cur = cm.getCursor(), token = cm.getTokenAt(cur); - if (token.end > cur.ch) { - token.end = cur.ch; - token.string = token.string.slice(0, cur.ch - token.start); - } - var inner = CodeMirror.innerMode(cm.getMode(), token.state); - if (inner.mode.name != "xml") return; - var result = [], replaceToken = false, prefix; - var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string); - var tagName = tag && /^\w/.test(token.string), tagStart; - - if (tagName) { - var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start); - var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null; - if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1); - } else if (tag && token.string == "<") { - tagType = "open"; - } else if (tag && token.string == ""); - } else { - // Attribute completion - var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; - var globalAttrs = tags["!attrs"]; - if (!attrs && !globalAttrs) return; - if (!attrs) { - attrs = globalAttrs; - } else if (globalAttrs) { // Combine tag-local and global attributes - var set = {}; - for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm]; - for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm]; - attrs = set; - } - if (token.type == "string" || token.string == "=") { // A value - var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), - Pos(cur.line, token.type == "string" ? token.start : token.end)); - var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; - if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; - if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget - if (token.type == "string") { - prefix = token.string; - var n = 0; - if (/['"]/.test(token.string.charAt(0))) { - quote = token.string.charAt(0); - prefix = token.string.slice(1); - n++; - } - var len = token.string.length; - if (/['"]/.test(token.string.charAt(len - 1))) { - quote = token.string.charAt(len - 1); - prefix = token.string.substr(n, len - 2); - } - replaceToken = true; - } - for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0) - result.push(quote + atValues[i] + quote); - } else { // An attribute name - if (token.type == "attribute") { - prefix = token.string; - replaceToken = true; - } - for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0)) - result.push(attr); - } - } - return { - list: result, - from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur, - to: replaceToken ? Pos(cur.line, token.end) : cur - }; - } - - CodeMirror.registerHelper("hint", "xml", getHints); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var Pos = CodeMirror.Pos; + + function getHints(cm, options) { + var tags = options && options.schemaInfo; + var quote = (options && options.quoteChar) || '"'; + if (!tags) return; + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + var inner = CodeMirror.innerMode(cm.getMode(), token.state); + if (inner.mode.name != "xml") return; + var result = [], replaceToken = false, prefix; + var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string); + var tagName = tag && /^\w/.test(token.string), tagStart; + + if (tagName) { + var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start); + var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null; + if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1); + } else if (tag && token.string == "<") { + tagType = "open"; + } else if (tag && token.string == ""); + } else { + // Attribute completion + var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; + var globalAttrs = tags["!attrs"]; + if (!attrs && !globalAttrs) return; + if (!attrs) { + attrs = globalAttrs; + } else if (globalAttrs) { // Combine tag-local and global attributes + var set = {}; + for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm]; + for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm]; + attrs = set; + } + if (token.type == "string" || token.string == "=") { // A value + var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), + Pos(cur.line, token.type == "string" ? token.start : token.end)); + var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; + if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; + if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget + if (token.type == "string") { + prefix = token.string; + var n = 0; + if (/['"]/.test(token.string.charAt(0))) { + quote = token.string.charAt(0); + prefix = token.string.slice(1); + n++; + } + var len = token.string.length; + if (/['"]/.test(token.string.charAt(len - 1))) { + quote = token.string.charAt(len - 1); + prefix = token.string.substr(n, len - 2); + } + replaceToken = true; + } + for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0) + result.push(quote + atValues[i] + quote); + } else { // An attribute name + if (token.type == "attribute") { + prefix = token.string; + replaceToken = true; + } + for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0)) + result.push(attr); + } + } + return { + list: result, + from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur, + to: replaceToken ? Pos(cur.line, token.end) : cur + }; + } + + CodeMirror.registerHelper("hint", "xml", getHints); +}); diff --git a/shared/codemirror/addon/lint/coffeescript-lint.js b/shared/codemirror/addon/lint/coffeescript-lint.js index 7e39428..5cf193e 100644 --- a/shared/codemirror/addon/lint/coffeescript-lint.js +++ b/shared/codemirror/addon/lint/coffeescript-lint.js @@ -1,41 +1,41 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js - -// declare global: coffeelint - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("lint", "coffeescript", function(text) { - var found = []; - var parseError = function(err) { - var loc = err.lineNumber; - found.push({from: CodeMirror.Pos(loc-1, 0), - to: CodeMirror.Pos(loc, 0), - severity: err.level, - message: err.message}); - }; - try { - var res = coffeelint.lint(text); - for(var i = 0; i < res.length; i++) { - parseError(res[i]); - } - } catch(e) { - found.push({from: CodeMirror.Pos(e.location.first_line, 0), - to: CodeMirror.Pos(e.location.last_line, e.location.last_column), - severity: 'error', - message: e.message}); - } - return found; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js + +// declare global: coffeelint + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("lint", "coffeescript", function(text) { + var found = []; + var parseError = function(err) { + var loc = err.lineNumber; + found.push({from: CodeMirror.Pos(loc-1, 0), + to: CodeMirror.Pos(loc, 0), + severity: err.level, + message: err.message}); + }; + try { + var res = coffeelint.lint(text); + for(var i = 0; i < res.length; i++) { + parseError(res[i]); + } + } catch(e) { + found.push({from: CodeMirror.Pos(e.location.first_line, 0), + to: CodeMirror.Pos(e.location.last_line, e.location.last_column), + severity: 'error', + message: e.message}); + } + return found; +}); + +}); diff --git a/shared/codemirror/addon/lint/css-lint.js b/shared/codemirror/addon/lint/css-lint.js index 1f61b47..e361dde 100644 --- a/shared/codemirror/addon/lint/css-lint.js +++ b/shared/codemirror/addon/lint/css-lint.js @@ -1,35 +1,35 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Depends on csslint.js from https://github.com/stubbornella/csslint - -// declare global: CSSLint - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("lint", "css", function(text) { - var found = []; - if (!window.CSSLint) return found; - var results = CSSLint.verify(text), messages = results.messages, message = null; - for ( var i = 0; i < messages.length; i++) { - message = messages[i]; - var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; - found.push({ - from: CodeMirror.Pos(startLine, startCol), - to: CodeMirror.Pos(endLine, endCol), - message: message.message, - severity : message.type - }); - } - return found; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Depends on csslint.js from https://github.com/stubbornella/csslint + +// declare global: CSSLint + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("lint", "css", function(text) { + var found = []; + if (!window.CSSLint) return found; + var results = CSSLint.verify(text), messages = results.messages, message = null; + for ( var i = 0; i < messages.length; i++) { + message = messages[i]; + var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; + found.push({ + from: CodeMirror.Pos(startLine, startCol), + to: CodeMirror.Pos(endLine, endCol), + message: message.message, + severity : message.type + }); + } + return found; +}); + +}); diff --git a/shared/codemirror/addon/lint/html-lint.js b/shared/codemirror/addon/lint/html-lint.js index 1e84170..1d3075d 100644 --- a/shared/codemirror/addon/lint/html-lint.js +++ b/shared/codemirror/addon/lint/html-lint.js @@ -1,46 +1,46 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js - -// declare global: HTMLHint - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("htmlhint")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "htmlhint"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var defaultRules = { - "tagname-lowercase": true, - "attr-lowercase": true, - "attr-value-double-quotes": true, - "doctype-first": false, - "tag-pair": true, - "spec-char-escape": true, - "id-unique": true, - "src-not-empty": true, - "attr-no-duplication": true - }; - - CodeMirror.registerHelper("lint", "html", function(text, options) { - var found = []; - if (!window.HTMLHint) return found; - var messages = HTMLHint.verify(text, options && options.rules || defaultRules); - for (var i = 0; i < messages.length; i++) { - var message = messages[i]; - var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col; - found.push({ - from: CodeMirror.Pos(startLine, startCol), - to: CodeMirror.Pos(endLine, endCol), - message: message.message, - severity : message.type - }); - } - return found; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js + +// declare global: HTMLHint + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("htmlhint")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "htmlhint"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var defaultRules = { + "tagname-lowercase": true, + "attr-lowercase": true, + "attr-value-double-quotes": true, + "doctype-first": false, + "tag-pair": true, + "spec-char-escape": true, + "id-unique": true, + "src-not-empty": true, + "attr-no-duplication": true + }; + + CodeMirror.registerHelper("lint", "html", function(text, options) { + var found = []; + if (!window.HTMLHint) return found; + var messages = HTMLHint.verify(text, options && options.rules || defaultRules); + for (var i = 0; i < messages.length; i++) { + var message = messages[i]; + var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col; + found.push({ + from: CodeMirror.Pos(startLine, startCol), + to: CodeMirror.Pos(endLine, endCol), + message: message.message, + severity : message.type + }); + } + return found; + }); +}); diff --git a/shared/codemirror/addon/lint/javascript-lint.js b/shared/codemirror/addon/lint/javascript-lint.js index d4f2ae9..d4d3a83 100644 --- a/shared/codemirror/addon/lint/javascript-lint.js +++ b/shared/codemirror/addon/lint/javascript-lint.js @@ -1,136 +1,136 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - // declare global: JSHINT - - var bogus = [ "Dangerous comment" ]; - - var warnings = [ [ "Expected '{'", - "Statement body should be inside '{ }' braces." ] ]; - - var errors = [ "Missing semicolon", "Extra comma", "Missing property name", - "Unmatched ", " and instead saw", " is not defined", - "Unclosed string", "Stopping, unable to continue" ]; - - function validator(text, options) { - if (!window.JSHINT) return []; - JSHINT(text, options, options.globals); - var errors = JSHINT.data().errors, result = []; - if (errors) parseErrors(errors, result); - return result; - } - - CodeMirror.registerHelper("lint", "javascript", validator); - - function cleanup(error) { - // All problems are warnings by default - fixWith(error, warnings, "warning", true); - fixWith(error, errors, "error"); - - return isBogus(error) ? null : error; - } - - function fixWith(error, fixes, severity, force) { - var description, fix, find, replace, found; - - description = error.description; - - for ( var i = 0; i < fixes.length; i++) { - fix = fixes[i]; - find = (typeof fix === "string" ? fix : fix[0]); - replace = (typeof fix === "string" ? null : fix[1]); - found = description.indexOf(find) !== -1; - - if (force || found) { - error.severity = severity; - } - if (found && replace) { - error.description = replace; - } - } - } - - function isBogus(error) { - var description = error.description; - for ( var i = 0; i < bogus.length; i++) { - if (description.indexOf(bogus[i]) !== -1) { - return true; - } - } - return false; - } - - function parseErrors(errors, output) { - for ( var i = 0; i < errors.length; i++) { - var error = errors[i]; - if (error) { - var linetabpositions, index; - - linetabpositions = []; - - // This next block is to fix a problem in jshint. Jshint - // replaces - // all tabs with spaces then performs some checks. The error - // positions (character/space) are then reported incorrectly, - // not taking the replacement step into account. Here we look - // at the evidence line and try to adjust the character position - // to the correct value. - if (error.evidence) { - // Tab positions are computed once per line and cached - var tabpositions = linetabpositions[error.line]; - if (!tabpositions) { - var evidence = error.evidence; - tabpositions = []; - // ugggh phantomjs does not like this - // forEachChar(evidence, function(item, index) { - Array.prototype.forEach.call(evidence, function(item, - index) { - if (item === '\t') { - // First col is 1 (not 0) to match error - // positions - tabpositions.push(index + 1); - } - }); - linetabpositions[error.line] = tabpositions; - } - if (tabpositions.length > 0) { - var pos = error.character; - tabpositions.forEach(function(tabposition) { - if (pos > tabposition) pos -= 1; - }); - error.character = pos; - } - } - - var start = error.character - 1, end = start + 1; - if (error.evidence) { - index = error.evidence.substring(start).search(/.\b/); - if (index > -1) { - end += index; - } - } - - // Convert to format expected by validation service - error.description = error.reason;// + "(jshint)"; - error.start = error.character; - error.end = end; - error = cleanup(error); - - if (error) - output.push({message: error.description, - severity: error.severity, - from: CodeMirror.Pos(error.line - 1, start), - to: CodeMirror.Pos(error.line - 1, end)}); - } - } - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + // declare global: JSHINT + + var bogus = [ "Dangerous comment" ]; + + var warnings = [ [ "Expected '{'", + "Statement body should be inside '{ }' braces." ] ]; + + var errors = [ "Missing semicolon", "Extra comma", "Missing property name", + "Unmatched ", " and instead saw", " is not defined", + "Unclosed string", "Stopping, unable to continue" ]; + + function validator(text, options) { + if (!window.JSHINT) return []; + JSHINT(text, options, options.globals); + var errors = JSHINT.data().errors, result = []; + if (errors) parseErrors(errors, result); + return result; + } + + CodeMirror.registerHelper("lint", "javascript", validator); + + function cleanup(error) { + // All problems are warnings by default + fixWith(error, warnings, "warning", true); + fixWith(error, errors, "error"); + + return isBogus(error) ? null : error; + } + + function fixWith(error, fixes, severity, force) { + var description, fix, find, replace, found; + + description = error.description; + + for ( var i = 0; i < fixes.length; i++) { + fix = fixes[i]; + find = (typeof fix === "string" ? fix : fix[0]); + replace = (typeof fix === "string" ? null : fix[1]); + found = description.indexOf(find) !== -1; + + if (force || found) { + error.severity = severity; + } + if (found && replace) { + error.description = replace; + } + } + } + + function isBogus(error) { + var description = error.description; + for ( var i = 0; i < bogus.length; i++) { + if (description.indexOf(bogus[i]) !== -1) { + return true; + } + } + return false; + } + + function parseErrors(errors, output) { + for ( var i = 0; i < errors.length; i++) { + var error = errors[i]; + if (error) { + var linetabpositions, index; + + linetabpositions = []; + + // This next block is to fix a problem in jshint. Jshint + // replaces + // all tabs with spaces then performs some checks. The error + // positions (character/space) are then reported incorrectly, + // not taking the replacement step into account. Here we look + // at the evidence line and try to adjust the character position + // to the correct value. + if (error.evidence) { + // Tab positions are computed once per line and cached + var tabpositions = linetabpositions[error.line]; + if (!tabpositions) { + var evidence = error.evidence; + tabpositions = []; + // ugggh phantomjs does not like this + // forEachChar(evidence, function(item, index) { + Array.prototype.forEach.call(evidence, function(item, + index) { + if (item === '\t') { + // First col is 1 (not 0) to match error + // positions + tabpositions.push(index + 1); + } + }); + linetabpositions[error.line] = tabpositions; + } + if (tabpositions.length > 0) { + var pos = error.character; + tabpositions.forEach(function(tabposition) { + if (pos > tabposition) pos -= 1; + }); + error.character = pos; + } + } + + var start = error.character - 1, end = start + 1; + if (error.evidence) { + index = error.evidence.substring(start).search(/.\b/); + if (index > -1) { + end += index; + } + } + + // Convert to format expected by validation service + error.description = error.reason;// + "(jshint)"; + error.start = error.character; + error.end = end; + error = cleanup(error); + + if (error) + output.push({message: error.description, + severity: error.severity, + from: CodeMirror.Pos(error.line - 1, start), + to: CodeMirror.Pos(error.line - 1, end)}); + } + } + } +}); diff --git a/shared/codemirror/addon/lint/json-lint.js b/shared/codemirror/addon/lint/json-lint.js index 9dbb616..c748957 100644 --- a/shared/codemirror/addon/lint/json-lint.js +++ b/shared/codemirror/addon/lint/json-lint.js @@ -1,31 +1,31 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Depends on jsonlint.js from https://github.com/zaach/jsonlint - -// declare global: jsonlint - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("lint", "json", function(text) { - var found = []; - jsonlint.parseError = function(str, hash) { - var loc = hash.loc; - found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), - to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), - message: str}); - }; - try { jsonlint.parse(text); } - catch(e) {} - return found; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Depends on jsonlint.js from https://github.com/zaach/jsonlint + +// declare global: jsonlint + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("lint", "json", function(text) { + var found = []; + jsonlint.parseError = function(str, hash) { + var loc = hash.loc; + found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), + to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), + message: str}); + }; + try { jsonlint.parse(text); } + catch(e) {} + return found; +}); + +}); diff --git a/shared/codemirror/addon/lint/lint.css b/shared/codemirror/addon/lint/lint.css index 414a9a0..8e7282d 100644 --- a/shared/codemirror/addon/lint/lint.css +++ b/shared/codemirror/addon/lint/lint.css @@ -1,73 +1,73 @@ -/* The lint marker gutter */ -.CodeMirror-lint-markers { - width: 16px; -} - -.CodeMirror-lint-tooltip { - background-color: infobackground; - border: 1px solid black; - border-radius: 4px 4px 4px 4px; - color: infotext; - font-family: monospace; - font-size: 10pt; - overflow: hidden; - padding: 2px 5px; - position: fixed; - white-space: pre; - white-space: pre-wrap; - z-index: 100; - max-width: 600px; - opacity: 0; - transition: opacity .4s; - -moz-transition: opacity .4s; - -webkit-transition: opacity .4s; - -o-transition: opacity .4s; - -ms-transition: opacity .4s; -} - -.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { - background-position: left bottom; - background-repeat: repeat-x; -} - -.CodeMirror-lint-mark-error { - background-image: - url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") - ; -} - -.CodeMirror-lint-mark-warning { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { - background-position: center center; - background-repeat: no-repeat; - cursor: pointer; - display: inline-block; - height: 16px; - width: 16px; - vertical-align: middle; - position: relative; -} - -.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { - padding-left: 18px; - background-position: top left; - background-repeat: no-repeat; -} - -.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-multiple { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); - background-repeat: no-repeat; - background-position: right bottom; - width: 100%; height: 100%; -} +/* The lint marker gutter */ +.CodeMirror-lint-markers { + width: 16px; +} + +.CodeMirror-lint-tooltip { + background-color: infobackground; + border: 1px solid black; + border-radius: 4px 4px 4px 4px; + color: infotext; + font-family: monospace; + font-size: 10pt; + overflow: hidden; + padding: 2px 5px; + position: fixed; + white-space: pre; + white-space: pre-wrap; + z-index: 100; + max-width: 600px; + opacity: 0; + transition: opacity .4s; + -moz-transition: opacity .4s; + -webkit-transition: opacity .4s; + -o-transition: opacity .4s; + -ms-transition: opacity .4s; +} + +.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { + background-position: left bottom; + background-repeat: repeat-x; +} + +.CodeMirror-lint-mark-error { + background-image: + url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") + ; +} + +.CodeMirror-lint-mark-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; + display: inline-block; + height: 16px; + width: 16px; + vertical-align: middle; + position: relative; +} + +.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { + padding-left: 18px; + background-position: top left; + background-repeat: no-repeat; +} + +.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-multiple { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); + background-repeat: no-repeat; + background-position: right bottom; + width: 100%; height: 100%; +} diff --git a/shared/codemirror/addon/lint/lint.js b/shared/codemirror/addon/lint/lint.js index e3a4527..c7c9fba 100644 --- a/shared/codemirror/addon/lint/lint.js +++ b/shared/codemirror/addon/lint/lint.js @@ -1,239 +1,239 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - var GUTTER_ID = "CodeMirror-lint-markers"; - - function showTooltip(e, content) { - var tt = document.createElement("div"); - tt.className = "CodeMirror-lint-tooltip"; - tt.appendChild(content.cloneNode(true)); - document.body.appendChild(tt); - - function position(e) { - if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); - tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px"; - tt.style.left = (e.clientX + 5) + "px"; - } - CodeMirror.on(document, "mousemove", position); - position(e); - if (tt.style.opacity != null) tt.style.opacity = 1; - return tt; - } - function rm(elt) { - if (elt.parentNode) elt.parentNode.removeChild(elt); - } - function hideTooltip(tt) { - if (!tt.parentNode) return; - if (tt.style.opacity == null) rm(tt); - tt.style.opacity = 0; - setTimeout(function() { rm(tt); }, 600); - } - - function showTooltipFor(e, content, node) { - var tooltip = showTooltip(e, content); - function hide() { - CodeMirror.off(node, "mouseout", hide); - if (tooltip) { hideTooltip(tooltip); tooltip = null; } - } - var poll = setInterval(function() { - if (tooltip) for (var n = node;; n = n.parentNode) { - if (n && n.nodeType == 11) n = n.host; - if (n == document.body) return; - if (!n) { hide(); break; } - } - if (!tooltip) return clearInterval(poll); - }, 400); - CodeMirror.on(node, "mouseout", hide); - } - - function LintState(cm, options, hasGutter) { - this.marked = []; - this.options = options; - this.timeout = null; - this.hasGutter = hasGutter; - this.onMouseOver = function(e) { onMouseOver(cm, e); }; - this.waitingFor = 0 - } - - function parseOptions(_cm, options) { - if (options instanceof Function) return {getAnnotations: options}; - if (!options || options === true) options = {}; - return options; - } - - function clearMarks(cm) { - var state = cm.state.lint; - if (state.hasGutter) cm.clearGutter(GUTTER_ID); - for (var i = 0; i < state.marked.length; ++i) - state.marked[i].clear(); - state.marked.length = 0; - } - - function makeMarker(labels, severity, multiple, tooltips) { - var marker = document.createElement("div"), inner = marker; - marker.className = "CodeMirror-lint-marker-" + severity; - if (multiple) { - inner = marker.appendChild(document.createElement("div")); - inner.className = "CodeMirror-lint-marker-multiple"; - } - - if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { - showTooltipFor(e, labels, inner); - }); - - return marker; - } - - function getMaxSeverity(a, b) { - if (a == "error") return a; - else return b; - } - - function groupByLine(annotations) { - var lines = []; - for (var i = 0; i < annotations.length; ++i) { - var ann = annotations[i], line = ann.from.line; - (lines[line] || (lines[line] = [])).push(ann); - } - return lines; - } - - function annotationTooltip(ann) { - var severity = ann.severity; - if (!severity) severity = "error"; - var tip = document.createElement("div"); - tip.className = "CodeMirror-lint-message-" + severity; - tip.appendChild(document.createTextNode(ann.message)); - return tip; - } - - function lintAsync(cm, getAnnotations, passOptions) { - var state = cm.state.lint - var id = ++state.waitingFor - function abort() { - id = -1 - cm.off("change", abort) - } - cm.on("change", abort) - getAnnotations(cm.getValue(), function(annotations, arg2) { - cm.off("change", abort) - if (state.waitingFor != id) return - if (arg2 && annotations instanceof CodeMirror) annotations = arg2 - updateLinting(cm, annotations) - }, passOptions, cm); - } - - function startLinting(cm) { - var state = cm.state.lint, options = state.options; - var passOptions = options.options || options; // Support deprecated passing of `options` property in options - var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint"); - if (!getAnnotations) return; - if (options.async || getAnnotations.async) { - lintAsync(cm, getAnnotations, passOptions) - } else { - updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm)); - } - } - - function updateLinting(cm, annotationsNotSorted) { - clearMarks(cm); - var state = cm.state.lint, options = state.options; - - var annotations = groupByLine(annotationsNotSorted); - - for (var line = 0; line < annotations.length; ++line) { - var anns = annotations[line]; - if (!anns) continue; - - var maxSeverity = null; - var tipLabel = state.hasGutter && document.createDocumentFragment(); - - for (var i = 0; i < anns.length; ++i) { - var ann = anns[i]; - var severity = ann.severity; - if (!severity) severity = "error"; - maxSeverity = getMaxSeverity(maxSeverity, severity); - - if (options.formatAnnotation) ann = options.formatAnnotation(ann); - if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); - - if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { - className: "CodeMirror-lint-mark-" + severity, - __annotation: ann - })); - } - - if (state.hasGutter) - cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1, - state.options.tooltips)); - } - if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm); - } - - function onChange(cm) { - var state = cm.state.lint; - if (!state) return; - clearTimeout(state.timeout); - state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); - } - - function popupTooltips(annotations, e) { - var target = e.target || e.srcElement; - var tooltip = document.createDocumentFragment(); - for (var i = 0; i < annotations.length; i++) { - var ann = annotations[i]; - tooltip.appendChild(annotationTooltip(ann)); - } - showTooltipFor(e, tooltip, target); - } - - function onMouseOver(cm, e) { - var target = e.target || e.srcElement; - if (!/\bCodeMirror-lint-mark-/.test(target.className)) return; - var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2; - var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client")); - - var annotations = []; - for (var i = 0; i < spans.length; ++i) { - var ann = spans[i].__annotation; - if (ann) annotations.push(ann); - } - if (annotations.length) popupTooltips(annotations, e); - } - - CodeMirror.defineOption("lint", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - clearMarks(cm); - if (cm.state.lint.options.lintOnChange !== false) - cm.off("change", onChange); - CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); - clearTimeout(cm.state.lint.timeout); - delete cm.state.lint; - } - - if (val) { - var gutters = cm.getOption("gutters"), hasLintGutter = false; - for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; - var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter); - if (state.options.lintOnChange !== false) - cm.on("change", onChange); - if (state.options.tooltips != false) - CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); - - startLinting(cm); - } - }); - - CodeMirror.defineExtension("performLint", function() { - if (this.state.lint) startLinting(this); - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var GUTTER_ID = "CodeMirror-lint-markers"; + + function showTooltip(e, content) { + var tt = document.createElement("div"); + tt.className = "CodeMirror-lint-tooltip"; + tt.appendChild(content.cloneNode(true)); + document.body.appendChild(tt); + + function position(e) { + if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); + tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px"; + tt.style.left = (e.clientX + 5) + "px"; + } + CodeMirror.on(document, "mousemove", position); + position(e); + if (tt.style.opacity != null) tt.style.opacity = 1; + return tt; + } + function rm(elt) { + if (elt.parentNode) elt.parentNode.removeChild(elt); + } + function hideTooltip(tt) { + if (!tt.parentNode) return; + if (tt.style.opacity == null) rm(tt); + tt.style.opacity = 0; + setTimeout(function() { rm(tt); }, 600); + } + + function showTooltipFor(e, content, node) { + var tooltip = showTooltip(e, content); + function hide() { + CodeMirror.off(node, "mouseout", hide); + if (tooltip) { hideTooltip(tooltip); tooltip = null; } + } + var poll = setInterval(function() { + if (tooltip) for (var n = node;; n = n.parentNode) { + if (n && n.nodeType == 11) n = n.host; + if (n == document.body) return; + if (!n) { hide(); break; } + } + if (!tooltip) return clearInterval(poll); + }, 400); + CodeMirror.on(node, "mouseout", hide); + } + + function LintState(cm, options, hasGutter) { + this.marked = []; + this.options = options; + this.timeout = null; + this.hasGutter = hasGutter; + this.onMouseOver = function(e) { onMouseOver(cm, e); }; + this.waitingFor = 0 + } + + function parseOptions(_cm, options) { + if (options instanceof Function) return {getAnnotations: options}; + if (!options || options === true) options = {}; + return options; + } + + function clearMarks(cm) { + var state = cm.state.lint; + if (state.hasGutter) cm.clearGutter(GUTTER_ID); + for (var i = 0; i < state.marked.length; ++i) + state.marked[i].clear(); + state.marked.length = 0; + } + + function makeMarker(labels, severity, multiple, tooltips) { + var marker = document.createElement("div"), inner = marker; + marker.className = "CodeMirror-lint-marker-" + severity; + if (multiple) { + inner = marker.appendChild(document.createElement("div")); + inner.className = "CodeMirror-lint-marker-multiple"; + } + + if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { + showTooltipFor(e, labels, inner); + }); + + return marker; + } + + function getMaxSeverity(a, b) { + if (a == "error") return a; + else return b; + } + + function groupByLine(annotations) { + var lines = []; + for (var i = 0; i < annotations.length; ++i) { + var ann = annotations[i], line = ann.from.line; + (lines[line] || (lines[line] = [])).push(ann); + } + return lines; + } + + function annotationTooltip(ann) { + var severity = ann.severity; + if (!severity) severity = "error"; + var tip = document.createElement("div"); + tip.className = "CodeMirror-lint-message-" + severity; + tip.appendChild(document.createTextNode(ann.message)); + return tip; + } + + function lintAsync(cm, getAnnotations, passOptions) { + var state = cm.state.lint + var id = ++state.waitingFor + function abort() { + id = -1 + cm.off("change", abort) + } + cm.on("change", abort) + getAnnotations(cm.getValue(), function(annotations, arg2) { + cm.off("change", abort) + if (state.waitingFor != id) return + if (arg2 && annotations instanceof CodeMirror) annotations = arg2 + updateLinting(cm, annotations) + }, passOptions, cm); + } + + function startLinting(cm) { + var state = cm.state.lint, options = state.options; + var passOptions = options.options || options; // Support deprecated passing of `options` property in options + var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint"); + if (!getAnnotations) return; + if (options.async || getAnnotations.async) { + lintAsync(cm, getAnnotations, passOptions) + } else { + updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm)); + } + } + + function updateLinting(cm, annotationsNotSorted) { + clearMarks(cm); + var state = cm.state.lint, options = state.options; + + var annotations = groupByLine(annotationsNotSorted); + + for (var line = 0; line < annotations.length; ++line) { + var anns = annotations[line]; + if (!anns) continue; + + var maxSeverity = null; + var tipLabel = state.hasGutter && document.createDocumentFragment(); + + for (var i = 0; i < anns.length; ++i) { + var ann = anns[i]; + var severity = ann.severity; + if (!severity) severity = "error"; + maxSeverity = getMaxSeverity(maxSeverity, severity); + + if (options.formatAnnotation) ann = options.formatAnnotation(ann); + if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); + + if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { + className: "CodeMirror-lint-mark-" + severity, + __annotation: ann + })); + } + + if (state.hasGutter) + cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1, + state.options.tooltips)); + } + if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm); + } + + function onChange(cm) { + var state = cm.state.lint; + if (!state) return; + clearTimeout(state.timeout); + state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); + } + + function popupTooltips(annotations, e) { + var target = e.target || e.srcElement; + var tooltip = document.createDocumentFragment(); + for (var i = 0; i < annotations.length; i++) { + var ann = annotations[i]; + tooltip.appendChild(annotationTooltip(ann)); + } + showTooltipFor(e, tooltip, target); + } + + function onMouseOver(cm, e) { + var target = e.target || e.srcElement; + if (!/\bCodeMirror-lint-mark-/.test(target.className)) return; + var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2; + var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client")); + + var annotations = []; + for (var i = 0; i < spans.length; ++i) { + var ann = spans[i].__annotation; + if (ann) annotations.push(ann); + } + if (annotations.length) popupTooltips(annotations, e); + } + + CodeMirror.defineOption("lint", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + clearMarks(cm); + if (cm.state.lint.options.lintOnChange !== false) + cm.off("change", onChange); + CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); + clearTimeout(cm.state.lint.timeout); + delete cm.state.lint; + } + + if (val) { + var gutters = cm.getOption("gutters"), hasLintGutter = false; + for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; + var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter); + if (state.options.lintOnChange !== false) + cm.on("change", onChange); + if (state.options.tooltips != false) + CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); + + startLinting(cm); + } + }); + + CodeMirror.defineExtension("performLint", function() { + if (this.state.lint) startLinting(this); + }); +}); diff --git a/shared/codemirror/addon/lint/yaml-lint.js b/shared/codemirror/addon/lint/yaml-lint.js index 3f77e52..ec431da 100644 --- a/shared/codemirror/addon/lint/yaml-lint.js +++ b/shared/codemirror/addon/lint/yaml-lint.js @@ -1,28 +1,28 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -// Depends on js-yaml.js from https://github.com/nodeca/js-yaml - -// declare global: jsyaml - -CodeMirror.registerHelper("lint", "yaml", function(text) { - var found = []; - try { jsyaml.load(text); } - catch(e) { - var loc = e.mark; - found.push({ from: CodeMirror.Pos(loc.line, loc.column), to: CodeMirror.Pos(loc.line, loc.column), message: e.message }); - } - return found; -}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +// Depends on js-yaml.js from https://github.com/nodeca/js-yaml + +// declare global: jsyaml + +CodeMirror.registerHelper("lint", "yaml", function(text) { + var found = []; + try { jsyaml.load(text); } + catch(e) { + var loc = e.mark; + found.push({ from: CodeMirror.Pos(loc.line, loc.column), to: CodeMirror.Pos(loc.line, loc.column), message: e.message }); + } + return found; +}); + +}); diff --git a/shared/codemirror/addon/merge/merge.css b/shared/codemirror/addon/merge/merge.css index bda3d9f..1b75fe5 100644 --- a/shared/codemirror/addon/merge/merge.css +++ b/shared/codemirror/addon/merge/merge.css @@ -1,113 +1,113 @@ -.CodeMirror-merge { - position: relative; - border: 1px solid #ddd; - white-space: pre; -} - -.CodeMirror-merge, .CodeMirror-merge .CodeMirror { - height: 350px; -} - -.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; } -.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; } -.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; } -.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; } - -.CodeMirror-merge-pane { - display: inline-block; - white-space: normal; - vertical-align: top; -} -.CodeMirror-merge-pane-rightmost { - position: absolute; - right: 0px; - z-index: 1; -} - -.CodeMirror-merge-gap { - z-index: 2; - display: inline-block; - height: 100%; - -moz-box-sizing: border-box; - box-sizing: border-box; - overflow: hidden; - border-left: 1px solid #ddd; - border-right: 1px solid #ddd; - position: relative; - background: #f8f8f8; -} - -.CodeMirror-merge-scrolllock-wrap { - position: absolute; - bottom: 0; left: 50%; -} -.CodeMirror-merge-scrolllock { - position: relative; - left: -50%; - cursor: pointer; - color: #555; - line-height: 1; -} - -.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right { - position: absolute; - left: 0; top: 0; - right: 0; bottom: 0; - line-height: 1; -} - -.CodeMirror-merge-copy { - position: absolute; - cursor: pointer; - color: #44c; - z-index: 3; -} - -.CodeMirror-merge-copy-reverse { - position: absolute; - cursor: pointer; - color: #44c; -} - -.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; } -.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; } - -.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==); - background-position: bottom left; - background-repeat: repeat-x; -} - -.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==); - background-position: bottom left; - background-repeat: repeat-x; -} - -.CodeMirror-merge-r-chunk { background: #ffffe0; } -.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; } -.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; } -.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; } - -.CodeMirror-merge-l-chunk { background: #eef; } -.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; } -.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; } -.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; } - -.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; } -.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; } -.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; } - -.CodeMirror-merge-collapsed-widget:before { - content: "(...)"; -} -.CodeMirror-merge-collapsed-widget { - cursor: pointer; - color: #88b; - background: #eef; - border: 1px solid #ddf; - font-size: 90%; - padding: 0 3px; - border-radius: 4px; -} -.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; } +.CodeMirror-merge { + position: relative; + border: 1px solid #ddd; + white-space: pre; +} + +.CodeMirror-merge, .CodeMirror-merge .CodeMirror { + height: 350px; +} + +.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; } +.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; } +.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; } +.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; } + +.CodeMirror-merge-pane { + display: inline-block; + white-space: normal; + vertical-align: top; +} +.CodeMirror-merge-pane-rightmost { + position: absolute; + right: 0px; + z-index: 1; +} + +.CodeMirror-merge-gap { + z-index: 2; + display: inline-block; + height: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; + overflow: hidden; + border-left: 1px solid #ddd; + border-right: 1px solid #ddd; + position: relative; + background: #f8f8f8; +} + +.CodeMirror-merge-scrolllock-wrap { + position: absolute; + bottom: 0; left: 50%; +} +.CodeMirror-merge-scrolllock { + position: relative; + left: -50%; + cursor: pointer; + color: #555; + line-height: 1; +} + +.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right { + position: absolute; + left: 0; top: 0; + right: 0; bottom: 0; + line-height: 1; +} + +.CodeMirror-merge-copy { + position: absolute; + cursor: pointer; + color: #44c; + z-index: 3; +} + +.CodeMirror-merge-copy-reverse { + position: absolute; + cursor: pointer; + color: #44c; +} + +.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; } +.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; } + +.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==); + background-position: bottom left; + background-repeat: repeat-x; +} + +.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==); + background-position: bottom left; + background-repeat: repeat-x; +} + +.CodeMirror-merge-r-chunk { background: #ffffe0; } +.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; } +.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; } +.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; } + +.CodeMirror-merge-l-chunk { background: #eef; } +.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; } +.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; } +.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; } + +.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; } +.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; } +.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; } + +.CodeMirror-merge-collapsed-widget:before { + content: "(...)"; +} +.CodeMirror-merge-collapsed-widget { + cursor: pointer; + color: #88b; + background: #eef; + border: 1px solid #ddf; + font-size: 90%; + padding: 0 3px; + border-radius: 4px; +} +.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; } diff --git a/shared/codemirror/addon/merge/merge.js b/shared/codemirror/addon/merge/merge.js index d67b760..f42b810 100644 --- a/shared/codemirror/addon/merge/merge.js +++ b/shared/codemirror/addon/merge/merge.js @@ -1,773 +1,773 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "diff_match_patch"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - var Pos = CodeMirror.Pos; - var svgNS = "http://www.w3.org/2000/svg"; - - function DiffView(mv, type) { - this.mv = mv; - this.type = type; - this.classes = type == "left" - ? {chunk: "CodeMirror-merge-l-chunk", - start: "CodeMirror-merge-l-chunk-start", - end: "CodeMirror-merge-l-chunk-end", - insert: "CodeMirror-merge-l-inserted", - del: "CodeMirror-merge-l-deleted", - connect: "CodeMirror-merge-l-connect"} - : {chunk: "CodeMirror-merge-r-chunk", - start: "CodeMirror-merge-r-chunk-start", - end: "CodeMirror-merge-r-chunk-end", - insert: "CodeMirror-merge-r-inserted", - del: "CodeMirror-merge-r-deleted", - connect: "CodeMirror-merge-r-connect"}; - } - - DiffView.prototype = { - constructor: DiffView, - init: function(pane, orig, options) { - this.edit = this.mv.edit; - (this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this); - this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options))); - this.orig.state.diffViews = [this]; - - this.diff = getDiff(asString(orig), asString(options.value)); - this.chunks = getChunks(this.diff); - this.diffOutOfDate = this.dealigned = false; - - this.showDifferences = options.showDifferences !== false; - this.forceUpdate = registerUpdate(this); - setScrollLock(this, true, false); - registerScroll(this); - }, - setShowDifferences: function(val) { - val = val !== false; - if (val != this.showDifferences) { - this.showDifferences = val; - this.forceUpdate("full"); - } - } - }; - - function ensureDiff(dv) { - if (dv.diffOutOfDate) { - dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue()); - dv.chunks = getChunks(dv.diff); - dv.diffOutOfDate = false; - CodeMirror.signal(dv.edit, "updateDiff", dv.diff); - } - } - - var updating = false; - function registerUpdate(dv) { - var edit = {from: 0, to: 0, marked: []}; - var orig = {from: 0, to: 0, marked: []}; - var debounceChange, updatingFast = false; - function update(mode) { - updating = true; - updatingFast = false; - if (mode == "full") { - if (dv.svg) clear(dv.svg); - if (dv.copyButtons) clear(dv.copyButtons); - clearMarks(dv.edit, edit.marked, dv.classes); - clearMarks(dv.orig, orig.marked, dv.classes); - edit.from = edit.to = orig.from = orig.to = 0; - } - ensureDiff(dv); - if (dv.showDifferences) { - updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes); - updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes); - } - makeConnections(dv); - - if (dv.mv.options.connect == "align") - alignChunks(dv); - updating = false; - } - function setDealign(fast) { - if (updating) return; - dv.dealigned = true; - set(fast); - } - function set(fast) { - if (updating || updatingFast) return; - clearTimeout(debounceChange); - if (fast === true) updatingFast = true; - debounceChange = setTimeout(update, fast === true ? 20 : 250); - } - function change(_cm, change) { - if (!dv.diffOutOfDate) { - dv.diffOutOfDate = true; - edit.from = edit.to = orig.from = orig.to = 0; - } - // Update faster when a line was added/removed - setDealign(change.text.length - 1 != change.to.line - change.from.line); - } - dv.edit.on("change", change); - dv.orig.on("change", change); - dv.edit.on("markerAdded", setDealign); - dv.edit.on("markerCleared", setDealign); - dv.orig.on("markerAdded", setDealign); - dv.orig.on("markerCleared", setDealign); - dv.edit.on("viewportChange", function() { set(false); }); - dv.orig.on("viewportChange", function() { set(false); }); - update(); - return update; - } - - function registerScroll(dv) { - dv.edit.on("scroll", function() { - syncScroll(dv, DIFF_INSERT) && makeConnections(dv); - }); - dv.orig.on("scroll", function() { - syncScroll(dv, DIFF_DELETE) && makeConnections(dv); - }); - } - - function syncScroll(dv, type) { - // Change handler will do a refresh after a timeout when diff is out of date - if (dv.diffOutOfDate) return false; - if (!dv.lockScroll) return true; - var editor, other, now = +new Date; - if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; } - else { editor = dv.orig; other = dv.edit; } - // Don't take action if the position of this editor was recently set - // (to prevent feedback loops) - if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false; - - var sInfo = editor.getScrollInfo(); - if (dv.mv.options.connect == "align") { - targetPos = sInfo.top; - } else { - var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen; - var mid = editor.lineAtHeight(midY, "local"); - var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT); - var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig); - var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit); - var ratio = (midY - off.top) / (off.bot - off.top); - var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top); - - var botDist, mix; - // Some careful tweaking to make sure no space is left out of view - // when scrolling to top or bottom. - if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) { - targetPos = targetPos * mix + sInfo.top * (1 - mix); - } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) { - var otherInfo = other.getScrollInfo(); - var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos; - if (botDistOther > botDist && (mix = botDist / halfScreen) < 1) - targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix); - } - } - - other.scrollTo(sInfo.left, targetPos); - other.state.scrollSetAt = now; - other.state.scrollSetBy = dv; - return true; - } - - function getOffsets(editor, around) { - var bot = around.after; - if (bot == null) bot = editor.lastLine() + 1; - return {top: editor.heightAtLine(around.before || 0, "local"), - bot: editor.heightAtLine(bot, "local")}; - } - - function setScrollLock(dv, val, action) { - dv.lockScroll = val; - if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv); - dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da"; - } - - // Updating the marks for editor content - - function clearMarks(editor, arr, classes) { - for (var i = 0; i < arr.length; ++i) { - var mark = arr[i]; - if (mark instanceof CodeMirror.TextMarker) { - mark.clear(); - } else if (mark.parent) { - editor.removeLineClass(mark, "background", classes.chunk); - editor.removeLineClass(mark, "background", classes.start); - editor.removeLineClass(mark, "background", classes.end); - } - } - arr.length = 0; - } - - // FIXME maybe add a margin around viewport to prevent too many updates - function updateMarks(editor, diff, state, type, classes) { - var vp = editor.getViewport(); - editor.operation(function() { - if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { - clearMarks(editor, state.marked, classes); - markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes); - state.from = vp.from; state.to = vp.to; - } else { - if (vp.from < state.from) { - markChanges(editor, diff, type, state.marked, vp.from, state.from, classes); - state.from = vp.from; - } - if (vp.to > state.to) { - markChanges(editor, diff, type, state.marked, state.to, vp.to, classes); - state.to = vp.to; - } - } - }); - } - - function markChanges(editor, diff, type, marks, from, to, classes) { - var pos = Pos(0, 0); - var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1)); - var cls = type == DIFF_DELETE ? classes.del : classes.insert; - function markChunk(start, end) { - var bfrom = Math.max(from, start), bto = Math.min(to, end); - for (var i = bfrom; i < bto; ++i) { - var line = editor.addLineClass(i, "background", classes.chunk); - if (i == start) editor.addLineClass(line, "background", classes.start); - if (i == end - 1) editor.addLineClass(line, "background", classes.end); - marks.push(line); - } - // When the chunk is empty, make sure a horizontal line shows up - if (start == end && bfrom == end && bto == end) { - if (bfrom) - marks.push(editor.addLineClass(bfrom - 1, "background", classes.end)); - else - marks.push(editor.addLineClass(bfrom, "background", classes.start)); - } - } - - var chunkStart = 0; - for (var i = 0; i < diff.length; ++i) { - var part = diff[i], tp = part[0], str = part[1]; - if (tp == DIFF_EQUAL) { - var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1); - moveOver(pos, str); - var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0); - if (cleanTo > cleanFrom) { - if (i) markChunk(chunkStart, cleanFrom); - chunkStart = cleanTo; - } - } else { - if (tp == type) { - var end = moveOver(pos, str, true); - var a = posMax(top, pos), b = posMin(bot, end); - if (!posEq(a, b)) - marks.push(editor.markText(a, b, {className: cls})); - pos = end; - } - } - } - if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1); - } - - // Updating the gap between editor and original - - function makeConnections(dv) { - if (!dv.showDifferences) return; - - if (dv.svg) { - clear(dv.svg); - var w = dv.gap.offsetWidth; - attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight); - } - if (dv.copyButtons) clear(dv.copyButtons); - - var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport(); - var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top; - for (var i = 0; i < dv.chunks.length; i++) { - var ch = dv.chunks[i]; - if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from && - ch.origFrom <= vpOrig.to && ch.origTo >= vpOrig.from) - drawConnectorsForChunk(dv, ch, sTopOrig, sTopEdit, w); - } - } - - function getMatchingOrigLine(editLine, chunks) { - var editStart = 0, origStart = 0; - for (var i = 0; i < chunks.length; i++) { - var chunk = chunks[i]; - if (chunk.editTo > editLine && chunk.editFrom <= editLine) return null; - if (chunk.editFrom > editLine) break; - editStart = chunk.editTo; - origStart = chunk.origTo; - } - return origStart + (editLine - editStart); - } - - function findAlignedLines(dv, other) { - var linesToAlign = []; - for (var i = 0; i < dv.chunks.length; i++) { - var chunk = dv.chunks[i]; - linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]); - } - if (other) { - for (var i = 0; i < other.chunks.length; i++) { - var chunk = other.chunks[i]; - for (var j = 0; j < linesToAlign.length; j++) { - var align = linesToAlign[j]; - if (align[1] == chunk.editTo) { - j = -1; - break; - } else if (align[1] > chunk.editTo) { - break; - } - } - if (j > -1) - linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]); - } - } - return linesToAlign; - } - - function alignChunks(dv, force) { - if (!dv.dealigned && !force) return; - if (!dv.orig.curOp) return dv.orig.operation(function() { - alignChunks(dv, force); - }); - - dv.dealigned = false; - var other = dv.mv.left == dv ? dv.mv.right : dv.mv.left; - if (other) { - ensureDiff(other); - other.dealigned = false; - } - var linesToAlign = findAlignedLines(dv, other); - - // Clear old aligners - var aligners = dv.mv.aligners; - for (var i = 0; i < aligners.length; i++) - aligners[i].clear(); - aligners.length = 0; - - var cm = [dv.orig, dv.edit], scroll = []; - if (other) cm.push(other.orig); - for (var i = 0; i < cm.length; i++) - scroll.push(cm[i].getScrollInfo().top); - - for (var ln = 0; ln < linesToAlign.length; ln++) - alignLines(cm, linesToAlign[ln], aligners); - - for (var i = 0; i < cm.length; i++) - cm[i].scrollTo(null, scroll[i]); - } - - function alignLines(cm, lines, aligners) { - var maxOffset = 0, offset = []; - for (var i = 0; i < cm.length; i++) if (lines[i] != null) { - var off = cm[i].heightAtLine(lines[i], "local"); - offset[i] = off; - maxOffset = Math.max(maxOffset, off); - } - for (var i = 0; i < cm.length; i++) if (lines[i] != null) { - var diff = maxOffset - offset[i]; - if (diff > 1) - aligners.push(padAbove(cm[i], lines[i], diff)); - } - } - - function padAbove(cm, line, size) { - var above = true; - if (line > cm.lastLine()) { - line--; - above = false; - } - var elt = document.createElement("div"); - elt.className = "CodeMirror-merge-spacer"; - elt.style.height = size + "px"; elt.style.minWidth = "1px"; - return cm.addLineWidget(line, elt, {height: size, above: above}); - } - - function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) { - var flip = dv.type == "left"; - var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig; - if (dv.svg) { - var topLpx = top; - var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit; - if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; } - var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig; - var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit; - if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; } - var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx; - var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx; - attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")), - "d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z", - "class", dv.classes.connect); - } - if (dv.copyButtons) { - var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc", - "CodeMirror-merge-copy")); - var editOriginals = dv.mv.options.allowEditingOriginals; - copy.title = editOriginals ? "Push to left" : "Revert chunk"; - copy.chunk = chunk; - copy.style.top = top + "px"; - - if (editOriginals) { - var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit; - var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc", - "CodeMirror-merge-copy-reverse")); - copyReverse.title = "Push to right"; - copyReverse.chunk = {editFrom: chunk.origFrom, editTo: chunk.origTo, - origFrom: chunk.editFrom, origTo: chunk.editTo}; - copyReverse.style.top = topReverse + "px"; - dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px"; - } - } - } - - function copyChunk(dv, to, from, chunk) { - if (dv.diffOutOfDate) return; - var editStart = chunk.editTo > to.lastLine() ? Pos(chunk.editFrom - 1) : Pos(chunk.editFrom, 0) - var origStart = chunk.origTo > from.lastLine() ? Pos(chunk.origFrom - 1) : Pos(chunk.origFrom, 0) - to.replaceRange(from.getRange(origStart, Pos(chunk.origTo, 0)), editStart, Pos(chunk.editTo, 0)) - } - - // Merge view, containing 0, 1, or 2 diff views. - - var MergeView = CodeMirror.MergeView = function(node, options) { - if (!(this instanceof MergeView)) return new MergeView(node, options); - - this.options = options; - var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight; - - var hasLeft = origLeft != null, hasRight = origRight != null; - var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0); - var wrap = [], left = this.left = null, right = this.right = null; - var self = this; - - if (hasLeft) { - left = this.left = new DiffView(this, "left"); - var leftPane = elt("div", null, "CodeMirror-merge-pane"); - wrap.push(leftPane); - wrap.push(buildGap(left)); - } - - var editPane = elt("div", null, "CodeMirror-merge-pane"); - wrap.push(editPane); - - if (hasRight) { - right = this.right = new DiffView(this, "right"); - wrap.push(buildGap(right)); - var rightPane = elt("div", null, "CodeMirror-merge-pane"); - wrap.push(rightPane); - } - - (hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost"; - - wrap.push(elt("div", null, null, "height: 0; clear: both;")); - - var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane")); - this.edit = CodeMirror(editPane, copyObj(options)); - - if (left) left.init(leftPane, origLeft, options); - if (right) right.init(rightPane, origRight, options); - - if (options.collapseIdentical) - this.editor().operation(function() { - collapseIdenticalStretches(self, options.collapseIdentical); - }); - if (options.connect == "align") { - this.aligners = []; - alignChunks(this.left || this.right, true); - } - - var onResize = function() { - if (left) makeConnections(left); - if (right) makeConnections(right); - }; - CodeMirror.on(window, "resize", onResize); - var resizeInterval = setInterval(function() { - for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {} - if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); } - }, 5000); - }; - - function buildGap(dv) { - var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock"); - lock.title = "Toggle locked scrolling"; - var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap"); - CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); }); - var gapElts = [lockWrap]; - if (dv.mv.options.revertButtons !== false) { - dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type); - CodeMirror.on(dv.copyButtons, "click", function(e) { - var node = e.target || e.srcElement; - if (!node.chunk) return; - if (node.className == "CodeMirror-merge-copy-reverse") { - copyChunk(dv, dv.orig, dv.edit, node.chunk); - return; - } - copyChunk(dv, dv.edit, dv.orig, node.chunk); - }); - gapElts.unshift(dv.copyButtons); - } - if (dv.mv.options.connect != "align") { - var svg = document.createElementNS && document.createElementNS(svgNS, "svg"); - if (svg && !svg.createSVGRect) svg = null; - dv.svg = svg; - if (svg) gapElts.push(svg); - } - - return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap"); - } - - MergeView.prototype = { - constuctor: MergeView, - editor: function() { return this.edit; }, - rightOriginal: function() { return this.right && this.right.orig; }, - leftOriginal: function() { return this.left && this.left.orig; }, - setShowDifferences: function(val) { - if (this.right) this.right.setShowDifferences(val); - if (this.left) this.left.setShowDifferences(val); - }, - rightChunks: function() { - if (this.right) { ensureDiff(this.right); return this.right.chunks; } - }, - leftChunks: function() { - if (this.left) { ensureDiff(this.left); return this.left.chunks; } - } - }; - - function asString(obj) { - if (typeof obj == "string") return obj; - else return obj.getValue(); - } - - // Operations on diffs - - var dmp = new diff_match_patch(); - function getDiff(a, b) { - var diff = dmp.diff_main(a, b); - dmp.diff_cleanupSemantic(diff); - // The library sometimes leaves in empty parts, which confuse the algorithm - for (var i = 0; i < diff.length; ++i) { - var part = diff[i]; - if (!part[1]) { - diff.splice(i--, 1); - } else if (i && diff[i - 1][0] == part[0]) { - diff.splice(i--, 1); - diff[i][1] += part[1]; - } - } - return diff; - } - - function getChunks(diff) { - var chunks = []; - var startEdit = 0, startOrig = 0; - var edit = Pos(0, 0), orig = Pos(0, 0); - for (var i = 0; i < diff.length; ++i) { - var part = diff[i], tp = part[0]; - if (tp == DIFF_EQUAL) { - var startOff = startOfLineClean(diff, i) ? 0 : 1; - var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff; - moveOver(edit, part[1], null, orig); - var endOff = endOfLineClean(diff, i) ? 1 : 0; - var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff; - if (cleanToEdit > cleanFromEdit) { - if (i) chunks.push({origFrom: startOrig, origTo: cleanFromOrig, - editFrom: startEdit, editTo: cleanFromEdit}); - startEdit = cleanToEdit; startOrig = cleanToOrig; - } - } else { - moveOver(tp == DIFF_INSERT ? edit : orig, part[1]); - } - } - if (startEdit <= edit.line || startOrig <= orig.line) - chunks.push({origFrom: startOrig, origTo: orig.line + 1, - editFrom: startEdit, editTo: edit.line + 1}); - return chunks; - } - - function endOfLineClean(diff, i) { - if (i == diff.length - 1) return true; - var next = diff[i + 1][1]; - if (next.length == 1 || next.charCodeAt(0) != 10) return false; - if (i == diff.length - 2) return true; - next = diff[i + 2][1]; - return next.length > 1 && next.charCodeAt(0) == 10; - } - - function startOfLineClean(diff, i) { - if (i == 0) return true; - var last = diff[i - 1][1]; - if (last.charCodeAt(last.length - 1) != 10) return false; - if (i == 1) return true; - last = diff[i - 2][1]; - return last.charCodeAt(last.length - 1) == 10; - } - - function chunkBoundariesAround(chunks, n, nInEdit) { - var beforeE, afterE, beforeO, afterO; - for (var i = 0; i < chunks.length; i++) { - var chunk = chunks[i]; - var fromLocal = nInEdit ? chunk.editFrom : chunk.origFrom; - var toLocal = nInEdit ? chunk.editTo : chunk.origTo; - if (afterE == null) { - if (fromLocal > n) { afterE = chunk.editFrom; afterO = chunk.origFrom; } - else if (toLocal > n) { afterE = chunk.editTo; afterO = chunk.origTo; } - } - if (toLocal <= n) { beforeE = chunk.editTo; beforeO = chunk.origTo; } - else if (fromLocal <= n) { beforeE = chunk.editFrom; beforeO = chunk.origFrom; } - } - return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}}; - } - - function collapseSingle(cm, from, to) { - cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); - var widget = document.createElement("span"); - widget.className = "CodeMirror-merge-collapsed-widget"; - widget.title = "Identical text collapsed. Click to expand."; - var mark = cm.markText(Pos(from, 0), Pos(to - 1), { - inclusiveLeft: true, - inclusiveRight: true, - replacedWith: widget, - clearOnEnter: true - }); - function clear() { - mark.clear(); - cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); - } - CodeMirror.on(widget, "click", clear); - return {mark: mark, clear: clear}; - } - - function collapseStretch(size, editors) { - var marks = []; - function clear() { - for (var i = 0; i < marks.length; i++) marks[i].clear(); - } - for (var i = 0; i < editors.length; i++) { - var editor = editors[i]; - var mark = collapseSingle(editor.cm, editor.line, editor.line + size); - marks.push(mark); - mark.mark.on("clear", clear); - } - return marks[0].mark; - } - - function unclearNearChunks(dv, margin, off, clear) { - for (var i = 0; i < dv.chunks.length; i++) { - var chunk = dv.chunks[i]; - for (var l = chunk.editFrom - margin; l < chunk.editTo + margin; l++) { - var pos = l + off; - if (pos >= 0 && pos < clear.length) clear[pos] = false; - } - } - } - - function collapseIdenticalStretches(mv, margin) { - if (typeof margin != "number") margin = 2; - var clear = [], edit = mv.editor(), off = edit.firstLine(); - for (var l = off, e = edit.lastLine(); l <= e; l++) clear.push(true); - if (mv.left) unclearNearChunks(mv.left, margin, off, clear); - if (mv.right) unclearNearChunks(mv.right, margin, off, clear); - - for (var i = 0; i < clear.length; i++) { - if (clear[i]) { - var line = i + off; - for (var size = 1; i < clear.length - 1 && clear[i + 1]; i++, size++) {} - if (size > margin) { - var editors = [{line: line, cm: edit}]; - if (mv.left) editors.push({line: getMatchingOrigLine(line, mv.left.chunks), cm: mv.left.orig}); - if (mv.right) editors.push({line: getMatchingOrigLine(line, mv.right.chunks), cm: mv.right.orig}); - var mark = collapseStretch(size, editors); - if (mv.options.onCollapse) mv.options.onCollapse(mv, line, size, mark); - } - } - } - } - - // General utilities - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") e.appendChild(document.createTextNode(content)); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - function clear(node) { - for (var count = node.childNodes.length; count > 0; --count) - node.removeChild(node.firstChild); - } - - function attrs(elt) { - for (var i = 1; i < arguments.length; i += 2) - elt.setAttribute(arguments[i], arguments[i+1]); - } - - function copyObj(obj, target) { - if (!target) target = {}; - for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; - return target; - } - - function moveOver(pos, str, copy, other) { - var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0; - for (;;) { - var nl = str.indexOf("\n", at); - if (nl == -1) break; - ++out.line; - if (other) ++other.line; - at = nl + 1; - } - out.ch = (at ? 0 : out.ch) + (str.length - at); - if (other) other.ch = (at ? 0 : other.ch) + (str.length - at); - return out; - } - - function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; } - function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; } - function posEq(a, b) { return a.line == b.line && a.ch == b.ch; } - - function findPrevDiff(chunks, start, isOrig) { - for (var i = chunks.length - 1; i >= 0; i--) { - var chunk = chunks[i]; - var to = (isOrig ? chunk.origTo : chunk.editTo) - 1; - if (to < start) return to; - } - } - - function findNextDiff(chunks, start, isOrig) { - for (var i = 0; i < chunks.length; i++) { - var chunk = chunks[i]; - var from = (isOrig ? chunk.origFrom : chunk.editFrom); - if (from > start) return from; - } - } - - function goNearbyDiff(cm, dir) { - var found = null, views = cm.state.diffViews, line = cm.getCursor().line; - if (views) for (var i = 0; i < views.length; i++) { - var dv = views[i], isOrig = cm == dv.orig; - ensureDiff(dv); - var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig); - if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found))) - found = pos; - } - if (found != null) - cm.setCursor(found, 0); - else - return CodeMirror.Pass; - } - - CodeMirror.commands.goNextDiff = function(cm) { - return goNearbyDiff(cm, 1); - }; - CodeMirror.commands.goPrevDiff = function(cm) { - return goNearbyDiff(cm, -1); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "diff_match_patch"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var Pos = CodeMirror.Pos; + var svgNS = "http://www.w3.org/2000/svg"; + + function DiffView(mv, type) { + this.mv = mv; + this.type = type; + this.classes = type == "left" + ? {chunk: "CodeMirror-merge-l-chunk", + start: "CodeMirror-merge-l-chunk-start", + end: "CodeMirror-merge-l-chunk-end", + insert: "CodeMirror-merge-l-inserted", + del: "CodeMirror-merge-l-deleted", + connect: "CodeMirror-merge-l-connect"} + : {chunk: "CodeMirror-merge-r-chunk", + start: "CodeMirror-merge-r-chunk-start", + end: "CodeMirror-merge-r-chunk-end", + insert: "CodeMirror-merge-r-inserted", + del: "CodeMirror-merge-r-deleted", + connect: "CodeMirror-merge-r-connect"}; + } + + DiffView.prototype = { + constructor: DiffView, + init: function(pane, orig, options) { + this.edit = this.mv.edit; + (this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this); + this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options))); + this.orig.state.diffViews = [this]; + + this.diff = getDiff(asString(orig), asString(options.value)); + this.chunks = getChunks(this.diff); + this.diffOutOfDate = this.dealigned = false; + + this.showDifferences = options.showDifferences !== false; + this.forceUpdate = registerUpdate(this); + setScrollLock(this, true, false); + registerScroll(this); + }, + setShowDifferences: function(val) { + val = val !== false; + if (val != this.showDifferences) { + this.showDifferences = val; + this.forceUpdate("full"); + } + } + }; + + function ensureDiff(dv) { + if (dv.diffOutOfDate) { + dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue()); + dv.chunks = getChunks(dv.diff); + dv.diffOutOfDate = false; + CodeMirror.signal(dv.edit, "updateDiff", dv.diff); + } + } + + var updating = false; + function registerUpdate(dv) { + var edit = {from: 0, to: 0, marked: []}; + var orig = {from: 0, to: 0, marked: []}; + var debounceChange, updatingFast = false; + function update(mode) { + updating = true; + updatingFast = false; + if (mode == "full") { + if (dv.svg) clear(dv.svg); + if (dv.copyButtons) clear(dv.copyButtons); + clearMarks(dv.edit, edit.marked, dv.classes); + clearMarks(dv.orig, orig.marked, dv.classes); + edit.from = edit.to = orig.from = orig.to = 0; + } + ensureDiff(dv); + if (dv.showDifferences) { + updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes); + updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes); + } + makeConnections(dv); + + if (dv.mv.options.connect == "align") + alignChunks(dv); + updating = false; + } + function setDealign(fast) { + if (updating) return; + dv.dealigned = true; + set(fast); + } + function set(fast) { + if (updating || updatingFast) return; + clearTimeout(debounceChange); + if (fast === true) updatingFast = true; + debounceChange = setTimeout(update, fast === true ? 20 : 250); + } + function change(_cm, change) { + if (!dv.diffOutOfDate) { + dv.diffOutOfDate = true; + edit.from = edit.to = orig.from = orig.to = 0; + } + // Update faster when a line was added/removed + setDealign(change.text.length - 1 != change.to.line - change.from.line); + } + dv.edit.on("change", change); + dv.orig.on("change", change); + dv.edit.on("markerAdded", setDealign); + dv.edit.on("markerCleared", setDealign); + dv.orig.on("markerAdded", setDealign); + dv.orig.on("markerCleared", setDealign); + dv.edit.on("viewportChange", function() { set(false); }); + dv.orig.on("viewportChange", function() { set(false); }); + update(); + return update; + } + + function registerScroll(dv) { + dv.edit.on("scroll", function() { + syncScroll(dv, DIFF_INSERT) && makeConnections(dv); + }); + dv.orig.on("scroll", function() { + syncScroll(dv, DIFF_DELETE) && makeConnections(dv); + }); + } + + function syncScroll(dv, type) { + // Change handler will do a refresh after a timeout when diff is out of date + if (dv.diffOutOfDate) return false; + if (!dv.lockScroll) return true; + var editor, other, now = +new Date; + if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; } + else { editor = dv.orig; other = dv.edit; } + // Don't take action if the position of this editor was recently set + // (to prevent feedback loops) + if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false; + + var sInfo = editor.getScrollInfo(); + if (dv.mv.options.connect == "align") { + targetPos = sInfo.top; + } else { + var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen; + var mid = editor.lineAtHeight(midY, "local"); + var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT); + var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig); + var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit); + var ratio = (midY - off.top) / (off.bot - off.top); + var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top); + + var botDist, mix; + // Some careful tweaking to make sure no space is left out of view + // when scrolling to top or bottom. + if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) { + targetPos = targetPos * mix + sInfo.top * (1 - mix); + } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) { + var otherInfo = other.getScrollInfo(); + var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos; + if (botDistOther > botDist && (mix = botDist / halfScreen) < 1) + targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix); + } + } + + other.scrollTo(sInfo.left, targetPos); + other.state.scrollSetAt = now; + other.state.scrollSetBy = dv; + return true; + } + + function getOffsets(editor, around) { + var bot = around.after; + if (bot == null) bot = editor.lastLine() + 1; + return {top: editor.heightAtLine(around.before || 0, "local"), + bot: editor.heightAtLine(bot, "local")}; + } + + function setScrollLock(dv, val, action) { + dv.lockScroll = val; + if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv); + dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da"; + } + + // Updating the marks for editor content + + function clearMarks(editor, arr, classes) { + for (var i = 0; i < arr.length; ++i) { + var mark = arr[i]; + if (mark instanceof CodeMirror.TextMarker) { + mark.clear(); + } else if (mark.parent) { + editor.removeLineClass(mark, "background", classes.chunk); + editor.removeLineClass(mark, "background", classes.start); + editor.removeLineClass(mark, "background", classes.end); + } + } + arr.length = 0; + } + + // FIXME maybe add a margin around viewport to prevent too many updates + function updateMarks(editor, diff, state, type, classes) { + var vp = editor.getViewport(); + editor.operation(function() { + if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { + clearMarks(editor, state.marked, classes); + markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes); + state.from = vp.from; state.to = vp.to; + } else { + if (vp.from < state.from) { + markChanges(editor, diff, type, state.marked, vp.from, state.from, classes); + state.from = vp.from; + } + if (vp.to > state.to) { + markChanges(editor, diff, type, state.marked, state.to, vp.to, classes); + state.to = vp.to; + } + } + }); + } + + function markChanges(editor, diff, type, marks, from, to, classes) { + var pos = Pos(0, 0); + var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1)); + var cls = type == DIFF_DELETE ? classes.del : classes.insert; + function markChunk(start, end) { + var bfrom = Math.max(from, start), bto = Math.min(to, end); + for (var i = bfrom; i < bto; ++i) { + var line = editor.addLineClass(i, "background", classes.chunk); + if (i == start) editor.addLineClass(line, "background", classes.start); + if (i == end - 1) editor.addLineClass(line, "background", classes.end); + marks.push(line); + } + // When the chunk is empty, make sure a horizontal line shows up + if (start == end && bfrom == end && bto == end) { + if (bfrom) + marks.push(editor.addLineClass(bfrom - 1, "background", classes.end)); + else + marks.push(editor.addLineClass(bfrom, "background", classes.start)); + } + } + + var chunkStart = 0; + for (var i = 0; i < diff.length; ++i) { + var part = diff[i], tp = part[0], str = part[1]; + if (tp == DIFF_EQUAL) { + var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1); + moveOver(pos, str); + var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0); + if (cleanTo > cleanFrom) { + if (i) markChunk(chunkStart, cleanFrom); + chunkStart = cleanTo; + } + } else { + if (tp == type) { + var end = moveOver(pos, str, true); + var a = posMax(top, pos), b = posMin(bot, end); + if (!posEq(a, b)) + marks.push(editor.markText(a, b, {className: cls})); + pos = end; + } + } + } + if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1); + } + + // Updating the gap between editor and original + + function makeConnections(dv) { + if (!dv.showDifferences) return; + + if (dv.svg) { + clear(dv.svg); + var w = dv.gap.offsetWidth; + attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight); + } + if (dv.copyButtons) clear(dv.copyButtons); + + var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport(); + var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top; + for (var i = 0; i < dv.chunks.length; i++) { + var ch = dv.chunks[i]; + if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from && + ch.origFrom <= vpOrig.to && ch.origTo >= vpOrig.from) + drawConnectorsForChunk(dv, ch, sTopOrig, sTopEdit, w); + } + } + + function getMatchingOrigLine(editLine, chunks) { + var editStart = 0, origStart = 0; + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + if (chunk.editTo > editLine && chunk.editFrom <= editLine) return null; + if (chunk.editFrom > editLine) break; + editStart = chunk.editTo; + origStart = chunk.origTo; + } + return origStart + (editLine - editStart); + } + + function findAlignedLines(dv, other) { + var linesToAlign = []; + for (var i = 0; i < dv.chunks.length; i++) { + var chunk = dv.chunks[i]; + linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]); + } + if (other) { + for (var i = 0; i < other.chunks.length; i++) { + var chunk = other.chunks[i]; + for (var j = 0; j < linesToAlign.length; j++) { + var align = linesToAlign[j]; + if (align[1] == chunk.editTo) { + j = -1; + break; + } else if (align[1] > chunk.editTo) { + break; + } + } + if (j > -1) + linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]); + } + } + return linesToAlign; + } + + function alignChunks(dv, force) { + if (!dv.dealigned && !force) return; + if (!dv.orig.curOp) return dv.orig.operation(function() { + alignChunks(dv, force); + }); + + dv.dealigned = false; + var other = dv.mv.left == dv ? dv.mv.right : dv.mv.left; + if (other) { + ensureDiff(other); + other.dealigned = false; + } + var linesToAlign = findAlignedLines(dv, other); + + // Clear old aligners + var aligners = dv.mv.aligners; + for (var i = 0; i < aligners.length; i++) + aligners[i].clear(); + aligners.length = 0; + + var cm = [dv.orig, dv.edit], scroll = []; + if (other) cm.push(other.orig); + for (var i = 0; i < cm.length; i++) + scroll.push(cm[i].getScrollInfo().top); + + for (var ln = 0; ln < linesToAlign.length; ln++) + alignLines(cm, linesToAlign[ln], aligners); + + for (var i = 0; i < cm.length; i++) + cm[i].scrollTo(null, scroll[i]); + } + + function alignLines(cm, lines, aligners) { + var maxOffset = 0, offset = []; + for (var i = 0; i < cm.length; i++) if (lines[i] != null) { + var off = cm[i].heightAtLine(lines[i], "local"); + offset[i] = off; + maxOffset = Math.max(maxOffset, off); + } + for (var i = 0; i < cm.length; i++) if (lines[i] != null) { + var diff = maxOffset - offset[i]; + if (diff > 1) + aligners.push(padAbove(cm[i], lines[i], diff)); + } + } + + function padAbove(cm, line, size) { + var above = true; + if (line > cm.lastLine()) { + line--; + above = false; + } + var elt = document.createElement("div"); + elt.className = "CodeMirror-merge-spacer"; + elt.style.height = size + "px"; elt.style.minWidth = "1px"; + return cm.addLineWidget(line, elt, {height: size, above: above}); + } + + function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) { + var flip = dv.type == "left"; + var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig; + if (dv.svg) { + var topLpx = top; + var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit; + if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; } + var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig; + var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit; + if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; } + var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx; + var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx; + attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")), + "d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z", + "class", dv.classes.connect); + } + if (dv.copyButtons) { + var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc", + "CodeMirror-merge-copy")); + var editOriginals = dv.mv.options.allowEditingOriginals; + copy.title = editOriginals ? "Push to left" : "Revert chunk"; + copy.chunk = chunk; + copy.style.top = top + "px"; + + if (editOriginals) { + var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit; + var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc", + "CodeMirror-merge-copy-reverse")); + copyReverse.title = "Push to right"; + copyReverse.chunk = {editFrom: chunk.origFrom, editTo: chunk.origTo, + origFrom: chunk.editFrom, origTo: chunk.editTo}; + copyReverse.style.top = topReverse + "px"; + dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px"; + } + } + } + + function copyChunk(dv, to, from, chunk) { + if (dv.diffOutOfDate) return; + var editStart = chunk.editTo > to.lastLine() ? Pos(chunk.editFrom - 1) : Pos(chunk.editFrom, 0) + var origStart = chunk.origTo > from.lastLine() ? Pos(chunk.origFrom - 1) : Pos(chunk.origFrom, 0) + to.replaceRange(from.getRange(origStart, Pos(chunk.origTo, 0)), editStart, Pos(chunk.editTo, 0)) + } + + // Merge view, containing 0, 1, or 2 diff views. + + var MergeView = CodeMirror.MergeView = function(node, options) { + if (!(this instanceof MergeView)) return new MergeView(node, options); + + this.options = options; + var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight; + + var hasLeft = origLeft != null, hasRight = origRight != null; + var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0); + var wrap = [], left = this.left = null, right = this.right = null; + var self = this; + + if (hasLeft) { + left = this.left = new DiffView(this, "left"); + var leftPane = elt("div", null, "CodeMirror-merge-pane"); + wrap.push(leftPane); + wrap.push(buildGap(left)); + } + + var editPane = elt("div", null, "CodeMirror-merge-pane"); + wrap.push(editPane); + + if (hasRight) { + right = this.right = new DiffView(this, "right"); + wrap.push(buildGap(right)); + var rightPane = elt("div", null, "CodeMirror-merge-pane"); + wrap.push(rightPane); + } + + (hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost"; + + wrap.push(elt("div", null, null, "height: 0; clear: both;")); + + var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane")); + this.edit = CodeMirror(editPane, copyObj(options)); + + if (left) left.init(leftPane, origLeft, options); + if (right) right.init(rightPane, origRight, options); + + if (options.collapseIdentical) + this.editor().operation(function() { + collapseIdenticalStretches(self, options.collapseIdentical); + }); + if (options.connect == "align") { + this.aligners = []; + alignChunks(this.left || this.right, true); + } + + var onResize = function() { + if (left) makeConnections(left); + if (right) makeConnections(right); + }; + CodeMirror.on(window, "resize", onResize); + var resizeInterval = setInterval(function() { + for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {} + if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); } + }, 5000); + }; + + function buildGap(dv) { + var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock"); + lock.title = "Toggle locked scrolling"; + var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap"); + CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); }); + var gapElts = [lockWrap]; + if (dv.mv.options.revertButtons !== false) { + dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type); + CodeMirror.on(dv.copyButtons, "click", function(e) { + var node = e.target || e.srcElement; + if (!node.chunk) return; + if (node.className == "CodeMirror-merge-copy-reverse") { + copyChunk(dv, dv.orig, dv.edit, node.chunk); + return; + } + copyChunk(dv, dv.edit, dv.orig, node.chunk); + }); + gapElts.unshift(dv.copyButtons); + } + if (dv.mv.options.connect != "align") { + var svg = document.createElementNS && document.createElementNS(svgNS, "svg"); + if (svg && !svg.createSVGRect) svg = null; + dv.svg = svg; + if (svg) gapElts.push(svg); + } + + return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap"); + } + + MergeView.prototype = { + constuctor: MergeView, + editor: function() { return this.edit; }, + rightOriginal: function() { return this.right && this.right.orig; }, + leftOriginal: function() { return this.left && this.left.orig; }, + setShowDifferences: function(val) { + if (this.right) this.right.setShowDifferences(val); + if (this.left) this.left.setShowDifferences(val); + }, + rightChunks: function() { + if (this.right) { ensureDiff(this.right); return this.right.chunks; } + }, + leftChunks: function() { + if (this.left) { ensureDiff(this.left); return this.left.chunks; } + } + }; + + function asString(obj) { + if (typeof obj == "string") return obj; + else return obj.getValue(); + } + + // Operations on diffs + + var dmp = new diff_match_patch(); + function getDiff(a, b) { + var diff = dmp.diff_main(a, b); + dmp.diff_cleanupSemantic(diff); + // The library sometimes leaves in empty parts, which confuse the algorithm + for (var i = 0; i < diff.length; ++i) { + var part = diff[i]; + if (!part[1]) { + diff.splice(i--, 1); + } else if (i && diff[i - 1][0] == part[0]) { + diff.splice(i--, 1); + diff[i][1] += part[1]; + } + } + return diff; + } + + function getChunks(diff) { + var chunks = []; + var startEdit = 0, startOrig = 0; + var edit = Pos(0, 0), orig = Pos(0, 0); + for (var i = 0; i < diff.length; ++i) { + var part = diff[i], tp = part[0]; + if (tp == DIFF_EQUAL) { + var startOff = startOfLineClean(diff, i) ? 0 : 1; + var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff; + moveOver(edit, part[1], null, orig); + var endOff = endOfLineClean(diff, i) ? 1 : 0; + var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff; + if (cleanToEdit > cleanFromEdit) { + if (i) chunks.push({origFrom: startOrig, origTo: cleanFromOrig, + editFrom: startEdit, editTo: cleanFromEdit}); + startEdit = cleanToEdit; startOrig = cleanToOrig; + } + } else { + moveOver(tp == DIFF_INSERT ? edit : orig, part[1]); + } + } + if (startEdit <= edit.line || startOrig <= orig.line) + chunks.push({origFrom: startOrig, origTo: orig.line + 1, + editFrom: startEdit, editTo: edit.line + 1}); + return chunks; + } + + function endOfLineClean(diff, i) { + if (i == diff.length - 1) return true; + var next = diff[i + 1][1]; + if (next.length == 1 || next.charCodeAt(0) != 10) return false; + if (i == diff.length - 2) return true; + next = diff[i + 2][1]; + return next.length > 1 && next.charCodeAt(0) == 10; + } + + function startOfLineClean(diff, i) { + if (i == 0) return true; + var last = diff[i - 1][1]; + if (last.charCodeAt(last.length - 1) != 10) return false; + if (i == 1) return true; + last = diff[i - 2][1]; + return last.charCodeAt(last.length - 1) == 10; + } + + function chunkBoundariesAround(chunks, n, nInEdit) { + var beforeE, afterE, beforeO, afterO; + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + var fromLocal = nInEdit ? chunk.editFrom : chunk.origFrom; + var toLocal = nInEdit ? chunk.editTo : chunk.origTo; + if (afterE == null) { + if (fromLocal > n) { afterE = chunk.editFrom; afterO = chunk.origFrom; } + else if (toLocal > n) { afterE = chunk.editTo; afterO = chunk.origTo; } + } + if (toLocal <= n) { beforeE = chunk.editTo; beforeO = chunk.origTo; } + else if (fromLocal <= n) { beforeE = chunk.editFrom; beforeO = chunk.origFrom; } + } + return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}}; + } + + function collapseSingle(cm, from, to) { + cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); + var widget = document.createElement("span"); + widget.className = "CodeMirror-merge-collapsed-widget"; + widget.title = "Identical text collapsed. Click to expand."; + var mark = cm.markText(Pos(from, 0), Pos(to - 1), { + inclusiveLeft: true, + inclusiveRight: true, + replacedWith: widget, + clearOnEnter: true + }); + function clear() { + mark.clear(); + cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); + } + CodeMirror.on(widget, "click", clear); + return {mark: mark, clear: clear}; + } + + function collapseStretch(size, editors) { + var marks = []; + function clear() { + for (var i = 0; i < marks.length; i++) marks[i].clear(); + } + for (var i = 0; i < editors.length; i++) { + var editor = editors[i]; + var mark = collapseSingle(editor.cm, editor.line, editor.line + size); + marks.push(mark); + mark.mark.on("clear", clear); + } + return marks[0].mark; + } + + function unclearNearChunks(dv, margin, off, clear) { + for (var i = 0; i < dv.chunks.length; i++) { + var chunk = dv.chunks[i]; + for (var l = chunk.editFrom - margin; l < chunk.editTo + margin; l++) { + var pos = l + off; + if (pos >= 0 && pos < clear.length) clear[pos] = false; + } + } + } + + function collapseIdenticalStretches(mv, margin) { + if (typeof margin != "number") margin = 2; + var clear = [], edit = mv.editor(), off = edit.firstLine(); + for (var l = off, e = edit.lastLine(); l <= e; l++) clear.push(true); + if (mv.left) unclearNearChunks(mv.left, margin, off, clear); + if (mv.right) unclearNearChunks(mv.right, margin, off, clear); + + for (var i = 0; i < clear.length; i++) { + if (clear[i]) { + var line = i + off; + for (var size = 1; i < clear.length - 1 && clear[i + 1]; i++, size++) {} + if (size > margin) { + var editors = [{line: line, cm: edit}]; + if (mv.left) editors.push({line: getMatchingOrigLine(line, mv.left.chunks), cm: mv.left.orig}); + if (mv.right) editors.push({line: getMatchingOrigLine(line, mv.right.chunks), cm: mv.right.orig}); + var mark = collapseStretch(size, editors); + if (mv.options.onCollapse) mv.options.onCollapse(mv, line, size, mark); + } + } + } + } + + // General utilities + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + function clear(node) { + for (var count = node.childNodes.length; count > 0; --count) + node.removeChild(node.firstChild); + } + + function attrs(elt) { + for (var i = 1; i < arguments.length; i += 2) + elt.setAttribute(arguments[i], arguments[i+1]); + } + + function copyObj(obj, target) { + if (!target) target = {}; + for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; + return target; + } + + function moveOver(pos, str, copy, other) { + var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0; + for (;;) { + var nl = str.indexOf("\n", at); + if (nl == -1) break; + ++out.line; + if (other) ++other.line; + at = nl + 1; + } + out.ch = (at ? 0 : out.ch) + (str.length - at); + if (other) other.ch = (at ? 0 : other.ch) + (str.length - at); + return out; + } + + function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; } + function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; } + function posEq(a, b) { return a.line == b.line && a.ch == b.ch; } + + function findPrevDiff(chunks, start, isOrig) { + for (var i = chunks.length - 1; i >= 0; i--) { + var chunk = chunks[i]; + var to = (isOrig ? chunk.origTo : chunk.editTo) - 1; + if (to < start) return to; + } + } + + function findNextDiff(chunks, start, isOrig) { + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + var from = (isOrig ? chunk.origFrom : chunk.editFrom); + if (from > start) return from; + } + } + + function goNearbyDiff(cm, dir) { + var found = null, views = cm.state.diffViews, line = cm.getCursor().line; + if (views) for (var i = 0; i < views.length; i++) { + var dv = views[i], isOrig = cm == dv.orig; + ensureDiff(dv); + var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig); + if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found))) + found = pos; + } + if (found != null) + cm.setCursor(found, 0); + else + return CodeMirror.Pass; + } + + CodeMirror.commands.goNextDiff = function(cm) { + return goNearbyDiff(cm, 1); + }; + CodeMirror.commands.goPrevDiff = function(cm) { + return goNearbyDiff(cm, -1); + }; +}); diff --git a/shared/codemirror/addon/mode/loadmode.js b/shared/codemirror/addon/mode/loadmode.js index 10117ec..dd7bb3c 100644 --- a/shared/codemirror/addon/mode/loadmode.js +++ b/shared/codemirror/addon/mode/loadmode.js @@ -1,64 +1,64 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), "cjs"); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); }); - else // Plain browser env - mod(CodeMirror, "plain"); -})(function(CodeMirror, env) { - 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 (typeof mode != "string") mode = mode.name; - if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); - if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); - - var file = CodeMirror.modeURL.replace(/%N/g, mode); - if (env == "plain") { - var script = document.createElement("script"); - script.src = file; - var others = document.getElementsByTagName("script")[0]; - var list = loading[mode] = [cont]; - CodeMirror.on(script, "load", function() { - ensureDeps(mode, function() { - for (var i = 0; i < list.length; ++i) list[i](); - }); - }); - others.parentNode.insertBefore(script, others); - } else if (env == "cjs") { - require(file); - cont(); - } else if (env == "amd") { - requirejs([file], cont); - } - }; - - CodeMirror.autoLoadMode = function(instance, mode) { - if (!CodeMirror.modes.hasOwnProperty(mode)) - CodeMirror.requireMode(mode, function() { - instance.setOption("mode", instance.getOption("mode")); - }); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), "cjs"); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); }); + else // Plain browser env + mod(CodeMirror, "plain"); +})(function(CodeMirror, env) { + 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 (typeof mode != "string") mode = mode.name; + if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); + if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); + + var file = CodeMirror.modeURL.replace(/%N/g, mode); + if (env == "plain") { + var script = document.createElement("script"); + script.src = file; + var others = document.getElementsByTagName("script")[0]; + var list = loading[mode] = [cont]; + CodeMirror.on(script, "load", function() { + ensureDeps(mode, function() { + for (var i = 0; i < list.length; ++i) list[i](); + }); + }); + others.parentNode.insertBefore(script, others); + } else if (env == "cjs") { + require(file); + cont(); + } else if (env == "amd") { + requirejs([file], cont); + } + }; + + CodeMirror.autoLoadMode = function(instance, mode) { + if (!CodeMirror.modes.hasOwnProperty(mode)) + CodeMirror.requireMode(mode, function() { + instance.setOption("mode", instance.getOption("mode")); + }); + }; +}); diff --git a/shared/codemirror/addon/mode/multiplex.js b/shared/codemirror/addon/mode/multiplex.js index 3d8b34c..dd7d229 100644 --- a/shared/codemirror/addon/mode/multiplex.js +++ b/shared/codemirror/addon/mode/multiplex.js @@ -1,123 +1,123 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.multiplexingMode = function(outer /*, others */) { - // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects - var others = Array.prototype.slice.call(arguments, 1); - - function indexOf(string, pattern, from, returnEnd) { - if (typeof pattern == "string") { - var found = string.indexOf(pattern, from); - return returnEnd && found > -1 ? found + pattern.length : found; - } - var m = pattern.exec(from ? string.slice(from) : string); - return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1; - } - - return { - startState: function() { - return { - outer: CodeMirror.startState(outer), - innerActive: null, - inner: null - }; - }, - - copyState: function(state) { - return { - outer: CodeMirror.copyState(outer, state.outer), - innerActive: state.innerActive, - inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) - }; - }, - - token: function(stream, state) { - if (!state.innerActive) { - var cutOff = Infinity, oldContent = stream.string; - for (var i = 0; i < others.length; ++i) { - var other = others[i]; - var found = indexOf(oldContent, other.open, stream.pos); - if (found == stream.pos) { - if (!other.parseDelimiters) stream.match(other.open); - state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); - return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); - } else if (found != -1 && found < cutOff) { - cutOff = found; - } - } - if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); - var outerToken = outer.token(stream, state.outer); - if (cutOff != Infinity) stream.string = oldContent; - return outerToken; - } else { - var curInner = state.innerActive, oldContent = stream.string; - if (!curInner.close && stream.sol()) { - state.innerActive = state.inner = null; - return this.token(stream, state); - } - var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1; - if (found == stream.pos && !curInner.parseDelimiters) { - stream.match(curInner.close); - state.innerActive = state.inner = null; - return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close"); - } - if (found > -1) stream.string = oldContent.slice(0, found); - var innerToken = curInner.mode.token(stream, state.inner); - if (found > -1) stream.string = oldContent; - - if (found == stream.pos && curInner.parseDelimiters) - state.innerActive = state.inner = null; - - if (curInner.innerStyle) { - if (innerToken) innerToken = innerToken + " " + curInner.innerStyle; - else innerToken = curInner.innerStyle; - } - - return innerToken; - } - }, - - indent: function(state, textAfter) { - var mode = state.innerActive ? state.innerActive.mode : outer; - if (!mode.indent) return CodeMirror.Pass; - return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); - }, - - blankLine: function(state) { - var mode = state.innerActive ? state.innerActive.mode : outer; - if (mode.blankLine) { - mode.blankLine(state.innerActive ? state.inner : state.outer); - } - if (!state.innerActive) { - for (var i = 0; i < others.length; ++i) { - var other = others[i]; - if (other.open === "\n") { - state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); - } - } - } else if (state.innerActive.close === "\n") { - state.innerActive = state.inner = null; - } - }, - - electricChars: outer.electricChars, - - innerMode: function(state) { - return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; - } - }; -}; - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.multiplexingMode = function(outer /*, others */) { + // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects + var others = Array.prototype.slice.call(arguments, 1); + + function indexOf(string, pattern, from, returnEnd) { + if (typeof pattern == "string") { + var found = string.indexOf(pattern, from); + return returnEnd && found > -1 ? found + pattern.length : found; + } + var m = pattern.exec(from ? string.slice(from) : string); + return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1; + } + + return { + startState: function() { + return { + outer: CodeMirror.startState(outer), + innerActive: null, + inner: null + }; + }, + + copyState: function(state) { + return { + outer: CodeMirror.copyState(outer, state.outer), + innerActive: state.innerActive, + inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) + }; + }, + + token: function(stream, state) { + if (!state.innerActive) { + var cutOff = Infinity, oldContent = stream.string; + for (var i = 0; i < others.length; ++i) { + var other = others[i]; + var found = indexOf(oldContent, other.open, stream.pos); + if (found == stream.pos) { + if (!other.parseDelimiters) stream.match(other.open); + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); + return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); + } else if (found != -1 && found < cutOff) { + cutOff = found; + } + } + if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); + var outerToken = outer.token(stream, state.outer); + if (cutOff != Infinity) stream.string = oldContent; + return outerToken; + } else { + var curInner = state.innerActive, oldContent = stream.string; + if (!curInner.close && stream.sol()) { + state.innerActive = state.inner = null; + return this.token(stream, state); + } + var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1; + if (found == stream.pos && !curInner.parseDelimiters) { + stream.match(curInner.close); + state.innerActive = state.inner = null; + return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close"); + } + if (found > -1) stream.string = oldContent.slice(0, found); + var innerToken = curInner.mode.token(stream, state.inner); + if (found > -1) stream.string = oldContent; + + if (found == stream.pos && curInner.parseDelimiters) + state.innerActive = state.inner = null; + + if (curInner.innerStyle) { + if (innerToken) innerToken = innerToken + " " + curInner.innerStyle; + else innerToken = curInner.innerStyle; + } + + return innerToken; + } + }, + + indent: function(state, textAfter) { + var mode = state.innerActive ? state.innerActive.mode : outer; + if (!mode.indent) return CodeMirror.Pass; + return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); + }, + + blankLine: function(state) { + var mode = state.innerActive ? state.innerActive.mode : outer; + if (mode.blankLine) { + mode.blankLine(state.innerActive ? state.inner : state.outer); + } + if (!state.innerActive) { + for (var i = 0; i < others.length; ++i) { + var other = others[i]; + if (other.open === "\n") { + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); + } + } + } else if (state.innerActive.close === "\n") { + state.innerActive = state.inner = null; + } + }, + + electricChars: outer.electricChars, + + innerMode: function(state) { + return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; + } + }; +}; + +}); diff --git a/shared/codemirror/addon/mode/multiplex_test.js b/shared/codemirror/addon/mode/multiplex_test.js index 24e5e67..f746139 100644 --- a/shared/codemirror/addon/mode/multiplex_test.js +++ b/shared/codemirror/addon/mode/multiplex_test.js @@ -1,33 +1,33 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function() { - CodeMirror.defineMode("markdown_with_stex", function(){ - var inner = CodeMirror.getMode({}, "stex"); - var outer = CodeMirror.getMode({}, "markdown"); - - var innerOptions = { - open: '$', - close: '$', - mode: inner, - delimStyle: 'delim', - innerStyle: 'inner' - }; - - return CodeMirror.multiplexingMode(outer, innerOptions); - }); - - var mode = CodeMirror.getMode({}, "markdown_with_stex"); - - function MT(name) { - test.mode( - name, - mode, - Array.prototype.slice.call(arguments, 1), - 'multiplexing'); - } - - MT( - "stexInsideMarkdown", - "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]"); -})(); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + CodeMirror.defineMode("markdown_with_stex", function(){ + var inner = CodeMirror.getMode({}, "stex"); + var outer = CodeMirror.getMode({}, "markdown"); + + var innerOptions = { + open: '$', + close: '$', + mode: inner, + delimStyle: 'delim', + innerStyle: 'inner' + }; + + return CodeMirror.multiplexingMode(outer, innerOptions); + }); + + var mode = CodeMirror.getMode({}, "markdown_with_stex"); + + function MT(name) { + test.mode( + name, + mode, + Array.prototype.slice.call(arguments, 1), + 'multiplexing'); + } + + MT( + "stexInsideMarkdown", + "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]"); +})(); diff --git a/shared/codemirror/addon/mode/overlay.js b/shared/codemirror/addon/mode/overlay.js index e1b9ed3..76fb722 100644 --- a/shared/codemirror/addon/mode/overlay.js +++ b/shared/codemirror/addon/mode/overlay.js @@ -1,85 +1,85 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Utility function that allows modes to be combined. The mode given -// as the base argument takes care of most of the normal mode -// functionality, but a second (typically simple) mode is used, which -// can override the style of text. Both modes get to parse all of the -// text, but when both assign a non-null style to a piece of code, the -// overlay wins, unless the combine argument was true and not overridden, -// or state.overlay.combineTokens was true, in which case the styles are -// combined. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.overlayMode = function(base, overlay, combine) { - return { - startState: function() { - return { - base: CodeMirror.startState(base), - overlay: CodeMirror.startState(overlay), - basePos: 0, baseCur: null, - overlayPos: 0, overlayCur: null, - streamSeen: null - }; - }, - copyState: function(state) { - return { - base: CodeMirror.copyState(base, state.base), - overlay: CodeMirror.copyState(overlay, state.overlay), - basePos: state.basePos, baseCur: null, - overlayPos: state.overlayPos, overlayCur: null - }; - }, - - token: function(stream, state) { - if (stream != state.streamSeen || - Math.min(state.basePos, state.overlayPos) < stream.start) { - state.streamSeen = stream; - state.basePos = state.overlayPos = stream.start; - } - - if (stream.start == state.basePos) { - state.baseCur = base.token(stream, state.base); - state.basePos = stream.pos; - } - if (stream.start == state.overlayPos) { - stream.pos = stream.start; - state.overlayCur = overlay.token(stream, state.overlay); - state.overlayPos = stream.pos; - } - stream.pos = Math.min(state.basePos, state.overlayPos); - - // state.overlay.combineTokens always takes precedence over combine, - // unless set to null - if (state.overlayCur == null) return state.baseCur; - else if (state.baseCur != null && - state.overlay.combineTokens || - combine && state.overlay.combineTokens == null) - return state.baseCur + " " + state.overlayCur; - else return state.overlayCur; - }, - - indent: base.indent && function(state, textAfter) { - return base.indent(state.base, textAfter); - }, - electricChars: base.electricChars, - - innerMode: function(state) { return {state: state.base, mode: base}; }, - - blankLine: function(state) { - if (base.blankLine) base.blankLine(state.base); - if (overlay.blankLine) overlay.blankLine(state.overlay); - } - }; -}; - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Utility function that allows modes to be combined. The mode given +// as the base argument takes care of most of the normal mode +// functionality, but a second (typically simple) mode is used, which +// can override the style of text. Both modes get to parse all of the +// text, but when both assign a non-null style to a piece of code, the +// overlay wins, unless the combine argument was true and not overridden, +// or state.overlay.combineTokens was true, in which case the styles are +// combined. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.overlayMode = function(base, overlay, combine) { + return { + startState: function() { + return { + base: CodeMirror.startState(base), + overlay: CodeMirror.startState(overlay), + basePos: 0, baseCur: null, + overlayPos: 0, overlayCur: null, + streamSeen: null + }; + }, + copyState: function(state) { + return { + base: CodeMirror.copyState(base, state.base), + overlay: CodeMirror.copyState(overlay, state.overlay), + basePos: state.basePos, baseCur: null, + overlayPos: state.overlayPos, overlayCur: null + }; + }, + + token: function(stream, state) { + if (stream != state.streamSeen || + Math.min(state.basePos, state.overlayPos) < stream.start) { + state.streamSeen = stream; + state.basePos = state.overlayPos = stream.start; + } + + if (stream.start == state.basePos) { + state.baseCur = base.token(stream, state.base); + state.basePos = stream.pos; + } + if (stream.start == state.overlayPos) { + stream.pos = stream.start; + state.overlayCur = overlay.token(stream, state.overlay); + state.overlayPos = stream.pos; + } + stream.pos = Math.min(state.basePos, state.overlayPos); + + // state.overlay.combineTokens always takes precedence over combine, + // unless set to null + if (state.overlayCur == null) return state.baseCur; + else if (state.baseCur != null && + state.overlay.combineTokens || + combine && state.overlay.combineTokens == null) + return state.baseCur + " " + state.overlayCur; + else return state.overlayCur; + }, + + indent: base.indent && function(state, textAfter) { + return base.indent(state.base, textAfter); + }, + electricChars: base.electricChars, + + innerMode: function(state) { return {state: state.base, mode: base}; }, + + blankLine: function(state) { + if (base.blankLine) base.blankLine(state.base); + if (overlay.blankLine) overlay.blankLine(state.overlay); + } + }; +}; + +}); diff --git a/shared/codemirror/addon/mode/simple.js b/shared/codemirror/addon/mode/simple.js index df66336..7acab6e 100644 --- a/shared/codemirror/addon/mode/simple.js +++ b/shared/codemirror/addon/mode/simple.js @@ -1,213 +1,213 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineSimpleMode = function(name, states) { - CodeMirror.defineMode(name, function(config) { - return CodeMirror.simpleMode(config, states); - }); - }; - - CodeMirror.simpleMode = function(config, states) { - ensureState(states, "start"); - var states_ = {}, meta = states.meta || {}, hasIndentation = false; - for (var state in states) if (state != meta && states.hasOwnProperty(state)) { - var list = states_[state] = [], orig = states[state]; - for (var i = 0; i < orig.length; i++) { - var data = orig[i]; - list.push(new Rule(data, states)); - if (data.indent || data.dedent) hasIndentation = true; - } - } - var mode = { - startState: function() { - return {state: "start", pending: null, - local: null, localState: null, - indent: hasIndentation ? [] : null}; - }, - copyState: function(state) { - var s = {state: state.state, pending: state.pending, - local: state.local, localState: null, - indent: state.indent && state.indent.slice(0)}; - if (state.localState) - s.localState = CodeMirror.copyState(state.local.mode, state.localState); - if (state.stack) - s.stack = state.stack.slice(0); - for (var pers = state.persistentStates; pers; pers = pers.next) - s.persistentStates = {mode: pers.mode, - spec: pers.spec, - state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state), - next: s.persistentStates}; - return s; - }, - token: tokenFunction(states_, config), - innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; }, - indent: indentFunction(states_, meta) - }; - if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop)) - mode[prop] = meta[prop]; - return mode; - }; - - function ensureState(states, name) { - if (!states.hasOwnProperty(name)) - throw new Error("Undefined state " + name + " in simple mode"); - } - - function toRegex(val, caret) { - if (!val) return /(?:)/; - var flags = ""; - if (val instanceof RegExp) { - if (val.ignoreCase) flags = "i"; - val = val.source; - } else { - val = String(val); - } - return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags); - } - - function asToken(val) { - if (!val) return null; - if (typeof val == "string") return val.replace(/\./g, " "); - var result = []; - for (var i = 0; i < val.length; i++) - result.push(val[i] && val[i].replace(/\./g, " ")); - return result; - } - - function Rule(data, states) { - if (data.next || data.push) ensureState(states, data.next || data.push); - this.regex = toRegex(data.regex); - this.token = asToken(data.token); - this.data = data; - } - - function tokenFunction(states, config) { - return function(stream, state) { - if (state.pending) { - var pend = state.pending.shift(); - if (state.pending.length == 0) state.pending = null; - stream.pos += pend.text.length; - return pend.token; - } - - if (state.local) { - if (state.local.end && stream.match(state.local.end)) { - var tok = state.local.endToken || null; - state.local = state.localState = null; - return tok; - } else { - var tok = state.local.mode.token(stream, state.localState), m; - if (state.local.endScan && (m = state.local.endScan.exec(stream.current()))) - stream.pos = stream.start + m.index; - return tok; - } - } - - var curState = states[state.state]; - for (var i = 0; i < curState.length; i++) { - var rule = curState[i]; - var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex); - if (matches) { - if (rule.data.next) { - state.state = rule.data.next; - } else if (rule.data.push) { - (state.stack || (state.stack = [])).push(state.state); - state.state = rule.data.push; - } else if (rule.data.pop && state.stack && state.stack.length) { - state.state = state.stack.pop(); - } - - if (rule.data.mode) - enterLocalMode(config, state, rule.data.mode, rule.token); - if (rule.data.indent) - state.indent.push(stream.indentation() + config.indentUnit); - if (rule.data.dedent) - state.indent.pop(); - if (matches.length > 2) { - state.pending = []; - for (var j = 2; j < matches.length; j++) - if (matches[j]) - state.pending.push({text: matches[j], token: rule.token[j - 1]}); - stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0)); - return rule.token[0]; - } else if (rule.token && rule.token.join) { - return rule.token[0]; - } else { - return rule.token; - } - } - } - stream.next(); - return null; - }; - } - - function cmp(a, b) { - if (a === b) return true; - if (!a || typeof a != "object" || !b || typeof b != "object") return false; - var props = 0; - for (var prop in a) if (a.hasOwnProperty(prop)) { - if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false; - props++; - } - for (var prop in b) if (b.hasOwnProperty(prop)) props--; - return props == 0; - } - - function enterLocalMode(config, state, spec, token) { - var pers; - if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next) - if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p; - var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec); - var lState = pers ? pers.state : CodeMirror.startState(mode); - if (spec.persistent && !pers) - state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates}; - - state.localState = lState; - state.local = {mode: mode, - end: spec.end && toRegex(spec.end), - endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false), - endToken: token && token.join ? token[token.length - 1] : token}; - } - - function indexOf(val, arr) { - for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true; - } - - function indentFunction(states, meta) { - return function(state, textAfter, line) { - if (state.local && state.local.mode.indent) - return state.local.mode.indent(state.localState, textAfter, line); - if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1) - return CodeMirror.Pass; - - var pos = state.indent.length - 1, rules = states[state.state]; - scan: for (;;) { - for (var i = 0; i < rules.length; i++) { - var rule = rules[i]; - if (rule.data.dedent && rule.data.dedentIfLineStart !== false) { - var m = rule.regex.exec(textAfter); - if (m && m[0]) { - pos--; - if (rule.next || rule.push) rules = states[rule.next || rule.push]; - textAfter = textAfter.slice(m[0].length); - continue scan; - } - } - } - break; - } - return pos < 0 ? 0 : state.indent[pos]; - }; - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineSimpleMode = function(name, states) { + CodeMirror.defineMode(name, function(config) { + return CodeMirror.simpleMode(config, states); + }); + }; + + CodeMirror.simpleMode = function(config, states) { + ensureState(states, "start"); + var states_ = {}, meta = states.meta || {}, hasIndentation = false; + for (var state in states) if (state != meta && states.hasOwnProperty(state)) { + var list = states_[state] = [], orig = states[state]; + for (var i = 0; i < orig.length; i++) { + var data = orig[i]; + list.push(new Rule(data, states)); + if (data.indent || data.dedent) hasIndentation = true; + } + } + var mode = { + startState: function() { + return {state: "start", pending: null, + local: null, localState: null, + indent: hasIndentation ? [] : null}; + }, + copyState: function(state) { + var s = {state: state.state, pending: state.pending, + local: state.local, localState: null, + indent: state.indent && state.indent.slice(0)}; + if (state.localState) + s.localState = CodeMirror.copyState(state.local.mode, state.localState); + if (state.stack) + s.stack = state.stack.slice(0); + for (var pers = state.persistentStates; pers; pers = pers.next) + s.persistentStates = {mode: pers.mode, + spec: pers.spec, + state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state), + next: s.persistentStates}; + return s; + }, + token: tokenFunction(states_, config), + innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; }, + indent: indentFunction(states_, meta) + }; + if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop)) + mode[prop] = meta[prop]; + return mode; + }; + + function ensureState(states, name) { + if (!states.hasOwnProperty(name)) + throw new Error("Undefined state " + name + " in simple mode"); + } + + function toRegex(val, caret) { + if (!val) return /(?:)/; + var flags = ""; + if (val instanceof RegExp) { + if (val.ignoreCase) flags = "i"; + val = val.source; + } else { + val = String(val); + } + return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags); + } + + function asToken(val) { + if (!val) return null; + if (typeof val == "string") return val.replace(/\./g, " "); + var result = []; + for (var i = 0; i < val.length; i++) + result.push(val[i] && val[i].replace(/\./g, " ")); + return result; + } + + function Rule(data, states) { + if (data.next || data.push) ensureState(states, data.next || data.push); + this.regex = toRegex(data.regex); + this.token = asToken(data.token); + this.data = data; + } + + function tokenFunction(states, config) { + return function(stream, state) { + if (state.pending) { + var pend = state.pending.shift(); + if (state.pending.length == 0) state.pending = null; + stream.pos += pend.text.length; + return pend.token; + } + + if (state.local) { + if (state.local.end && stream.match(state.local.end)) { + var tok = state.local.endToken || null; + state.local = state.localState = null; + return tok; + } else { + var tok = state.local.mode.token(stream, state.localState), m; + if (state.local.endScan && (m = state.local.endScan.exec(stream.current()))) + stream.pos = stream.start + m.index; + return tok; + } + } + + var curState = states[state.state]; + for (var i = 0; i < curState.length; i++) { + var rule = curState[i]; + var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex); + if (matches) { + if (rule.data.next) { + state.state = rule.data.next; + } else if (rule.data.push) { + (state.stack || (state.stack = [])).push(state.state); + state.state = rule.data.push; + } else if (rule.data.pop && state.stack && state.stack.length) { + state.state = state.stack.pop(); + } + + if (rule.data.mode) + enterLocalMode(config, state, rule.data.mode, rule.token); + if (rule.data.indent) + state.indent.push(stream.indentation() + config.indentUnit); + if (rule.data.dedent) + state.indent.pop(); + if (matches.length > 2) { + state.pending = []; + for (var j = 2; j < matches.length; j++) + if (matches[j]) + state.pending.push({text: matches[j], token: rule.token[j - 1]}); + stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0)); + return rule.token[0]; + } else if (rule.token && rule.token.join) { + return rule.token[0]; + } else { + return rule.token; + } + } + } + stream.next(); + return null; + }; + } + + function cmp(a, b) { + if (a === b) return true; + if (!a || typeof a != "object" || !b || typeof b != "object") return false; + var props = 0; + for (var prop in a) if (a.hasOwnProperty(prop)) { + if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false; + props++; + } + for (var prop in b) if (b.hasOwnProperty(prop)) props--; + return props == 0; + } + + function enterLocalMode(config, state, spec, token) { + var pers; + if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next) + if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p; + var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec); + var lState = pers ? pers.state : CodeMirror.startState(mode); + if (spec.persistent && !pers) + state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates}; + + state.localState = lState; + state.local = {mode: mode, + end: spec.end && toRegex(spec.end), + endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false), + endToken: token && token.join ? token[token.length - 1] : token}; + } + + function indexOf(val, arr) { + for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true; + } + + function indentFunction(states, meta) { + return function(state, textAfter, line) { + if (state.local && state.local.mode.indent) + return state.local.mode.indent(state.localState, textAfter, line); + if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1) + return CodeMirror.Pass; + + var pos = state.indent.length - 1, rules = states[state.state]; + scan: for (;;) { + for (var i = 0; i < rules.length; i++) { + var rule = rules[i]; + if (rule.data.dedent && rule.data.dedentIfLineStart !== false) { + var m = rule.regex.exec(textAfter); + if (m && m[0]) { + pos--; + if (rule.next || rule.push) rules = states[rule.next || rule.push]; + textAfter = textAfter.slice(m[0].length); + continue scan; + } + } + } + break; + } + return pos < 0 ? 0 : state.indent[pos]; + }; + } +}); diff --git a/shared/codemirror/addon/runmode/colorize.js b/shared/codemirror/addon/runmode/colorize.js index eb7060d..8317b87 100644 --- a/shared/codemirror/addon/runmode/colorize.js +++ b/shared/codemirror/addon/runmode/colorize.js @@ -1,40 +1,40 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./runmode")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./runmode"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; - - function textContent(node, out) { - if (node.nodeType == 3) return out.push(node.nodeValue); - for (var ch = node.firstChild; ch; ch = ch.nextSibling) { - textContent(ch, out); - if (isBlock.test(node.nodeType)) out.push("\n"); - } - } - - CodeMirror.colorize = function(collection, defaultMode) { - if (!collection) collection = document.body.getElementsByTagName("pre"); - - for (var i = 0; i < collection.length; ++i) { - var node = collection[i]; - var mode = node.getAttribute("data-lang") || defaultMode; - if (!mode) continue; - - var text = []; - textContent(node, text); - node.innerHTML = ""; - CodeMirror.runMode(text.join(""), mode, node); - - node.className += " cm-s-default"; - } - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./runmode")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./runmode"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; + + function textContent(node, out) { + if (node.nodeType == 3) return out.push(node.nodeValue); + for (var ch = node.firstChild; ch; ch = ch.nextSibling) { + textContent(ch, out); + if (isBlock.test(node.nodeType)) out.push("\n"); + } + } + + CodeMirror.colorize = function(collection, defaultMode) { + if (!collection) collection = document.body.getElementsByTagName("pre"); + + for (var i = 0; i < collection.length; ++i) { + var node = collection[i]; + var mode = node.getAttribute("data-lang") || defaultMode; + if (!mode) continue; + + var text = []; + textContent(node, text); + node.innerHTML = ""; + CodeMirror.runMode(text.join(""), mode, node); + + node.className += " cm-s-default"; + } + }; +}); diff --git a/shared/codemirror/addon/runmode/runmode-standalone.js b/shared/codemirror/addon/runmode/runmode-standalone.js index f4f352c..abe034b 100644 --- a/shared/codemirror/addon/runmode/runmode-standalone.js +++ b/shared/codemirror/addon/runmode/runmode-standalone.js @@ -1,157 +1,157 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -window.CodeMirror = {}; - -(function() { -"use strict"; - -function splitLines(string){ return string.split(/\r?\n|\r/); }; - -function StringStream(string) { - this.pos = this.start = 0; - this.string = string; - this.lineStart = 0; -} -StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == 0;}, - peek: function() {return this.string.charAt(this.pos) || null;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() {return this.start - this.lineStart;}, - indentation: function() {return 0;}, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } -}; -CodeMirror.StringStream = StringStream; - -CodeMirror.startState = function (mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; -}; - -var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; -CodeMirror.defineMode = function (name, mode) { - if (arguments.length > 2) - mode.dependencies = Array.prototype.slice.call(arguments, 2); - modes[name] = mode; -}; -CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; -CodeMirror.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - spec = mimeModes[spec.name]; - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; -}; -CodeMirror.getMode = function (options, spec) { - spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) throw new Error("Unknown mode: " + spec); - return mfactory(options, spec); -}; -CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min; -CodeMirror.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; -}); -CodeMirror.defineMIME("text/plain", "null"); - -CodeMirror.runMode = function (string, modespec, callback, options) { - var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec); - - if (callback.nodeType == 1) { - var tabSize = (options && options.tabSize) || 4; - var node = callback, col = 0; - node.innerHTML = ""; - callback = function (text, style) { - if (text == "\n") { - node.appendChild(document.createElement("br")); - col = 0; - return; - } - var content = ""; - // replace tabs - for (var pos = 0; ;) { - var idx = text.indexOf("\t", pos); - if (idx == -1) { - content += text.slice(pos); - col += text.length - pos; - break; - } else { - col += idx - pos; - content += text.slice(pos, idx); - var size = tabSize - col % tabSize; - col += size; - for (var i = 0; i < size; ++i) content += " "; - pos = idx + 1; - } - } - - if (style) { - var sp = node.appendChild(document.createElement("span")); - sp.className = "cm-" + style.replace(/ +/g, " cm-"); - sp.appendChild(document.createTextNode(content)); - } else { - node.appendChild(document.createTextNode(content)); - } - }; - } - - var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new CodeMirror.StringStream(lines[i]); - if (!stream.string && mode.blankLine) mode.blankLine(state); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; - } - } -}; -})(); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +window.CodeMirror = {}; + +(function() { +"use strict"; + +function splitLines(string){ return string.split(/\r?\n|\r/); }; + +function StringStream(string) { + this.pos = this.start = 0; + this.string = string; + this.lineStart = 0; +} +StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == 0;}, + peek: function() {return this.string.charAt(this.pos) || null;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() {return this.start - this.lineStart;}, + indentation: function() {return 0;}, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } +}; +CodeMirror.StringStream = StringStream; + +CodeMirror.startState = function (mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; +}; + +var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; +CodeMirror.defineMode = function (name, mode) { + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2); + modes[name] = mode; +}; +CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; +CodeMirror.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + spec = mimeModes[spec.name]; + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; +}; +CodeMirror.getMode = function (options, spec) { + spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) throw new Error("Unknown mode: " + spec); + return mfactory(options, spec); +}; +CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min; +CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; +}); +CodeMirror.defineMIME("text/plain", "null"); + +CodeMirror.runMode = function (string, modespec, callback, options) { + var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec); + + if (callback.nodeType == 1) { + var tabSize = (options && options.tabSize) || 4; + var node = callback, col = 0; + node.innerHTML = ""; + callback = function (text, style) { + if (text == "\n") { + node.appendChild(document.createElement("br")); + col = 0; + return; + } + var content = ""; + // replace tabs + for (var pos = 0; ;) { + var idx = text.indexOf("\t", pos); + if (idx == -1) { + content += text.slice(pos); + col += text.length - pos; + break; + } else { + col += idx - pos; + content += text.slice(pos, idx); + var size = tabSize - col % tabSize; + col += size; + for (var i = 0; i < size; ++i) content += " "; + pos = idx + 1; + } + } + + if (style) { + var sp = node.appendChild(document.createElement("span")); + sp.className = "cm-" + style.replace(/ +/g, " cm-"); + sp.appendChild(document.createTextNode(content)); + } else { + node.appendChild(document.createTextNode(content)); + } + }; + } + + var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) callback("\n"); + var stream = new CodeMirror.StringStream(lines[i]); + if (!stream.string && mode.blankLine) mode.blankLine(state); + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state); + stream.start = stream.pos; + } + } +}; +})(); diff --git a/shared/codemirror/addon/runmode/runmode.js b/shared/codemirror/addon/runmode/runmode.js index a51c6d0..4a5b1fc 100644 --- a/shared/codemirror/addon/runmode/runmode.js +++ b/shared/codemirror/addon/runmode/runmode.js @@ -1,72 +1,72 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.runMode = function(string, modespec, callback, options) { - var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); - var ie = /MSIE \d/.test(navigator.userAgent); - var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); - - if (callback.appendChild) { - var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; - var node = callback, col = 0; - node.innerHTML = ""; - callback = function(text, style) { - if (text == "\n") { - // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. - // Emitting a carriage return makes everything ok. - node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); - col = 0; - return; - } - var content = ""; - // replace tabs - for (var pos = 0;;) { - var idx = text.indexOf("\t", pos); - if (idx == -1) { - content += text.slice(pos); - col += text.length - pos; - break; - } else { - col += idx - pos; - content += text.slice(pos, idx); - var size = tabSize - col % tabSize; - col += size; - for (var i = 0; i < size; ++i) content += " "; - pos = idx + 1; - } - } - - if (style) { - var sp = node.appendChild(document.createElement("span")); - sp.className = "cm-" + style.replace(/ +/g, " cm-"); - sp.appendChild(document.createTextNode(content)); - } else { - node.appendChild(document.createTextNode(content)); - } - }; - } - - var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new CodeMirror.StringStream(lines[i]); - if (!stream.string && mode.blankLine) mode.blankLine(state); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; - } - } -}; - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.runMode = function(string, modespec, callback, options) { + var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); + var ie = /MSIE \d/.test(navigator.userAgent); + var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); + + if (callback.appendChild) { + var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; + var node = callback, col = 0; + node.innerHTML = ""; + callback = function(text, style) { + if (text == "\n") { + // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. + // Emitting a carriage return makes everything ok. + node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); + col = 0; + return; + } + var content = ""; + // replace tabs + for (var pos = 0;;) { + var idx = text.indexOf("\t", pos); + if (idx == -1) { + content += text.slice(pos); + col += text.length - pos; + break; + } else { + col += idx - pos; + content += text.slice(pos, idx); + var size = tabSize - col % tabSize; + col += size; + for (var i = 0; i < size; ++i) content += " "; + pos = idx + 1; + } + } + + if (style) { + var sp = node.appendChild(document.createElement("span")); + sp.className = "cm-" + style.replace(/ +/g, " cm-"); + sp.appendChild(document.createTextNode(content)); + } else { + node.appendChild(document.createTextNode(content)); + } + }; + } + + var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) callback("\n"); + var stream = new CodeMirror.StringStream(lines[i]); + if (!stream.string && mode.blankLine) mode.blankLine(state); + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state); + stream.start = stream.pos; + } + } +}; + +}); diff --git a/shared/codemirror/addon/runmode/runmode.node.js b/shared/codemirror/addon/runmode/runmode.node.js index b22a518..76dd159 100644 --- a/shared/codemirror/addon/runmode/runmode.node.js +++ b/shared/codemirror/addon/runmode/runmode.node.js @@ -1,179 +1,179 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -/* Just enough of CodeMirror to run runMode under node.js */ - -function splitLines(string){return string.split(/\r\n?|\n/);}; - -// Counts the column offset in a string, taking tabs into account. -// Used mostly to find indentation. -var countColumn = function(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) end = string.length; - } - for (var i = startIndex || 0, n = startValue || 0;;) { - var nextTab = string.indexOf("\t", i); - if (nextTab < 0 || nextTab >= end) - return n + (end - i); - n += nextTab - i; - n += tabSize - (n % tabSize); - i = nextTab + 1; - } -}; - -function StringStream(string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; -}; - -StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == this.lineStart;}, - peek: function() {return this.string.charAt(this.pos) || undefined;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - indentation: function() { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } -}; -exports.StringStream = StringStream; - -exports.startState = function(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; -}; - -var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; -exports.defineMode = function(name, mode) { - if (arguments.length > 2) - mode.dependencies = Array.prototype.slice.call(arguments, 2); - modes[name] = mode; -}; -exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; - -exports.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; -}); -exports.defineMIME("text/plain", "null"); - -exports.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - spec = mimeModes[spec.name]; - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; -}; - -function copyObj(obj, target, overwrite) { - if (!target) target = {}; - for (var prop in obj) - if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) - target[prop] = obj[prop]; - return target; -} - -// This can be used to attach properties to mode objects from -// outside the actual mode definition. -var modeExtensions = exports.modeExtensions = {}; -exports.extendMode = function(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); -}; - -exports.getMode = function(options, spec) { - var spec = exports.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) return exports.getMode(options, "text/plain"); - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) continue; - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - if (spec.helperType) modeObj.helperType = spec.helperType; - if (spec.modeProps) for (var prop in spec.modeProps) - modeObj[prop] = spec.modeProps[prop]; - - return modeObj; -}; -exports.registerHelper = exports.registerGlobalHelper = Math.min; - -exports.runMode = function(string, modespec, callback, options) { - var mode = exports.getMode({indentUnit: 2}, modespec); - var lines = splitLines(string), state = (options && options.state) || exports.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new exports.StringStream(lines[i]); - if (!stream.string && mode.blankLine) mode.blankLine(state); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; - } - } -}; - -require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]; -require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")]; +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/* Just enough of CodeMirror to run runMode under node.js */ + +function splitLines(string){return string.split(/\r\n?|\n/);}; + +// Counts the column offset in a string, taking tabs into account. +// Used mostly to find indentation. +var countColumn = function(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + return n + (end - i); + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } +}; + +function StringStream(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; +}; + +StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == this.lineStart;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + indentation: function() { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } +}; +exports.StringStream = StringStream; + +exports.startState = function(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; +}; + +var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; +exports.defineMode = function(name, mode) { + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2); + modes[name] = mode; +}; +exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; + +exports.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; +}); +exports.defineMIME("text/plain", "null"); + +exports.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + spec = mimeModes[spec.name]; + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; +}; + +function copyObj(obj, target, overwrite) { + if (!target) target = {}; + for (var prop in obj) + if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + target[prop] = obj[prop]; + return target; +} + +// This can be used to attach properties to mode objects from +// outside the actual mode definition. +var modeExtensions = exports.modeExtensions = {}; +exports.extendMode = function(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); +}; + +exports.getMode = function(options, spec) { + var spec = exports.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return exports.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) modeObj.helperType = spec.helperType; + if (spec.modeProps) for (var prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop]; + + return modeObj; +}; +exports.registerHelper = exports.registerGlobalHelper = Math.min; + +exports.runMode = function(string, modespec, callback, options) { + var mode = exports.getMode({indentUnit: 2}, modespec); + var lines = splitLines(string), state = (options && options.state) || exports.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) callback("\n"); + var stream = new exports.StringStream(lines[i]); + if (!stream.string && mode.blankLine) mode.blankLine(state); + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state); + stream.start = stream.pos; + } + } +}; + +require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]; +require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")]; diff --git a/shared/codemirror/addon/scroll/annotatescrollbar.js b/shared/codemirror/addon/scroll/annotatescrollbar.js index 5e748e8..59d2338 100644 --- a/shared/codemirror/addon/scroll/annotatescrollbar.js +++ b/shared/codemirror/addon/scroll/annotatescrollbar.js @@ -1,118 +1,118 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineExtension("annotateScrollbar", function(options) { - if (typeof options == "string") options = {className: options}; - return new Annotation(this, options); - }); - - CodeMirror.defineOption("scrollButtonHeight", 0); - - function Annotation(cm, options) { - this.cm = cm; - this.options = options; - this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight"); - this.annotations = []; - this.doRedraw = this.doUpdate = null; - this.div = cm.getWrapperElement().appendChild(document.createElement("div")); - this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none"; - this.computeScale(); - - function scheduleRedraw(delay) { - clearTimeout(self.doRedraw); - self.doRedraw = setTimeout(function() { self.redraw(); }, delay); - } - - var self = this; - cm.on("refresh", this.resizeHandler = function() { - clearTimeout(self.doUpdate); - self.doUpdate = setTimeout(function() { - if (self.computeScale()) scheduleRedraw(20); - }, 100); - }); - cm.on("markerAdded", this.resizeHandler); - cm.on("markerCleared", this.resizeHandler); - if (options.listenForChanges !== false) - cm.on("change", this.changeHandler = function() { - scheduleRedraw(250); - }); - } - - Annotation.prototype.computeScale = function() { - var cm = this.cm; - var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) / - cm.getScrollerElement().scrollHeight - if (hScale != this.hScale) { - this.hScale = hScale; - return true; - } - }; - - Annotation.prototype.update = function(annotations) { - this.annotations = annotations; - this.redraw(); - }; - - Annotation.prototype.redraw = function(compute) { - if (compute !== false) this.computeScale(); - var cm = this.cm, hScale = this.hScale; - - var frag = document.createDocumentFragment(), anns = this.annotations; - - var wrapping = cm.getOption("lineWrapping"); - var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; - var curLine = null, curLineObj = null; - function getY(pos, top) { - if (curLine != pos.line) { - curLine = pos.line; - curLineObj = cm.getLineHandle(curLine); - } - if (wrapping && curLineObj.height > singleLineH) - return cm.charCoords(pos, "local")[top ? "top" : "bottom"]; - var topY = cm.heightAtLine(curLineObj, "local"); - return topY + (top ? 0 : curLineObj.height); - } - - if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) { - var ann = anns[i]; - var top = nextTop || getY(ann.from, true) * hScale; - var bottom = getY(ann.to, false) * hScale; - while (i < anns.length - 1) { - nextTop = getY(anns[i + 1].from, true) * hScale; - if (nextTop > bottom + .9) break; - ann = anns[++i]; - bottom = getY(ann.to, false) * hScale; - } - if (bottom == top) continue; - var height = Math.max(bottom - top, 3); - - var elt = frag.appendChild(document.createElement("div")); - elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " - + (top + this.buttonHeight) + "px; height: " + height + "px"; - elt.className = this.options.className; - if (ann.id) { - elt.setAttribute("annotation-id", ann.id); - } - } - this.div.textContent = ""; - this.div.appendChild(frag); - }; - - Annotation.prototype.clear = function() { - this.cm.off("refresh", this.resizeHandler); - this.cm.off("markerAdded", this.resizeHandler); - this.cm.off("markerCleared", this.resizeHandler); - if (this.changeHandler) this.cm.off("change", this.changeHandler); - this.div.parentNode.removeChild(this.div); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineExtension("annotateScrollbar", function(options) { + if (typeof options == "string") options = {className: options}; + return new Annotation(this, options); + }); + + CodeMirror.defineOption("scrollButtonHeight", 0); + + function Annotation(cm, options) { + this.cm = cm; + this.options = options; + this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight"); + this.annotations = []; + this.doRedraw = this.doUpdate = null; + this.div = cm.getWrapperElement().appendChild(document.createElement("div")); + this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none"; + this.computeScale(); + + function scheduleRedraw(delay) { + clearTimeout(self.doRedraw); + self.doRedraw = setTimeout(function() { self.redraw(); }, delay); + } + + var self = this; + cm.on("refresh", this.resizeHandler = function() { + clearTimeout(self.doUpdate); + self.doUpdate = setTimeout(function() { + if (self.computeScale()) scheduleRedraw(20); + }, 100); + }); + cm.on("markerAdded", this.resizeHandler); + cm.on("markerCleared", this.resizeHandler); + if (options.listenForChanges !== false) + cm.on("change", this.changeHandler = function() { + scheduleRedraw(250); + }); + } + + Annotation.prototype.computeScale = function() { + var cm = this.cm; + var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) / + cm.getScrollerElement().scrollHeight + if (hScale != this.hScale) { + this.hScale = hScale; + return true; + } + }; + + Annotation.prototype.update = function(annotations) { + this.annotations = annotations; + this.redraw(); + }; + + Annotation.prototype.redraw = function(compute) { + if (compute !== false) this.computeScale(); + var cm = this.cm, hScale = this.hScale; + + var frag = document.createDocumentFragment(), anns = this.annotations; + + var wrapping = cm.getOption("lineWrapping"); + var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; + var curLine = null, curLineObj = null; + function getY(pos, top) { + if (curLine != pos.line) { + curLine = pos.line; + curLineObj = cm.getLineHandle(curLine); + } + if (wrapping && curLineObj.height > singleLineH) + return cm.charCoords(pos, "local")[top ? "top" : "bottom"]; + var topY = cm.heightAtLine(curLineObj, "local"); + return topY + (top ? 0 : curLineObj.height); + } + + if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) { + var ann = anns[i]; + var top = nextTop || getY(ann.from, true) * hScale; + var bottom = getY(ann.to, false) * hScale; + while (i < anns.length - 1) { + nextTop = getY(anns[i + 1].from, true) * hScale; + if (nextTop > bottom + .9) break; + ann = anns[++i]; + bottom = getY(ann.to, false) * hScale; + } + if (bottom == top) continue; + var height = Math.max(bottom - top, 3); + + var elt = frag.appendChild(document.createElement("div")); + elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " + + (top + this.buttonHeight) + "px; height: " + height + "px"; + elt.className = this.options.className; + if (ann.id) { + elt.setAttribute("annotation-id", ann.id); + } + } + this.div.textContent = ""; + this.div.appendChild(frag); + }; + + Annotation.prototype.clear = function() { + this.cm.off("refresh", this.resizeHandler); + this.cm.off("markerAdded", this.resizeHandler); + this.cm.off("markerCleared", this.resizeHandler); + if (this.changeHandler) this.cm.off("change", this.changeHandler); + this.div.parentNode.removeChild(this.div); + }; +}); diff --git a/shared/codemirror/addon/scroll/scrollpastend.js b/shared/codemirror/addon/scroll/scrollpastend.js index 008ae4c..22b8093 100644 --- a/shared/codemirror/addon/scroll/scrollpastend.js +++ b/shared/codemirror/addon/scroll/scrollpastend.js @@ -1,46 +1,46 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.off("change", onChange); - cm.off("refresh", updateBottomMargin); - cm.display.lineSpace.parentNode.style.paddingBottom = ""; - cm.state.scrollPastEndPadding = null; - } - if (val) { - cm.on("change", onChange); - cm.on("refresh", updateBottomMargin); - updateBottomMargin(cm); - } - }); - - function onChange(cm, change) { - if (CodeMirror.changeEnd(change).line == cm.lastLine()) - updateBottomMargin(cm); - } - - function updateBottomMargin(cm) { - var padding = ""; - if (cm.lineCount() > 1) { - var totalH = cm.display.scroller.clientHeight - 30, - lastLineH = cm.getLineHandle(cm.lastLine()).height; - padding = (totalH - lastLineH) + "px"; - } - if (cm.state.scrollPastEndPadding != padding) { - cm.state.scrollPastEndPadding = padding; - cm.display.lineSpace.parentNode.style.paddingBottom = padding; - cm.setSize(); - } - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.off("change", onChange); + cm.off("refresh", updateBottomMargin); + cm.display.lineSpace.parentNode.style.paddingBottom = ""; + cm.state.scrollPastEndPadding = null; + } + if (val) { + cm.on("change", onChange); + cm.on("refresh", updateBottomMargin); + updateBottomMargin(cm); + } + }); + + function onChange(cm, change) { + if (CodeMirror.changeEnd(change).line == cm.lastLine()) + updateBottomMargin(cm); + } + + function updateBottomMargin(cm) { + var padding = ""; + if (cm.lineCount() > 1) { + var totalH = cm.display.scroller.clientHeight - 30, + lastLineH = cm.getLineHandle(cm.lastLine()).height; + padding = (totalH - lastLineH) + "px"; + } + if (cm.state.scrollPastEndPadding != padding) { + cm.state.scrollPastEndPadding = padding; + cm.display.lineSpace.parentNode.style.paddingBottom = padding; + cm.setSize(); + } + } +}); diff --git a/shared/codemirror/addon/scroll/simplescrollbars.css b/shared/codemirror/addon/scroll/simplescrollbars.css index 5eea7aa..cf273db 100644 --- a/shared/codemirror/addon/scroll/simplescrollbars.css +++ b/shared/codemirror/addon/scroll/simplescrollbars.css @@ -1,66 +1,66 @@ -.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div { - position: absolute; - background: #ccc; - -moz-box-sizing: border-box; - box-sizing: border-box; - border: 1px solid #bbb; - border-radius: 2px; -} - -.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical { - position: absolute; - z-index: 6; - background: #eee; -} - -.CodeMirror-simplescroll-horizontal { - bottom: 0; left: 0; - height: 8px; -} -.CodeMirror-simplescroll-horizontal div { - bottom: 0; - height: 100%; -} - -.CodeMirror-simplescroll-vertical { - right: 0; top: 0; - width: 8px; -} -.CodeMirror-simplescroll-vertical div { - right: 0; - width: 100%; -} - - -.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler { - display: none; -} - -.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div { - position: absolute; - background: #bcd; - border-radius: 3px; -} - -.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical { - position: absolute; - z-index: 6; -} - -.CodeMirror-overlayscroll-horizontal { - bottom: 0; left: 0; - height: 6px; -} -.CodeMirror-overlayscroll-horizontal div { - bottom: 0; - height: 100%; -} - -.CodeMirror-overlayscroll-vertical { - right: 0; top: 0; - width: 6px; -} -.CodeMirror-overlayscroll-vertical div { - right: 0; - width: 100%; -} +.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div { + position: absolute; + background: #ccc; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 1px solid #bbb; + border-radius: 2px; +} + +.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical { + position: absolute; + z-index: 6; + background: #eee; +} + +.CodeMirror-simplescroll-horizontal { + bottom: 0; left: 0; + height: 8px; +} +.CodeMirror-simplescroll-horizontal div { + bottom: 0; + height: 100%; +} + +.CodeMirror-simplescroll-vertical { + right: 0; top: 0; + width: 8px; +} +.CodeMirror-simplescroll-vertical div { + right: 0; + width: 100%; +} + + +.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler { + display: none; +} + +.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div { + position: absolute; + background: #bcd; + border-radius: 3px; +} + +.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical { + position: absolute; + z-index: 6; +} + +.CodeMirror-overlayscroll-horizontal { + bottom: 0; left: 0; + height: 6px; +} +.CodeMirror-overlayscroll-horizontal div { + bottom: 0; + height: 100%; +} + +.CodeMirror-overlayscroll-vertical { + right: 0; top: 0; + width: 6px; +} +.CodeMirror-overlayscroll-vertical div { + right: 0; + width: 100%; +} diff --git a/shared/codemirror/addon/scroll/simplescrollbars.js b/shared/codemirror/addon/scroll/simplescrollbars.js index 32ba2f3..ead7b51 100644 --- a/shared/codemirror/addon/scroll/simplescrollbars.js +++ b/shared/codemirror/addon/scroll/simplescrollbars.js @@ -1,149 +1,149 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function Bar(cls, orientation, scroll) { - this.orientation = orientation; - this.scroll = scroll; - this.screen = this.total = this.size = 1; - this.pos = 0; - - this.node = document.createElement("div"); - this.node.className = cls + "-" + orientation; - this.inner = this.node.appendChild(document.createElement("div")); - - var self = this; - CodeMirror.on(this.inner, "mousedown", function(e) { - if (e.which != 1) return; - CodeMirror.e_preventDefault(e); - var axis = self.orientation == "horizontal" ? "pageX" : "pageY"; - var start = e[axis], startpos = self.pos; - function done() { - CodeMirror.off(document, "mousemove", move); - CodeMirror.off(document, "mouseup", done); - } - function move(e) { - if (e.which != 1) return done(); - self.moveTo(startpos + (e[axis] - start) * (self.total / self.size)); - } - CodeMirror.on(document, "mousemove", move); - CodeMirror.on(document, "mouseup", done); - }); - - CodeMirror.on(this.node, "click", function(e) { - CodeMirror.e_preventDefault(e); - var innerBox = self.inner.getBoundingClientRect(), where; - if (self.orientation == "horizontal") - where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0; - else - where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0; - self.moveTo(self.pos + where * self.screen); - }); - - function onWheel(e) { - var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"]; - var oldPos = self.pos; - self.moveTo(self.pos + moved); - if (self.pos != oldPos) CodeMirror.e_preventDefault(e); - } - CodeMirror.on(this.node, "mousewheel", onWheel); - CodeMirror.on(this.node, "DOMMouseScroll", onWheel); - } - - Bar.prototype.setPos = function(pos) { - if (pos < 0) pos = 0; - if (pos > this.total - this.screen) pos = this.total - this.screen; - if (pos == this.pos) return false; - this.pos = pos; - this.inner.style[this.orientation == "horizontal" ? "left" : "top"] = - (pos * (this.size / this.total)) + "px"; - return true - }; - - Bar.prototype.moveTo = function(pos) { - if (this.setPos(pos)) this.scroll(pos, this.orientation); - } - - var minButtonSize = 10; - - Bar.prototype.update = function(scrollSize, clientSize, barSize) { - this.screen = clientSize; - this.total = scrollSize; - this.size = barSize; - - var buttonSize = this.screen * (this.size / this.total); - if (buttonSize < minButtonSize) { - this.size -= minButtonSize - buttonSize; - buttonSize = minButtonSize; - } - this.inner.style[this.orientation == "horizontal" ? "width" : "height"] = - buttonSize + "px"; - this.setPos(this.pos); - }; - - function SimpleScrollbars(cls, place, scroll) { - this.addClass = cls; - this.horiz = new Bar(cls, "horizontal", scroll); - place(this.horiz.node); - this.vert = new Bar(cls, "vertical", scroll); - place(this.vert.node); - this.width = null; - } - - SimpleScrollbars.prototype.update = function(measure) { - if (this.width == null) { - var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle; - if (style) this.width = parseInt(style.height); - } - var width = this.width || 0; - - var needsH = measure.scrollWidth > measure.clientWidth + 1; - var needsV = measure.scrollHeight > measure.clientHeight + 1; - this.vert.node.style.display = needsV ? "block" : "none"; - this.horiz.node.style.display = needsH ? "block" : "none"; - - if (needsV) { - this.vert.update(measure.scrollHeight, measure.clientHeight, - measure.viewHeight - (needsH ? width : 0)); - this.vert.node.style.bottom = needsH ? width + "px" : "0"; - } - if (needsH) { - this.horiz.update(measure.scrollWidth, measure.clientWidth, - measure.viewWidth - (needsV ? width : 0) - measure.barLeft); - this.horiz.node.style.right = needsV ? width + "px" : "0"; - this.horiz.node.style.left = measure.barLeft + "px"; - } - - return {right: needsV ? width : 0, bottom: needsH ? width : 0}; - }; - - SimpleScrollbars.prototype.setScrollTop = function(pos) { - this.vert.setPos(pos); - }; - - SimpleScrollbars.prototype.setScrollLeft = function(pos) { - this.horiz.setPos(pos); - }; - - SimpleScrollbars.prototype.clear = function() { - var parent = this.horiz.node.parentNode; - parent.removeChild(this.horiz.node); - parent.removeChild(this.vert.node); - }; - - CodeMirror.scrollbarModel.simple = function(place, scroll) { - return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll); - }; - CodeMirror.scrollbarModel.overlay = function(place, scroll) { - return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function Bar(cls, orientation, scroll) { + this.orientation = orientation; + this.scroll = scroll; + this.screen = this.total = this.size = 1; + this.pos = 0; + + this.node = document.createElement("div"); + this.node.className = cls + "-" + orientation; + this.inner = this.node.appendChild(document.createElement("div")); + + var self = this; + CodeMirror.on(this.inner, "mousedown", function(e) { + if (e.which != 1) return; + CodeMirror.e_preventDefault(e); + var axis = self.orientation == "horizontal" ? "pageX" : "pageY"; + var start = e[axis], startpos = self.pos; + function done() { + CodeMirror.off(document, "mousemove", move); + CodeMirror.off(document, "mouseup", done); + } + function move(e) { + if (e.which != 1) return done(); + self.moveTo(startpos + (e[axis] - start) * (self.total / self.size)); + } + CodeMirror.on(document, "mousemove", move); + CodeMirror.on(document, "mouseup", done); + }); + + CodeMirror.on(this.node, "click", function(e) { + CodeMirror.e_preventDefault(e); + var innerBox = self.inner.getBoundingClientRect(), where; + if (self.orientation == "horizontal") + where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0; + else + where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0; + self.moveTo(self.pos + where * self.screen); + }); + + function onWheel(e) { + var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"]; + var oldPos = self.pos; + self.moveTo(self.pos + moved); + if (self.pos != oldPos) CodeMirror.e_preventDefault(e); + } + CodeMirror.on(this.node, "mousewheel", onWheel); + CodeMirror.on(this.node, "DOMMouseScroll", onWheel); + } + + Bar.prototype.setPos = function(pos) { + if (pos < 0) pos = 0; + if (pos > this.total - this.screen) pos = this.total - this.screen; + if (pos == this.pos) return false; + this.pos = pos; + this.inner.style[this.orientation == "horizontal" ? "left" : "top"] = + (pos * (this.size / this.total)) + "px"; + return true + }; + + Bar.prototype.moveTo = function(pos) { + if (this.setPos(pos)) this.scroll(pos, this.orientation); + } + + var minButtonSize = 10; + + Bar.prototype.update = function(scrollSize, clientSize, barSize) { + this.screen = clientSize; + this.total = scrollSize; + this.size = barSize; + + var buttonSize = this.screen * (this.size / this.total); + if (buttonSize < minButtonSize) { + this.size -= minButtonSize - buttonSize; + buttonSize = minButtonSize; + } + this.inner.style[this.orientation == "horizontal" ? "width" : "height"] = + buttonSize + "px"; + this.setPos(this.pos); + }; + + function SimpleScrollbars(cls, place, scroll) { + this.addClass = cls; + this.horiz = new Bar(cls, "horizontal", scroll); + place(this.horiz.node); + this.vert = new Bar(cls, "vertical", scroll); + place(this.vert.node); + this.width = null; + } + + SimpleScrollbars.prototype.update = function(measure) { + if (this.width == null) { + var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle; + if (style) this.width = parseInt(style.height); + } + var width = this.width || 0; + + var needsH = measure.scrollWidth > measure.clientWidth + 1; + var needsV = measure.scrollHeight > measure.clientHeight + 1; + this.vert.node.style.display = needsV ? "block" : "none"; + this.horiz.node.style.display = needsH ? "block" : "none"; + + if (needsV) { + this.vert.update(measure.scrollHeight, measure.clientHeight, + measure.viewHeight - (needsH ? width : 0)); + this.vert.node.style.bottom = needsH ? width + "px" : "0"; + } + if (needsH) { + this.horiz.update(measure.scrollWidth, measure.clientWidth, + measure.viewWidth - (needsV ? width : 0) - measure.barLeft); + this.horiz.node.style.right = needsV ? width + "px" : "0"; + this.horiz.node.style.left = measure.barLeft + "px"; + } + + return {right: needsV ? width : 0, bottom: needsH ? width : 0}; + }; + + SimpleScrollbars.prototype.setScrollTop = function(pos) { + this.vert.setPos(pos); + }; + + SimpleScrollbars.prototype.setScrollLeft = function(pos) { + this.horiz.setPos(pos); + }; + + SimpleScrollbars.prototype.clear = function() { + var parent = this.horiz.node.parentNode; + parent.removeChild(this.horiz.node); + parent.removeChild(this.vert.node); + }; + + CodeMirror.scrollbarModel.simple = function(place, scroll) { + return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll); + }; + CodeMirror.scrollbarModel.overlay = function(place, scroll) { + return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll); + }; +}); diff --git a/shared/codemirror/addon/search/jump-to-line.js b/shared/codemirror/addon/search/jump-to-line.js index 8b599cb..27a86d6 100644 --- a/shared/codemirror/addon/search/jump-to-line.js +++ b/shared/codemirror/addon/search/jump-to-line.js @@ -1,49 +1,49 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Defines jumpToLine command. Uses dialog.js if present. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../dialog/dialog")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../dialog/dialog"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function dialog(cm, text, shortText, deflt, f) { - if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); - else f(prompt(shortText, deflt)); - } - - var jumpDialog = - 'Jump to line: (Use line:column or scroll% syntax)'; - - function interpretLine(cm, string) { - var num = Number(string) - if (/^[-+]/.test(string)) return cm.getCursor().line + num - else return num - 1 - } - - CodeMirror.commands.jumpToLine = function(cm) { - var cur = cm.getCursor(); - dialog(cm, jumpDialog, "Jump to line:", (cur.line + 1) + ":" + cur.ch, function(posStr) { - if (!posStr) return; - - var match; - if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) { - cm.setCursor(interpretLine(cm, match[1]), Number(match[2])) - } else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) { - var line = Math.round(cm.lineCount() * Number(match[1]) / 100); - if (/^[-+]/.test(match[1])) line = cur.line + line + 1; - cm.setCursor(line - 1, cur.ch); - } else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) { - cm.setCursor(interpretLine(cm, match[1]), cur.ch); - } - }); - }; - - CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine"; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Defines jumpToLine command. Uses dialog.js if present. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../dialog/dialog")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../dialog/dialog"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function dialog(cm, text, shortText, deflt, f) { + if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); + else f(prompt(shortText, deflt)); + } + + var jumpDialog = + 'Jump to line: (Use line:column or scroll% syntax)'; + + function interpretLine(cm, string) { + var num = Number(string) + if (/^[-+]/.test(string)) return cm.getCursor().line + num + else return num - 1 + } + + CodeMirror.commands.jumpToLine = function(cm) { + var cur = cm.getCursor(); + dialog(cm, jumpDialog, "Jump to line:", (cur.line + 1) + ":" + cur.ch, function(posStr) { + if (!posStr) return; + + var match; + if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) { + cm.setCursor(interpretLine(cm, match[1]), Number(match[2])) + } else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) { + var line = Math.round(cm.lineCount() * Number(match[1]) / 100); + if (/^[-+]/.test(match[1])) line = cur.line + line + 1; + cm.setCursor(line - 1, cur.ch); + } else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) { + cm.setCursor(interpretLine(cm, match[1]), cur.ch); + } + }); + }; + + CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine"; +}); diff --git a/shared/codemirror/addon/search/match-highlighter.js b/shared/codemirror/addon/search/match-highlighter.js index 2c2914a..99d3d39 100644 --- a/shared/codemirror/addon/search/match-highlighter.js +++ b/shared/codemirror/addon/search/match-highlighter.js @@ -1,146 +1,146 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Highlighting text that matches the selection -// -// Defines an option highlightSelectionMatches, which, when enabled, -// will style strings that match the selection throughout the -// document. -// -// The option can be set to true to simply enable it, or to a -// {minChars, style, wordsOnly, showToken, delay} object to explicitly -// configure it. minChars is the minimum amount of characters that should be -// selected for the behavior to occur, and style is the token style to -// apply to the matches. This will be prefixed by "cm-" to create an -// actual CSS class name. If wordsOnly is enabled, the matches will be -// highlighted only if the selected text is a word. showToken, when enabled, -// will cause the current token to be highlighted when nothing is selected. -// delay is used to specify how much time to wait, in milliseconds, before -// highlighting the matches. If annotateScrollbar is enabled, the occurences -// will be highlighted on the scrollbar via the matchesonscrollbar addon. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./matchesonscrollbar")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./matchesonscrollbar"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var defaults = { - style: "matchhighlight", - minChars: 2, - delay: 100, - wordsOnly: false, - annotateScrollbar: false, - showToken: false, - trim: true - } - - function State(options) { - this.options = {} - for (var name in defaults) - this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name] - this.overlay = this.timeout = null; - this.matchesonscroll = null; - } - - CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - removeOverlay(cm); - clearTimeout(cm.state.matchHighlighter.timeout); - cm.state.matchHighlighter = null; - cm.off("cursorActivity", cursorActivity); - } - if (val) { - cm.state.matchHighlighter = new State(val); - highlightMatches(cm); - cm.on("cursorActivity", cursorActivity); - } - }); - - function cursorActivity(cm) { - var state = cm.state.matchHighlighter; - clearTimeout(state.timeout); - state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay); - } - - function addOverlay(cm, query, hasBoundary, style) { - var state = cm.state.matchHighlighter; - cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style)); - if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) { - var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query; - state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, true, - {className: "CodeMirror-selection-highlight-scrollbar"}); - } - } - - function removeOverlay(cm) { - var state = cm.state.matchHighlighter; - if (state.overlay) { - cm.removeOverlay(state.overlay); - state.overlay = null; - if (state.matchesonscroll) { - state.matchesonscroll.clear(); - state.matchesonscroll = null; - } - } - } - - function highlightMatches(cm) { - cm.operation(function() { - var state = cm.state.matchHighlighter; - removeOverlay(cm); - if (!cm.somethingSelected() && state.options.showToken) { - var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken; - var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; - while (start && re.test(line.charAt(start - 1))) --start; - while (end < line.length && re.test(line.charAt(end))) ++end; - if (start < end) - addOverlay(cm, line.slice(start, end), re, state.options.style); - return; - } - var from = cm.getCursor("from"), to = cm.getCursor("to"); - if (from.line != to.line) return; - if (state.options.wordsOnly && !isWord(cm, from, to)) return; - var selection = cm.getRange(from, to) - if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "") - if (selection.length >= state.options.minChars) - addOverlay(cm, selection, false, state.options.style); - }); - } - - function isWord(cm, from, to) { - var str = cm.getRange(from, to); - if (str.match(/^\w+$/) !== null) { - if (from.ch > 0) { - var pos = {line: from.line, ch: from.ch - 1}; - var chr = cm.getRange(pos, from); - if (chr.match(/\W/) === null) return false; - } - if (to.ch < cm.getLine(from.line).length) { - var pos = {line: to.line, ch: to.ch + 1}; - var chr = cm.getRange(to, pos); - if (chr.match(/\W/) === null) return false; - } - return true; - } else return false; - } - - function boundariesAround(stream, re) { - return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && - (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); - } - - function makeOverlay(query, hasBoundary, style) { - return {token: function(stream) { - if (stream.match(query) && - (!hasBoundary || boundariesAround(stream, hasBoundary))) - return style; - stream.next(); - stream.skipTo(query.charAt(0)) || stream.skipToEnd(); - }}; - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Highlighting text that matches the selection +// +// Defines an option highlightSelectionMatches, which, when enabled, +// will style strings that match the selection throughout the +// document. +// +// The option can be set to true to simply enable it, or to a +// {minChars, style, wordsOnly, showToken, delay} object to explicitly +// configure it. minChars is the minimum amount of characters that should be +// selected for the behavior to occur, and style is the token style to +// apply to the matches. This will be prefixed by "cm-" to create an +// actual CSS class name. If wordsOnly is enabled, the matches will be +// highlighted only if the selected text is a word. showToken, when enabled, +// will cause the current token to be highlighted when nothing is selected. +// delay is used to specify how much time to wait, in milliseconds, before +// highlighting the matches. If annotateScrollbar is enabled, the occurences +// will be highlighted on the scrollbar via the matchesonscrollbar addon. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./matchesonscrollbar")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./matchesonscrollbar"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var defaults = { + style: "matchhighlight", + minChars: 2, + delay: 100, + wordsOnly: false, + annotateScrollbar: false, + showToken: false, + trim: true + } + + function State(options) { + this.options = {} + for (var name in defaults) + this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name] + this.overlay = this.timeout = null; + this.matchesonscroll = null; + } + + CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + removeOverlay(cm); + clearTimeout(cm.state.matchHighlighter.timeout); + cm.state.matchHighlighter = null; + cm.off("cursorActivity", cursorActivity); + } + if (val) { + cm.state.matchHighlighter = new State(val); + highlightMatches(cm); + cm.on("cursorActivity", cursorActivity); + } + }); + + function cursorActivity(cm) { + var state = cm.state.matchHighlighter; + clearTimeout(state.timeout); + state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay); + } + + function addOverlay(cm, query, hasBoundary, style) { + var state = cm.state.matchHighlighter; + cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style)); + if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) { + var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query; + state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, true, + {className: "CodeMirror-selection-highlight-scrollbar"}); + } + } + + function removeOverlay(cm) { + var state = cm.state.matchHighlighter; + if (state.overlay) { + cm.removeOverlay(state.overlay); + state.overlay = null; + if (state.matchesonscroll) { + state.matchesonscroll.clear(); + state.matchesonscroll = null; + } + } + } + + function highlightMatches(cm) { + cm.operation(function() { + var state = cm.state.matchHighlighter; + removeOverlay(cm); + if (!cm.somethingSelected() && state.options.showToken) { + var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken; + var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; + while (start && re.test(line.charAt(start - 1))) --start; + while (end < line.length && re.test(line.charAt(end))) ++end; + if (start < end) + addOverlay(cm, line.slice(start, end), re, state.options.style); + return; + } + var from = cm.getCursor("from"), to = cm.getCursor("to"); + if (from.line != to.line) return; + if (state.options.wordsOnly && !isWord(cm, from, to)) return; + var selection = cm.getRange(from, to) + if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "") + if (selection.length >= state.options.minChars) + addOverlay(cm, selection, false, state.options.style); + }); + } + + function isWord(cm, from, to) { + var str = cm.getRange(from, to); + if (str.match(/^\w+$/) !== null) { + if (from.ch > 0) { + var pos = {line: from.line, ch: from.ch - 1}; + var chr = cm.getRange(pos, from); + if (chr.match(/\W/) === null) return false; + } + if (to.ch < cm.getLine(from.line).length) { + var pos = {line: to.line, ch: to.ch + 1}; + var chr = cm.getRange(to, pos); + if (chr.match(/\W/) === null) return false; + } + return true; + } else return false; + } + + function boundariesAround(stream, re) { + return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && + (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); + } + + function makeOverlay(query, hasBoundary, style) { + return {token: function(stream) { + if (stream.match(query) && + (!hasBoundary || boundariesAround(stream, hasBoundary))) + return style; + stream.next(); + stream.skipTo(query.charAt(0)) || stream.skipToEnd(); + }}; + } +}); diff --git a/shared/codemirror/addon/search/matchesonscrollbar.css b/shared/codemirror/addon/search/matchesonscrollbar.css index 77932cc..77efb38 100644 --- a/shared/codemirror/addon/search/matchesonscrollbar.css +++ b/shared/codemirror/addon/search/matchesonscrollbar.css @@ -1,8 +1,8 @@ -.CodeMirror-search-match { - background: gold; - border-top: 1px solid orange; - border-bottom: 1px solid orange; - -moz-box-sizing: border-box; - box-sizing: border-box; - opacity: .5; -} +.CodeMirror-search-match { + background: gold; + border-top: 1px solid orange; + border-bottom: 1px solid orange; + -moz-box-sizing: border-box; + box-sizing: border-box; + opacity: .5; +} diff --git a/shared/codemirror/addon/search/matchesonscrollbar.js b/shared/codemirror/addon/search/matchesonscrollbar.js index 8d19228..c79bad7 100644 --- a/shared/codemirror/addon/search/matchesonscrollbar.js +++ b/shared/codemirror/addon/search/matchesonscrollbar.js @@ -1,97 +1,97 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) { - if (typeof options == "string") options = {className: options}; - if (!options) options = {}; - return new SearchAnnotation(this, query, caseFold, options); - }); - - function SearchAnnotation(cm, query, caseFold, options) { - this.cm = cm; - this.options = options; - var annotateOptions = {listenForChanges: false}; - for (var prop in options) annotateOptions[prop] = options[prop]; - if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; - this.annotation = cm.annotateScrollbar(annotateOptions); - this.query = query; - this.caseFold = caseFold; - this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1}; - this.matches = []; - this.update = null; - - this.findMatches(); - this.annotation.update(this.matches); - - var self = this; - cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); }); - } - - var MAX_MATCHES = 1000; - - SearchAnnotation.prototype.findMatches = function() { - if (!this.gap) return; - for (var i = 0; i < this.matches.length; i++) { - var match = this.matches[i]; - if (match.from.line >= this.gap.to) break; - if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); - } - var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold); - var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES; - while (cursor.findNext()) { - var match = {from: cursor.from(), to: cursor.to()}; - if (match.from.line >= this.gap.to) break; - this.matches.splice(i++, 0, match); - if (this.matches.length > maxMatches) break; - } - this.gap = null; - }; - - function offsetLine(line, changeStart, sizeChange) { - if (line <= changeStart) return line; - return Math.max(changeStart, line + sizeChange); - } - - SearchAnnotation.prototype.onChange = function(change) { - var startLine = change.from.line; - var endLine = CodeMirror.changeEnd(change).line; - var sizeChange = endLine - change.to.line; - if (this.gap) { - this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line); - this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line); - } else { - this.gap = {from: change.from.line, to: endLine + 1}; - } - - if (sizeChange) for (var i = 0; i < this.matches.length; i++) { - var match = this.matches[i]; - var newFrom = offsetLine(match.from.line, startLine, sizeChange); - if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch); - var newTo = offsetLine(match.to.line, startLine, sizeChange); - if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch); - } - clearTimeout(this.update); - var self = this; - this.update = setTimeout(function() { self.updateAfterChange(); }, 250); - }; - - SearchAnnotation.prototype.updateAfterChange = function() { - this.findMatches(); - this.annotation.update(this.matches); - }; - - SearchAnnotation.prototype.clear = function() { - this.cm.off("change", this.changeHandler); - this.annotation.clear(); - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) { + if (typeof options == "string") options = {className: options}; + if (!options) options = {}; + return new SearchAnnotation(this, query, caseFold, options); + }); + + function SearchAnnotation(cm, query, caseFold, options) { + this.cm = cm; + this.options = options; + var annotateOptions = {listenForChanges: false}; + for (var prop in options) annotateOptions[prop] = options[prop]; + if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; + this.annotation = cm.annotateScrollbar(annotateOptions); + this.query = query; + this.caseFold = caseFold; + this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1}; + this.matches = []; + this.update = null; + + this.findMatches(); + this.annotation.update(this.matches); + + var self = this; + cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); }); + } + + var MAX_MATCHES = 1000; + + SearchAnnotation.prototype.findMatches = function() { + if (!this.gap) return; + for (var i = 0; i < this.matches.length; i++) { + var match = this.matches[i]; + if (match.from.line >= this.gap.to) break; + if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); + } + var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold); + var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES; + while (cursor.findNext()) { + var match = {from: cursor.from(), to: cursor.to()}; + if (match.from.line >= this.gap.to) break; + this.matches.splice(i++, 0, match); + if (this.matches.length > maxMatches) break; + } + this.gap = null; + }; + + function offsetLine(line, changeStart, sizeChange) { + if (line <= changeStart) return line; + return Math.max(changeStart, line + sizeChange); + } + + SearchAnnotation.prototype.onChange = function(change) { + var startLine = change.from.line; + var endLine = CodeMirror.changeEnd(change).line; + var sizeChange = endLine - change.to.line; + if (this.gap) { + this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line); + this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line); + } else { + this.gap = {from: change.from.line, to: endLine + 1}; + } + + if (sizeChange) for (var i = 0; i < this.matches.length; i++) { + var match = this.matches[i]; + var newFrom = offsetLine(match.from.line, startLine, sizeChange); + if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch); + var newTo = offsetLine(match.to.line, startLine, sizeChange); + if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch); + } + clearTimeout(this.update); + var self = this; + this.update = setTimeout(function() { self.updateAfterChange(); }, 250); + }; + + SearchAnnotation.prototype.updateAfterChange = function() { + this.findMatches(); + this.annotation.update(this.matches); + }; + + SearchAnnotation.prototype.clear = function() { + this.cm.off("change", this.changeHandler); + this.annotation.clear(); + }; +}); diff --git a/shared/codemirror/addon/search/search.js b/shared/codemirror/addon/search/search.js index e6b4f85..82ea2bc 100644 --- a/shared/codemirror/addon/search/search.js +++ b/shared/codemirror/addon/search/search.js @@ -1,231 +1,231 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Define search commands. Depends on dialog.js or another -// implementation of the openDialog method. - -// Replace works a little oddly -- it will do the replace on the next -// Ctrl-G (or whatever is bound to findNext) press. You prevent a -// replace by making sure the match is no longer selected when hitting -// Ctrl-G. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function searchOverlay(query, caseInsensitive) { - if (typeof query == "string") - query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g"); - else if (!query.global) - query = new RegExp(query.source, query.ignoreCase ? "gi" : "g"); - - return {token: function(stream) { - query.lastIndex = stream.pos; - var match = query.exec(stream.string); - if (match && match.index == stream.pos) { - stream.pos += match[0].length || 1; - return "searching"; - } else if (match) { - stream.pos = match.index; - } else { - stream.skipToEnd(); - } - }}; - } - - function SearchState() { - this.posFrom = this.posTo = this.lastQuery = this.query = null; - this.overlay = null; - } - - function getSearchState(cm) { - return cm.state.search || (cm.state.search = new SearchState()); - } - - function queryCaseInsensitive(query) { - return typeof query == "string" && query == query.toLowerCase(); - } - - function getSearchCursor(cm, query, pos) { - // Heuristic: if the query string is all lowercase, do a case insensitive search. - return cm.getSearchCursor(query, pos, queryCaseInsensitive(query)); - } - - function persistentDialog(cm, text, deflt, f) { - cm.openDialog(text, f, { - value: deflt, - selectValueOnOpen: true, - closeOnEnter: false, - onClose: function() { clearSearch(cm); } - }); - } - - function dialog(cm, text, shortText, deflt, f) { - if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); - else f(prompt(shortText, deflt)); - } - - function confirmDialog(cm, text, shortText, fs) { - if (cm.openConfirm) cm.openConfirm(text, fs); - else if (confirm(shortText)) fs[0](); - } - - function parseString(string) { - return string.replace(/\\(.)/g, function(_, ch) { - if (ch == "n") return "\n" - if (ch == "r") return "\r" - return ch - }) - } - - function parseQuery(query) { - var isRE = query.match(/^\/(.*)\/([a-z]*)$/); - if (isRE) { - try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } - catch(e) {} // Not a regular expression after all, do a string search - } else { - query = parseString(query) - } - if (typeof query == "string" ? query == "" : query.test("")) - query = /x^/; - return query; - } - - var queryDialog = - 'Search: (Use /re/ syntax for regexp search)'; - - function startSearch(cm, state, query) { - state.queryText = query; - state.query = parseQuery(query); - cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); - state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); - cm.addOverlay(state.overlay); - if (cm.showMatchesOnScrollbar) { - if (state.annotate) { state.annotate.clear(); state.annotate = null; } - state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); - } - } - - function doSearch(cm, rev, persistent) { - var state = getSearchState(cm); - if (state.query) return findNext(cm, rev); - var q = cm.getSelection() || state.lastQuery; - if (persistent && cm.openDialog) { - var hiding = null - persistentDialog(cm, queryDialog, q, function(query, event) { - CodeMirror.e_stop(event); - if (!query) return; - if (query != state.queryText) { - startSearch(cm, state, query); - state.posFrom = state.posTo = cm.getCursor(); - } - if (hiding) hiding.style.opacity = 1 - findNext(cm, event.shiftKey, function(_, to) { - var dialog - if (to.line < 3 && document.querySelector && - (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) && - dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top) - (hiding = dialog).style.opacity = .4 - }) - }); - } else { - dialog(cm, queryDialog, "Search for:", q, function(query) { - if (query && !state.query) cm.operation(function() { - startSearch(cm, state, query); - state.posFrom = state.posTo = cm.getCursor(); - findNext(cm, rev); - }); - }); - } - } - - function findNext(cm, rev, callback) {cm.operation(function() { - var state = getSearchState(cm); - var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); - if (!cursor.find(rev)) { - cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); - if (!cursor.find(rev)) return; - } - cm.setSelection(cursor.from(), cursor.to()); - cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20); - state.posFrom = cursor.from(); state.posTo = cursor.to(); - if (callback) callback(cursor.from(), cursor.to()) - });} - - function clearSearch(cm) {cm.operation(function() { - var state = getSearchState(cm); - state.lastQuery = state.query; - if (!state.query) return; - state.query = state.queryText = null; - cm.removeOverlay(state.overlay); - if (state.annotate) { state.annotate.clear(); state.annotate = null; } - });} - - var replaceQueryDialog = - ' (Use /re/ syntax for regexp search)'; - var replacementQueryDialog = 'With: '; - var doReplaceConfirm = "Replace? "; - - function replaceAll(cm, query, text) { - cm.operation(function() { - for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { - if (typeof query != "string") { - var match = cm.getRange(cursor.from(), cursor.to()).match(query); - cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); - } else cursor.replace(text); - } - }); - } - - function replace(cm, all) { - if (cm.getOption("readOnly")) return; - var query = cm.getSelection() || getSearchState(cm).lastQuery; - var dialogText = all ? "Replace all:" : "Replace:" - dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) { - if (!query) return; - query = parseQuery(query); - dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { - text = parseString(text) - if (all) { - replaceAll(cm, query, text) - } else { - clearSearch(cm); - var cursor = getSearchCursor(cm, query, cm.getCursor("from")); - var advance = function() { - var start = cursor.from(), match; - if (!(match = cursor.findNext())) { - cursor = getSearchCursor(cm, query); - if (!(match = cursor.findNext()) || - (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; - } - cm.setSelection(cursor.from(), cursor.to()); - cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); - confirmDialog(cm, doReplaceConfirm, "Replace?", - [function() {doReplace(match);}, advance, - function() {replaceAll(cm, query, text)}]); - }; - var doReplace = function(match) { - cursor.replace(typeof query == "string" ? text : - text.replace(/\$(\d)/g, function(_, i) {return match[i];})); - advance(); - }; - advance(); - } - }); - }); - } - - CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; - CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);}; - CodeMirror.commands.findNext = doSearch; - CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; - CodeMirror.commands.clearSearch = clearSearch; - CodeMirror.commands.replace = replace; - CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Define search commands. Depends on dialog.js or another +// implementation of the openDialog method. + +// Replace works a little oddly -- it will do the replace on the next +// Ctrl-G (or whatever is bound to findNext) press. You prevent a +// replace by making sure the match is no longer selected when hitting +// Ctrl-G. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function searchOverlay(query, caseInsensitive) { + if (typeof query == "string") + query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g"); + else if (!query.global) + query = new RegExp(query.source, query.ignoreCase ? "gi" : "g"); + + return {token: function(stream) { + query.lastIndex = stream.pos; + var match = query.exec(stream.string); + if (match && match.index == stream.pos) { + stream.pos += match[0].length || 1; + return "searching"; + } else if (match) { + stream.pos = match.index; + } else { + stream.skipToEnd(); + } + }}; + } + + function SearchState() { + this.posFrom = this.posTo = this.lastQuery = this.query = null; + this.overlay = null; + } + + function getSearchState(cm) { + return cm.state.search || (cm.state.search = new SearchState()); + } + + function queryCaseInsensitive(query) { + return typeof query == "string" && query == query.toLowerCase(); + } + + function getSearchCursor(cm, query, pos) { + // Heuristic: if the query string is all lowercase, do a case insensitive search. + return cm.getSearchCursor(query, pos, queryCaseInsensitive(query)); + } + + function persistentDialog(cm, text, deflt, f) { + cm.openDialog(text, f, { + value: deflt, + selectValueOnOpen: true, + closeOnEnter: false, + onClose: function() { clearSearch(cm); } + }); + } + + function dialog(cm, text, shortText, deflt, f) { + if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); + else f(prompt(shortText, deflt)); + } + + function confirmDialog(cm, text, shortText, fs) { + if (cm.openConfirm) cm.openConfirm(text, fs); + else if (confirm(shortText)) fs[0](); + } + + function parseString(string) { + return string.replace(/\\(.)/g, function(_, ch) { + if (ch == "n") return "\n" + if (ch == "r") return "\r" + return ch + }) + } + + function parseQuery(query) { + var isRE = query.match(/^\/(.*)\/([a-z]*)$/); + if (isRE) { + try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } + catch(e) {} // Not a regular expression after all, do a string search + } else { + query = parseString(query) + } + if (typeof query == "string" ? query == "" : query.test("")) + query = /x^/; + return query; + } + + var queryDialog = + 'Search: (Use /re/ syntax for regexp search)'; + + function startSearch(cm, state, query) { + state.queryText = query; + state.query = parseQuery(query); + cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); + state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); + cm.addOverlay(state.overlay); + if (cm.showMatchesOnScrollbar) { + if (state.annotate) { state.annotate.clear(); state.annotate = null; } + state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); + } + } + + function doSearch(cm, rev, persistent) { + var state = getSearchState(cm); + if (state.query) return findNext(cm, rev); + var q = cm.getSelection() || state.lastQuery; + if (persistent && cm.openDialog) { + var hiding = null + persistentDialog(cm, queryDialog, q, function(query, event) { + CodeMirror.e_stop(event); + if (!query) return; + if (query != state.queryText) { + startSearch(cm, state, query); + state.posFrom = state.posTo = cm.getCursor(); + } + if (hiding) hiding.style.opacity = 1 + findNext(cm, event.shiftKey, function(_, to) { + var dialog + if (to.line < 3 && document.querySelector && + (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) && + dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top) + (hiding = dialog).style.opacity = .4 + }) + }); + } else { + dialog(cm, queryDialog, "Search for:", q, function(query) { + if (query && !state.query) cm.operation(function() { + startSearch(cm, state, query); + state.posFrom = state.posTo = cm.getCursor(); + findNext(cm, rev); + }); + }); + } + } + + function findNext(cm, rev, callback) {cm.operation(function() { + var state = getSearchState(cm); + var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); + if (!cursor.find(rev)) { + cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); + if (!cursor.find(rev)) return; + } + cm.setSelection(cursor.from(), cursor.to()); + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20); + state.posFrom = cursor.from(); state.posTo = cursor.to(); + if (callback) callback(cursor.from(), cursor.to()) + });} + + function clearSearch(cm) {cm.operation(function() { + var state = getSearchState(cm); + state.lastQuery = state.query; + if (!state.query) return; + state.query = state.queryText = null; + cm.removeOverlay(state.overlay); + if (state.annotate) { state.annotate.clear(); state.annotate = null; } + });} + + var replaceQueryDialog = + ' (Use /re/ syntax for regexp search)'; + var replacementQueryDialog = 'With: '; + var doReplaceConfirm = "Replace? "; + + function replaceAll(cm, query, text) { + cm.operation(function() { + for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { + if (typeof query != "string") { + var match = cm.getRange(cursor.from(), cursor.to()).match(query); + cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); + } else cursor.replace(text); + } + }); + } + + function replace(cm, all) { + if (cm.getOption("readOnly")) return; + var query = cm.getSelection() || getSearchState(cm).lastQuery; + var dialogText = all ? "Replace all:" : "Replace:" + dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) { + if (!query) return; + query = parseQuery(query); + dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { + text = parseString(text) + if (all) { + replaceAll(cm, query, text) + } else { + clearSearch(cm); + var cursor = getSearchCursor(cm, query, cm.getCursor("from")); + var advance = function() { + var start = cursor.from(), match; + if (!(match = cursor.findNext())) { + cursor = getSearchCursor(cm, query); + if (!(match = cursor.findNext()) || + (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; + } + cm.setSelection(cursor.from(), cursor.to()); + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); + confirmDialog(cm, doReplaceConfirm, "Replace?", + [function() {doReplace(match);}, advance, + function() {replaceAll(cm, query, text)}]); + }; + var doReplace = function(match) { + cursor.replace(typeof query == "string" ? text : + text.replace(/\$(\d)/g, function(_, i) {return match[i];})); + advance(); + }; + advance(); + } + }); + }); + } + + CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; + CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);}; + CodeMirror.commands.findNext = doSearch; + CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; + CodeMirror.commands.clearSearch = clearSearch; + CodeMirror.commands.replace = replace; + CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; +}); diff --git a/shared/codemirror/addon/search/searchcursor.js b/shared/codemirror/addon/search/searchcursor.js index b70242e..663e88b 100644 --- a/shared/codemirror/addon/search/searchcursor.js +++ b/shared/codemirror/addon/search/searchcursor.js @@ -1,189 +1,189 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - var Pos = CodeMirror.Pos; - - function SearchCursor(doc, query, pos, caseFold) { - this.atOccurrence = false; this.doc = doc; - if (caseFold == null && typeof query == "string") caseFold = false; - - pos = pos ? doc.clipPos(pos) : Pos(0, 0); - this.pos = {from: pos, to: pos}; - - // The matches method is filled in based on the type of query. - // It takes a position and a direction, and returns an object - // describing the next occurrence of the query, or null if no - // more matches were found. - if (typeof query != "string") { // Regexp match - if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); - this.matches = function(reverse, pos) { - if (reverse) { - query.lastIndex = 0; - var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; - for (;;) { - query.lastIndex = cutOff; - var newMatch = query.exec(line); - if (!newMatch) break; - match = newMatch; - start = match.index; - cutOff = match.index + (match[0].length || 1); - if (cutOff == line.length) break; - } - var matchLen = (match && match[0].length) || 0; - if (!matchLen) { - if (start == 0 && line.length == 0) {match = undefined;} - else if (start != doc.getLine(pos.line).length) { - matchLen++; - } - } - } else { - query.lastIndex = pos.ch; - var line = doc.getLine(pos.line), match = query.exec(line); - var matchLen = (match && match[0].length) || 0; - var start = match && match.index; - if (start + matchLen != line.length && !matchLen) matchLen = 1; - } - if (match && matchLen) - return {from: Pos(pos.line, start), - to: Pos(pos.line, start + matchLen), - match: match}; - }; - } else { // String query - var origQuery = query; - if (caseFold) query = query.toLowerCase(); - var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; - var target = query.split("\n"); - // Different methods for single-line and multi-line queries - if (target.length == 1) { - if (!query.length) { - // Empty string would match anything and never progress, so - // we define it to match nothing instead. - this.matches = function() {}; - } else { - this.matches = function(reverse, pos) { - if (reverse) { - var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); - var match = line.lastIndexOf(query); - if (match > -1) { - match = adjustPos(orig, line, match); - return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; - } - } else { - var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig); - var match = line.indexOf(query); - if (match > -1) { - match = adjustPos(orig, line, match) + pos.ch; - return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; - } - } - }; - } - } else { - var origTarget = origQuery.split("\n"); - this.matches = function(reverse, pos) { - var last = target.length - 1; - if (reverse) { - if (pos.line - (target.length - 1) < doc.firstLine()) return; - if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; - var to = Pos(pos.line, origTarget[last].length); - for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) - if (target[i] != fold(doc.getLine(ln))) return; - var line = doc.getLine(ln), cut = line.length - origTarget[0].length; - if (fold(line.slice(cut)) != target[0]) return; - return {from: Pos(ln, cut), to: to}; - } else { - if (pos.line + (target.length - 1) > doc.lastLine()) return; - var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; - if (fold(line.slice(cut)) != target[0]) return; - var from = Pos(pos.line, cut); - for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) - if (target[i] != fold(doc.getLine(ln))) return; - if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return; - return {from: from, to: Pos(ln, origTarget[last].length)}; - } - }; - } - } - } - - SearchCursor.prototype = { - findNext: function() {return this.find(false);}, - findPrevious: function() {return this.find(true);}, - - find: function(reverse) { - var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); - function savePosAndFail(line) { - var pos = Pos(line, 0); - self.pos = {from: pos, to: pos}; - self.atOccurrence = false; - return false; - } - - for (;;) { - if (this.pos = this.matches(reverse, pos)) { - this.atOccurrence = true; - return this.pos.match || true; - } - if (reverse) { - if (!pos.line) return savePosAndFail(0); - pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); - } - else { - var maxLine = this.doc.lineCount(); - if (pos.line == maxLine - 1) return savePosAndFail(maxLine); - pos = Pos(pos.line + 1, 0); - } - } - }, - - from: function() {if (this.atOccurrence) return this.pos.from;}, - to: function() {if (this.atOccurrence) return this.pos.to;}, - - replace: function(newText, origin) { - if (!this.atOccurrence) return; - var lines = CodeMirror.splitLines(newText); - this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin); - this.pos.to = Pos(this.pos.from.line + lines.length - 1, - lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); - } - }; - - // Maps a position in a case-folded line back to a position in the original line - // (compensating for codepoints increasing in number during folding) - function adjustPos(orig, folded, pos) { - if (orig.length == folded.length) return pos; - for (var pos1 = Math.min(pos, orig.length);;) { - var len1 = orig.slice(0, pos1).toLowerCase().length; - if (len1 < pos) ++pos1; - else if (len1 > pos) --pos1; - else return pos1; - } - } - - CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this.doc, query, pos, caseFold); - }); - CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this, query, pos, caseFold); - }); - - CodeMirror.defineExtension("selectMatches", function(query, caseFold) { - var ranges = []; - var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); - while (cur.findNext()) { - if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break; - ranges.push({anchor: cur.from(), head: cur.to()}); - } - if (ranges.length) - this.setSelections(ranges, 0); - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var Pos = CodeMirror.Pos; + + function SearchCursor(doc, query, pos, caseFold) { + this.atOccurrence = false; this.doc = doc; + if (caseFold == null && typeof query == "string") caseFold = false; + + pos = pos ? doc.clipPos(pos) : Pos(0, 0); + this.pos = {from: pos, to: pos}; + + // The matches method is filled in based on the type of query. + // It takes a position and a direction, and returns an object + // describing the next occurrence of the query, or null if no + // more matches were found. + if (typeof query != "string") { // Regexp match + if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); + this.matches = function(reverse, pos) { + if (reverse) { + query.lastIndex = 0; + var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; + for (;;) { + query.lastIndex = cutOff; + var newMatch = query.exec(line); + if (!newMatch) break; + match = newMatch; + start = match.index; + cutOff = match.index + (match[0].length || 1); + if (cutOff == line.length) break; + } + var matchLen = (match && match[0].length) || 0; + if (!matchLen) { + if (start == 0 && line.length == 0) {match = undefined;} + else if (start != doc.getLine(pos.line).length) { + matchLen++; + } + } + } else { + query.lastIndex = pos.ch; + var line = doc.getLine(pos.line), match = query.exec(line); + var matchLen = (match && match[0].length) || 0; + var start = match && match.index; + if (start + matchLen != line.length && !matchLen) matchLen = 1; + } + if (match && matchLen) + return {from: Pos(pos.line, start), + to: Pos(pos.line, start + matchLen), + match: match}; + }; + } else { // String query + var origQuery = query; + if (caseFold) query = query.toLowerCase(); + var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; + var target = query.split("\n"); + // Different methods for single-line and multi-line queries + if (target.length == 1) { + if (!query.length) { + // Empty string would match anything and never progress, so + // we define it to match nothing instead. + this.matches = function() {}; + } else { + this.matches = function(reverse, pos) { + if (reverse) { + var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); + var match = line.lastIndexOf(query); + if (match > -1) { + match = adjustPos(orig, line, match); + return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; + } + } else { + var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig); + var match = line.indexOf(query); + if (match > -1) { + match = adjustPos(orig, line, match) + pos.ch; + return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; + } + } + }; + } + } else { + var origTarget = origQuery.split("\n"); + this.matches = function(reverse, pos) { + var last = target.length - 1; + if (reverse) { + if (pos.line - (target.length - 1) < doc.firstLine()) return; + if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; + var to = Pos(pos.line, origTarget[last].length); + for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) + if (target[i] != fold(doc.getLine(ln))) return; + var line = doc.getLine(ln), cut = line.length - origTarget[0].length; + if (fold(line.slice(cut)) != target[0]) return; + return {from: Pos(ln, cut), to: to}; + } else { + if (pos.line + (target.length - 1) > doc.lastLine()) return; + var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; + if (fold(line.slice(cut)) != target[0]) return; + var from = Pos(pos.line, cut); + for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) + if (target[i] != fold(doc.getLine(ln))) return; + if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return; + return {from: from, to: Pos(ln, origTarget[last].length)}; + } + }; + } + } + } + + SearchCursor.prototype = { + findNext: function() {return this.find(false);}, + findPrevious: function() {return this.find(true);}, + + find: function(reverse) { + var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); + function savePosAndFail(line) { + var pos = Pos(line, 0); + self.pos = {from: pos, to: pos}; + self.atOccurrence = false; + return false; + } + + for (;;) { + if (this.pos = this.matches(reverse, pos)) { + this.atOccurrence = true; + return this.pos.match || true; + } + if (reverse) { + if (!pos.line) return savePosAndFail(0); + pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); + } + else { + var maxLine = this.doc.lineCount(); + if (pos.line == maxLine - 1) return savePosAndFail(maxLine); + pos = Pos(pos.line + 1, 0); + } + } + }, + + from: function() {if (this.atOccurrence) return this.pos.from;}, + to: function() {if (this.atOccurrence) return this.pos.to;}, + + replace: function(newText, origin) { + if (!this.atOccurrence) return; + var lines = CodeMirror.splitLines(newText); + this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin); + this.pos.to = Pos(this.pos.from.line + lines.length - 1, + lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); + } + }; + + // Maps a position in a case-folded line back to a position in the original line + // (compensating for codepoints increasing in number during folding) + function adjustPos(orig, folded, pos) { + if (orig.length == folded.length) return pos; + for (var pos1 = Math.min(pos, orig.length);;) { + var len1 = orig.slice(0, pos1).toLowerCase().length; + if (len1 < pos) ++pos1; + else if (len1 > pos) --pos1; + else return pos1; + } + } + + CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this.doc, query, pos, caseFold); + }); + CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this, query, pos, caseFold); + }); + + CodeMirror.defineExtension("selectMatches", function(query, caseFold) { + var ranges = []; + var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); + while (cur.findNext()) { + if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break; + ranges.push({anchor: cur.from(), head: cur.to()}); + } + if (ranges.length) + this.setSelections(ranges, 0); + }); +}); diff --git a/shared/codemirror/addon/selection/active-line.js b/shared/codemirror/addon/selection/active-line.js index b0b3f61..d7d2506 100644 --- a/shared/codemirror/addon/selection/active-line.js +++ b/shared/codemirror/addon/selection/active-line.js @@ -1,74 +1,74 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Because sometimes you need to style the cursor's line. -// -// Adds an option 'styleActiveLine' which, when enabled, gives the -// active line's wrapping
the CSS class "CodeMirror-activeline", -// and gives its background
the class "CodeMirror-activeline-background". - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - var WRAP_CLASS = "CodeMirror-activeline"; - var BACK_CLASS = "CodeMirror-activeline-background"; - var GUTT_CLASS = "CodeMirror-activeline-gutter"; - - CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.state.activeLines = []; - updateActiveLines(cm, cm.listSelections()); - cm.on("beforeSelectionChange", selectionChange); - } else if (!val && prev) { - cm.off("beforeSelectionChange", selectionChange); - clearActiveLines(cm); - delete cm.state.activeLines; - } - }); - - function clearActiveLines(cm) { - for (var i = 0; i < cm.state.activeLines.length; i++) { - cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); - cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); - cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS); - } - } - - function sameArray(a, b) { - if (a.length != b.length) return false; - for (var i = 0; i < a.length; i++) - if (a[i] != b[i]) return false; - return true; - } - - function updateActiveLines(cm, ranges) { - var active = []; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - if (!range.empty()) continue; - var line = cm.getLineHandleVisualStart(range.head.line); - if (active[active.length - 1] != line) active.push(line); - } - if (sameArray(cm.state.activeLines, active)) return; - cm.operation(function() { - clearActiveLines(cm); - for (var i = 0; i < active.length; i++) { - cm.addLineClass(active[i], "wrap", WRAP_CLASS); - cm.addLineClass(active[i], "background", BACK_CLASS); - cm.addLineClass(active[i], "gutter", GUTT_CLASS); - } - cm.state.activeLines = active; - }); - } - - function selectionChange(cm, sel) { - updateActiveLines(cm, sel.ranges); - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Because sometimes you need to style the cursor's line. +// +// Adds an option 'styleActiveLine' which, when enabled, gives the +// active line's wrapping
the CSS class "CodeMirror-activeline", +// and gives its background
the class "CodeMirror-activeline-background". + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var WRAP_CLASS = "CodeMirror-activeline"; + var BACK_CLASS = "CodeMirror-activeline-background"; + var GUTT_CLASS = "CodeMirror-activeline-gutter"; + + CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.activeLines = []; + updateActiveLines(cm, cm.listSelections()); + cm.on("beforeSelectionChange", selectionChange); + } else if (!val && prev) { + cm.off("beforeSelectionChange", selectionChange); + clearActiveLines(cm); + delete cm.state.activeLines; + } + }); + + function clearActiveLines(cm) { + for (var i = 0; i < cm.state.activeLines.length; i++) { + cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); + cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); + cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS); + } + } + + function sameArray(a, b) { + if (a.length != b.length) return false; + for (var i = 0; i < a.length; i++) + if (a[i] != b[i]) return false; + return true; + } + + function updateActiveLines(cm, ranges) { + var active = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) continue; + var line = cm.getLineHandleVisualStart(range.head.line); + if (active[active.length - 1] != line) active.push(line); + } + if (sameArray(cm.state.activeLines, active)) return; + cm.operation(function() { + clearActiveLines(cm); + for (var i = 0; i < active.length; i++) { + cm.addLineClass(active[i], "wrap", WRAP_CLASS); + cm.addLineClass(active[i], "background", BACK_CLASS); + cm.addLineClass(active[i], "gutter", GUTT_CLASS); + } + cm.state.activeLines = active; + }); + } + + function selectionChange(cm, sel) { + updateActiveLines(cm, sel.ranges); + } +}); diff --git a/shared/codemirror/addon/selection/mark-selection.js b/shared/codemirror/addon/selection/mark-selection.js index 5c42d21..ccf164a 100644 --- a/shared/codemirror/addon/selection/mark-selection.js +++ b/shared/codemirror/addon/selection/mark-selection.js @@ -1,118 +1,118 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Because sometimes you need to mark the selected *text*. -// -// Adds an option 'styleSelectedText' which, when enabled, gives -// selected text the CSS class given as option value, or -// "CodeMirror-selectedtext" when the value is not a string. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.state.markedSelection = []; - cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; - reset(cm); - cm.on("cursorActivity", onCursorActivity); - cm.on("change", onChange); - } else if (!val && prev) { - cm.off("cursorActivity", onCursorActivity); - cm.off("change", onChange); - clear(cm); - cm.state.markedSelection = cm.state.markedSelectionStyle = null; - } - }); - - function onCursorActivity(cm) { - cm.operation(function() { update(cm); }); - } - - function onChange(cm) { - if (cm.state.markedSelection.length) - cm.operation(function() { clear(cm); }); - } - - var CHUNK_SIZE = 8; - var Pos = CodeMirror.Pos; - var cmp = CodeMirror.cmpPos; - - function coverRange(cm, from, to, addAt) { - if (cmp(from, to) == 0) return; - var array = cm.state.markedSelection; - var cls = cm.state.markedSelectionStyle; - for (var line = from.line;;) { - var start = line == from.line ? from : Pos(line, 0); - var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; - var end = atEnd ? to : Pos(endLine, 0); - var mark = cm.markText(start, end, {className: cls}); - if (addAt == null) array.push(mark); - else array.splice(addAt++, 0, mark); - if (atEnd) break; - line = endLine; - } - } - - function clear(cm) { - var array = cm.state.markedSelection; - for (var i = 0; i < array.length; ++i) array[i].clear(); - array.length = 0; - } - - function reset(cm) { - clear(cm); - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) - coverRange(cm, ranges[i].from(), ranges[i].to()); - } - - function update(cm) { - if (!cm.somethingSelected()) return clear(cm); - if (cm.listSelections().length > 1) return reset(cm); - - var from = cm.getCursor("start"), to = cm.getCursor("end"); - - var array = cm.state.markedSelection; - if (!array.length) return coverRange(cm, from, to); - - var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); - if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || - cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) - return reset(cm); - - while (cmp(from, coverStart.from) > 0) { - array.shift().clear(); - coverStart = array[0].find(); - } - if (cmp(from, coverStart.from) < 0) { - if (coverStart.to.line - from.line < CHUNK_SIZE) { - array.shift().clear(); - coverRange(cm, from, coverStart.to, 0); - } else { - coverRange(cm, from, coverStart.from, 0); - } - } - - while (cmp(to, coverEnd.to) < 0) { - array.pop().clear(); - coverEnd = array[array.length - 1].find(); - } - if (cmp(to, coverEnd.to) > 0) { - if (to.line - coverEnd.from.line < CHUNK_SIZE) { - array.pop().clear(); - coverRange(cm, coverEnd.from, to); - } else { - coverRange(cm, coverEnd.to, to); - } - } - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Because sometimes you need to mark the selected *text*. +// +// Adds an option 'styleSelectedText' which, when enabled, gives +// selected text the CSS class given as option value, or +// "CodeMirror-selectedtext" when the value is not a string. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.markedSelection = []; + cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; + reset(cm); + cm.on("cursorActivity", onCursorActivity); + cm.on("change", onChange); + } else if (!val && prev) { + cm.off("cursorActivity", onCursorActivity); + cm.off("change", onChange); + clear(cm); + cm.state.markedSelection = cm.state.markedSelectionStyle = null; + } + }); + + function onCursorActivity(cm) { + cm.operation(function() { update(cm); }); + } + + function onChange(cm) { + if (cm.state.markedSelection.length) + cm.operation(function() { clear(cm); }); + } + + var CHUNK_SIZE = 8; + var Pos = CodeMirror.Pos; + var cmp = CodeMirror.cmpPos; + + function coverRange(cm, from, to, addAt) { + if (cmp(from, to) == 0) return; + var array = cm.state.markedSelection; + var cls = cm.state.markedSelectionStyle; + for (var line = from.line;;) { + var start = line == from.line ? from : Pos(line, 0); + var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; + var end = atEnd ? to : Pos(endLine, 0); + var mark = cm.markText(start, end, {className: cls}); + if (addAt == null) array.push(mark); + else array.splice(addAt++, 0, mark); + if (atEnd) break; + line = endLine; + } + } + + function clear(cm) { + var array = cm.state.markedSelection; + for (var i = 0; i < array.length; ++i) array[i].clear(); + array.length = 0; + } + + function reset(cm) { + clear(cm); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) + coverRange(cm, ranges[i].from(), ranges[i].to()); + } + + function update(cm) { + if (!cm.somethingSelected()) return clear(cm); + if (cm.listSelections().length > 1) return reset(cm); + + var from = cm.getCursor("start"), to = cm.getCursor("end"); + + var array = cm.state.markedSelection; + if (!array.length) return coverRange(cm, from, to); + + var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); + if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || + cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) + return reset(cm); + + while (cmp(from, coverStart.from) > 0) { + array.shift().clear(); + coverStart = array[0].find(); + } + if (cmp(from, coverStart.from) < 0) { + if (coverStart.to.line - from.line < CHUNK_SIZE) { + array.shift().clear(); + coverRange(cm, from, coverStart.to, 0); + } else { + coverRange(cm, from, coverStart.from, 0); + } + } + + while (cmp(to, coverEnd.to) < 0) { + array.pop().clear(); + coverEnd = array[array.length - 1].find(); + } + if (cmp(to, coverEnd.to) > 0) { + if (to.line - coverEnd.from.line < CHUNK_SIZE) { + array.pop().clear(); + coverRange(cm, coverEnd.from, to); + } else { + coverRange(cm, coverEnd.to, to); + } + } + } +}); diff --git a/shared/codemirror/addon/selection/selection-pointer.js b/shared/codemirror/addon/selection/selection-pointer.js index ef5e404..4bfd2f7 100644 --- a/shared/codemirror/addon/selection/selection-pointer.js +++ b/shared/codemirror/addon/selection/selection-pointer.js @@ -1,98 +1,98 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("selectionPointer", false, function(cm, val) { - var data = cm.state.selectionPointer; - if (data) { - CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); - CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout); - CodeMirror.off(window, "scroll", data.windowScroll); - cm.off("cursorActivity", reset); - cm.off("scroll", reset); - cm.state.selectionPointer = null; - cm.display.lineDiv.style.cursor = ""; - } - if (val) { - data = cm.state.selectionPointer = { - value: typeof val == "string" ? val : "default", - mousemove: function(event) { mousemove(cm, event); }, - mouseout: function(event) { mouseout(cm, event); }, - windowScroll: function() { reset(cm); }, - rects: null, - mouseX: null, mouseY: null, - willUpdate: false - }; - CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); - CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout); - CodeMirror.on(window, "scroll", data.windowScroll); - cm.on("cursorActivity", reset); - cm.on("scroll", reset); - } - }); - - function mousemove(cm, event) { - var data = cm.state.selectionPointer; - if (event.buttons == null ? event.which : event.buttons) { - data.mouseX = data.mouseY = null; - } else { - data.mouseX = event.clientX; - data.mouseY = event.clientY; - } - scheduleUpdate(cm); - } - - function mouseout(cm, event) { - if (!cm.getWrapperElement().contains(event.relatedTarget)) { - var data = cm.state.selectionPointer; - data.mouseX = data.mouseY = null; - scheduleUpdate(cm); - } - } - - function reset(cm) { - cm.state.selectionPointer.rects = null; - scheduleUpdate(cm); - } - - function scheduleUpdate(cm) { - if (!cm.state.selectionPointer.willUpdate) { - cm.state.selectionPointer.willUpdate = true; - setTimeout(function() { - update(cm); - cm.state.selectionPointer.willUpdate = false; - }, 50); - } - } - - function update(cm) { - var data = cm.state.selectionPointer; - if (!data) return; - if (data.rects == null && data.mouseX != null) { - data.rects = []; - if (cm.somethingSelected()) { - for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) - data.rects.push(sel.getBoundingClientRect()); - } - } - var inside = false; - if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) { - var rect = data.rects[i]; - if (rect.left <= data.mouseX && rect.right >= data.mouseX && - rect.top <= data.mouseY && rect.bottom >= data.mouseY) - inside = true; - } - var cursor = inside ? data.value : ""; - if (cm.display.lineDiv.style.cursor != cursor) - cm.display.lineDiv.style.cursor = cursor; - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("selectionPointer", false, function(cm, val) { + var data = cm.state.selectionPointer; + if (data) { + CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); + CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout); + CodeMirror.off(window, "scroll", data.windowScroll); + cm.off("cursorActivity", reset); + cm.off("scroll", reset); + cm.state.selectionPointer = null; + cm.display.lineDiv.style.cursor = ""; + } + if (val) { + data = cm.state.selectionPointer = { + value: typeof val == "string" ? val : "default", + mousemove: function(event) { mousemove(cm, event); }, + mouseout: function(event) { mouseout(cm, event); }, + windowScroll: function() { reset(cm); }, + rects: null, + mouseX: null, mouseY: null, + willUpdate: false + }; + CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); + CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout); + CodeMirror.on(window, "scroll", data.windowScroll); + cm.on("cursorActivity", reset); + cm.on("scroll", reset); + } + }); + + function mousemove(cm, event) { + var data = cm.state.selectionPointer; + if (event.buttons == null ? event.which : event.buttons) { + data.mouseX = data.mouseY = null; + } else { + data.mouseX = event.clientX; + data.mouseY = event.clientY; + } + scheduleUpdate(cm); + } + + function mouseout(cm, event) { + if (!cm.getWrapperElement().contains(event.relatedTarget)) { + var data = cm.state.selectionPointer; + data.mouseX = data.mouseY = null; + scheduleUpdate(cm); + } + } + + function reset(cm) { + cm.state.selectionPointer.rects = null; + scheduleUpdate(cm); + } + + function scheduleUpdate(cm) { + if (!cm.state.selectionPointer.willUpdate) { + cm.state.selectionPointer.willUpdate = true; + setTimeout(function() { + update(cm); + cm.state.selectionPointer.willUpdate = false; + }, 50); + } + } + + function update(cm) { + var data = cm.state.selectionPointer; + if (!data) return; + if (data.rects == null && data.mouseX != null) { + data.rects = []; + if (cm.somethingSelected()) { + for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) + data.rects.push(sel.getBoundingClientRect()); + } + } + var inside = false; + if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) { + var rect = data.rects[i]; + if (rect.left <= data.mouseX && rect.right >= data.mouseX && + rect.top <= data.mouseY && rect.bottom >= data.mouseY) + inside = true; + } + var cursor = inside ? data.value : ""; + if (cm.display.lineDiv.style.cursor != cursor) + cm.display.lineDiv.style.cursor = cursor; + } +}); diff --git a/shared/codemirror/addon/tern/tern.css b/shared/codemirror/addon/tern/tern.css index c4b8a2f..0d2bfbf 100644 --- a/shared/codemirror/addon/tern/tern.css +++ b/shared/codemirror/addon/tern/tern.css @@ -1,87 +1,87 @@ -.CodeMirror-Tern-completion { - padding-left: 22px; - position: relative; - line-height: 1.5; -} -.CodeMirror-Tern-completion:before { - position: absolute; - left: 2px; - bottom: 2px; - border-radius: 50%; - font-size: 12px; - font-weight: bold; - height: 15px; - width: 15px; - line-height: 16px; - text-align: center; - color: white; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.CodeMirror-Tern-completion-unknown:before { - content: "?"; - background: #4bb; -} -.CodeMirror-Tern-completion-object:before { - content: "O"; - background: #77c; -} -.CodeMirror-Tern-completion-fn:before { - content: "F"; - background: #7c7; -} -.CodeMirror-Tern-completion-array:before { - content: "A"; - background: #c66; -} -.CodeMirror-Tern-completion-number:before { - content: "1"; - background: #999; -} -.CodeMirror-Tern-completion-string:before { - content: "S"; - background: #999; -} -.CodeMirror-Tern-completion-bool:before { - content: "B"; - background: #999; -} - -.CodeMirror-Tern-completion-guess { - color: #999; -} - -.CodeMirror-Tern-tooltip { - border: 1px solid silver; - border-radius: 3px; - color: #444; - padding: 2px 5px; - font-size: 90%; - font-family: monospace; - background-color: white; - white-space: pre-wrap; - - max-width: 40em; - position: absolute; - z-index: 10; - -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - - transition: opacity 1s; - -moz-transition: opacity 1s; - -webkit-transition: opacity 1s; - -o-transition: opacity 1s; - -ms-transition: opacity 1s; -} - -.CodeMirror-Tern-hint-doc { - max-width: 25em; - margin-top: -3px; -} - -.CodeMirror-Tern-fname { color: black; } -.CodeMirror-Tern-farg { color: #70a; } -.CodeMirror-Tern-farg-current { text-decoration: underline; } -.CodeMirror-Tern-type { color: #07c; } -.CodeMirror-Tern-fhint-guess { opacity: .7; } +.CodeMirror-Tern-completion { + padding-left: 22px; + position: relative; + line-height: 1.5; +} +.CodeMirror-Tern-completion:before { + position: absolute; + left: 2px; + bottom: 2px; + border-radius: 50%; + font-size: 12px; + font-weight: bold; + height: 15px; + width: 15px; + line-height: 16px; + text-align: center; + color: white; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.CodeMirror-Tern-completion-unknown:before { + content: "?"; + background: #4bb; +} +.CodeMirror-Tern-completion-object:before { + content: "O"; + background: #77c; +} +.CodeMirror-Tern-completion-fn:before { + content: "F"; + background: #7c7; +} +.CodeMirror-Tern-completion-array:before { + content: "A"; + background: #c66; +} +.CodeMirror-Tern-completion-number:before { + content: "1"; + background: #999; +} +.CodeMirror-Tern-completion-string:before { + content: "S"; + background: #999; +} +.CodeMirror-Tern-completion-bool:before { + content: "B"; + background: #999; +} + +.CodeMirror-Tern-completion-guess { + color: #999; +} + +.CodeMirror-Tern-tooltip { + border: 1px solid silver; + border-radius: 3px; + color: #444; + padding: 2px 5px; + font-size: 90%; + font-family: monospace; + background-color: white; + white-space: pre-wrap; + + max-width: 40em; + position: absolute; + z-index: 10; + -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + + transition: opacity 1s; + -moz-transition: opacity 1s; + -webkit-transition: opacity 1s; + -o-transition: opacity 1s; + -ms-transition: opacity 1s; +} + +.CodeMirror-Tern-hint-doc { + max-width: 25em; + margin-top: -3px; +} + +.CodeMirror-Tern-fname { color: black; } +.CodeMirror-Tern-farg { color: #70a; } +.CodeMirror-Tern-farg-current { text-decoration: underline; } +.CodeMirror-Tern-type { color: #07c; } +.CodeMirror-Tern-fhint-guess { opacity: .7; } diff --git a/shared/codemirror/addon/tern/tern.js b/shared/codemirror/addon/tern/tern.js index efdf2ed..c0d52f5 100644 --- a/shared/codemirror/addon/tern/tern.js +++ b/shared/codemirror/addon/tern/tern.js @@ -1,701 +1,701 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Glue code between CodeMirror and Tern. -// -// Create a CodeMirror.TernServer to wrap an actual Tern server, -// register open documents (CodeMirror.Doc instances) with it, and -// call its methods to activate the assisting functions that Tern -// provides. -// -// Options supported (all optional): -// * defs: An array of JSON definition data structures. -// * plugins: An object mapping plugin names to configuration -// options. -// * getFile: A function(name, c) that can be used to access files in -// the project that haven't been loaded yet. Simply do c(null) to -// indicate that a file is not available. -// * fileFilter: A function(value, docName, doc) that will be applied -// to documents before passing them on to Tern. -// * switchToDoc: A function(name, doc) that should, when providing a -// multi-file view, switch the view or focus to the named file. -// * showError: A function(editor, message) that can be used to -// override the way errors are displayed. -// * completionTip: Customize the content in tooltips for completions. -// Is passed a single argument—the completion's data as returned by -// Tern—and may return a string, DOM node, or null to indicate that -// no tip should be shown. By default the docstring is shown. -// * typeTip: Like completionTip, but for the tooltips shown for type -// queries. -// * responseFilter: A function(doc, query, request, error, data) that -// will be applied to the Tern responses before treating them -// -// -// It is possible to run the Tern server in a web worker by specifying -// these additional options: -// * useWorker: Set to true to enable web worker mode. You'll probably -// want to feature detect the actual value you use here, for example -// !!window.Worker. -// * workerScript: The main script of the worker. Point this to -// wherever you are hosting worker.js from this directory. -// * workerDeps: An array of paths pointing (relative to workerScript) -// to the Acorn and Tern libraries and any Tern plugins you want to -// load. Or, if you minified those into a single script and included -// them in the workerScript, simply leave this undefined. - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - // declare global: tern - - CodeMirror.TernServer = function(options) { - var self = this; - this.options = options || {}; - var plugins = this.options.plugins || (this.options.plugins = {}); - if (!plugins.doc_comment) plugins.doc_comment = true; - this.docs = Object.create(null); - if (this.options.useWorker) { - this.server = new WorkerServer(this); - } else { - this.server = new tern.Server({ - getFile: function(name, c) { return getFile(self, name, c); }, - async: true, - defs: this.options.defs || [], - plugins: plugins - }); - } - this.trackChange = function(doc, change) { trackChange(self, doc, change); }; - - this.cachedArgHints = null; - this.activeArgHints = null; - this.jumpStack = []; - - this.getHint = function(cm, c) { return hint(self, cm, c); }; - this.getHint.async = true; - }; - - CodeMirror.TernServer.prototype = { - addDoc: function(name, doc) { - var data = {doc: doc, name: name, changed: null}; - this.server.addFile(name, docValue(this, data)); - CodeMirror.on(doc, "change", this.trackChange); - return this.docs[name] = data; - }, - - delDoc: function(id) { - var found = resolveDoc(this, id); - if (!found) return; - CodeMirror.off(found.doc, "change", this.trackChange); - delete this.docs[found.name]; - this.server.delFile(found.name); - }, - - hideDoc: function(id) { - closeArgHints(this); - var found = resolveDoc(this, id); - if (found && found.changed) sendDoc(this, found); - }, - - complete: function(cm) { - cm.showHint({hint: this.getHint}); - }, - - showType: function(cm, pos, c) { showContextInfo(this, cm, pos, "type", c); }, - - showDocs: function(cm, pos, c) { showContextInfo(this, cm, pos, "documentation", c); }, - - updateArgHints: function(cm) { updateArgHints(this, cm); }, - - jumpToDef: function(cm) { jumpToDef(this, cm); }, - - jumpBack: function(cm) { jumpBack(this, cm); }, - - rename: function(cm) { rename(this, cm); }, - - selectName: function(cm) { selectName(this, cm); }, - - request: function (cm, query, c, pos) { - var self = this; - var doc = findDoc(this, cm.getDoc()); - var request = buildRequest(this, doc, query, pos); - var extraOptions = request.query && this.options.queryOptions && this.options.queryOptions[request.query.type] - if (extraOptions) for (var prop in extraOptions) request.query[prop] = extraOptions[prop]; - - this.server.request(request, function (error, data) { - if (!error && self.options.responseFilter) - data = self.options.responseFilter(doc, query, request, error, data); - c(error, data); - }); - }, - - destroy: function () { - closeArgHints(this) - if (this.worker) { - this.worker.terminate(); - this.worker = null; - } - } - }; - - var Pos = CodeMirror.Pos; - var cls = "CodeMirror-Tern-"; - var bigDoc = 250; - - function getFile(ts, name, c) { - var buf = ts.docs[name]; - if (buf) - c(docValue(ts, buf)); - else if (ts.options.getFile) - ts.options.getFile(name, c); - else - c(null); - } - - function findDoc(ts, doc, name) { - for (var n in ts.docs) { - var cur = ts.docs[n]; - if (cur.doc == doc) return cur; - } - if (!name) for (var i = 0;; ++i) { - n = "[doc" + (i || "") + "]"; - if (!ts.docs[n]) { name = n; break; } - } - return ts.addDoc(name, doc); - } - - function resolveDoc(ts, id) { - if (typeof id == "string") return ts.docs[id]; - if (id instanceof CodeMirror) id = id.getDoc(); - if (id instanceof CodeMirror.Doc) return findDoc(ts, id); - } - - function trackChange(ts, doc, change) { - var data = findDoc(ts, doc); - - var argHints = ts.cachedArgHints; - if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0) - ts.cachedArgHints = null; - - var changed = data.changed; - if (changed == null) - data.changed = changed = {from: change.from.line, to: change.from.line}; - var end = change.from.line + (change.text.length - 1); - if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end); - if (end >= changed.to) changed.to = end + 1; - if (changed.from > change.from.line) changed.from = change.from.line; - - if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() { - if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data); - }, 200); - } - - function sendDoc(ts, doc) { - ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) { - if (error) window.console.error(error); - else doc.changed = null; - }); - } - - // Completion - - function hint(ts, cm, c) { - ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) { - if (error) return showError(ts, cm, error); - var completions = [], after = ""; - var from = data.start, to = data.end; - if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" && - cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]") - after = "\"]"; - - for (var i = 0; i < data.completions.length; ++i) { - var completion = data.completions[i], className = typeToIcon(completion.type); - if (data.guess) className += " " + cls + "guess"; - completions.push({text: completion.name + after, - displayText: completion.displayName || completion.name, - className: className, - data: completion}); - } - - var obj = {from: from, to: to, list: completions}; - var tooltip = null; - CodeMirror.on(obj, "close", function() { remove(tooltip); }); - CodeMirror.on(obj, "update", function() { remove(tooltip); }); - CodeMirror.on(obj, "select", function(cur, node) { - remove(tooltip); - var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc; - if (content) { - tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset, - node.getBoundingClientRect().top + window.pageYOffset, content); - tooltip.className += " " + cls + "hint-doc"; - } - }); - c(obj); - }); - } - - function typeToIcon(type) { - var suffix; - if (type == "?") suffix = "unknown"; - else if (type == "number" || type == "string" || type == "bool") suffix = type; - else if (/^fn\(/.test(type)) suffix = "fn"; - else if (/^\[/.test(type)) suffix = "array"; - else suffix = "object"; - return cls + "completion " + cls + "completion-" + suffix; - } - - // Type queries - - function showContextInfo(ts, cm, pos, queryName, c) { - ts.request(cm, queryName, function(error, data) { - if (error) return showError(ts, cm, error); - if (ts.options.typeTip) { - var tip = ts.options.typeTip(data); - } else { - var tip = elt("span", null, elt("strong", null, data.type || "not found")); - if (data.doc) - tip.appendChild(document.createTextNode(" — " + data.doc)); - if (data.url) { - tip.appendChild(document.createTextNode(" ")); - var child = tip.appendChild(elt("a", null, "[docs]")); - child.href = data.url; - child.target = "_blank"; - } - } - tempTooltip(cm, tip, ts); - if (c) c(); - }, pos); - } - - // Maintaining argument hints - - function updateArgHints(ts, cm) { - closeArgHints(ts); - - if (cm.somethingSelected()) return; - var state = cm.getTokenAt(cm.getCursor()).state; - var inner = CodeMirror.innerMode(cm.getMode(), state); - if (inner.mode.name != "javascript") return; - var lex = inner.state.lexical; - if (lex.info != "call") return; - - var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize"); - for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) { - var str = cm.getLine(line), extra = 0; - for (var pos = 0;;) { - var tab = str.indexOf("\t", pos); - if (tab == -1) break; - extra += tabSize - (tab + extra) % tabSize - 1; - pos = tab + 1; - } - ch = lex.column - extra; - if (str.charAt(ch) == "(") {found = true; break;} - } - if (!found) return; - - var start = Pos(line, ch); - var cache = ts.cachedArgHints; - if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0) - return showArgHints(ts, cm, argPos); - - ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) { - if (error || !data.type || !(/^fn\(/).test(data.type)) return; - ts.cachedArgHints = { - start: start, - type: parseFnType(data.type), - name: data.exprName || data.name || "fn", - guess: data.guess, - doc: cm.getDoc() - }; - showArgHints(ts, cm, argPos); - }); - } - - function showArgHints(ts, cm, pos) { - closeArgHints(ts); - - var cache = ts.cachedArgHints, tp = cache.type; - var tip = elt("span", cache.guess ? cls + "fhint-guess" : null, - elt("span", cls + "fname", cache.name), "("); - for (var i = 0; i < tp.args.length; ++i) { - if (i) tip.appendChild(document.createTextNode(", ")); - var arg = tp.args[i]; - tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?")); - if (arg.type != "?") { - tip.appendChild(document.createTextNode(":\u00a0")); - tip.appendChild(elt("span", cls + "type", arg.type)); - } - } - tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")")); - if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype)); - var place = cm.cursorCoords(null, "page"); - ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip); - } - - function parseFnType(text) { - var args = [], pos = 3; - - function skipMatching(upto) { - var depth = 0, start = pos; - for (;;) { - var next = text.charAt(pos); - if (upto.test(next) && !depth) return text.slice(start, pos); - if (/[{\[\(]/.test(next)) ++depth; - else if (/[}\]\)]/.test(next)) --depth; - ++pos; - } - } - - // Parse arguments - if (text.charAt(pos) != ")") for (;;) { - var name = text.slice(pos).match(/^([^, \(\[\{]+): /); - if (name) { - pos += name[0].length; - name = name[1]; - } - args.push({name: name, type: skipMatching(/[\),]/)}); - if (text.charAt(pos) == ")") break; - pos += 2; - } - - var rettype = text.slice(pos).match(/^\) -> (.*)$/); - - return {args: args, rettype: rettype && rettype[1]}; - } - - // Moving to the definition of something - - function jumpToDef(ts, cm) { - function inner(varName) { - var req = {type: "definition", variable: varName || null}; - var doc = findDoc(ts, cm.getDoc()); - ts.server.request(buildRequest(ts, doc, req), function(error, data) { - if (error) return showError(ts, cm, error); - if (!data.file && data.url) { window.open(data.url); return; } - - if (data.file) { - var localDoc = ts.docs[data.file], found; - if (localDoc && (found = findContext(localDoc.doc, data))) { - ts.jumpStack.push({file: doc.name, - start: cm.getCursor("from"), - end: cm.getCursor("to")}); - moveTo(ts, doc, localDoc, found.start, found.end); - return; - } - } - showError(ts, cm, "Could not find a definition."); - }); - } - - if (!atInterestingExpression(cm)) - dialog(cm, "Jump to variable", function(name) { if (name) inner(name); }); - else - inner(); - } - - function jumpBack(ts, cm) { - var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file]; - if (!doc) return; - moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end); - } - - function moveTo(ts, curDoc, doc, start, end) { - doc.doc.setSelection(start, end); - if (curDoc != doc && ts.options.switchToDoc) { - closeArgHints(ts); - ts.options.switchToDoc(doc.name, doc.doc); - } - } - - // The {line,ch} representation of positions makes this rather awkward. - function findContext(doc, data) { - var before = data.context.slice(0, data.contextOffset).split("\n"); - var startLine = data.start.line - (before.length - 1); - var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length); - - var text = doc.getLine(startLine).slice(start.ch); - for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur) - text += "\n" + doc.getLine(cur); - if (text.slice(0, data.context.length) == data.context) return data; - - var cursor = doc.getSearchCursor(data.context, 0, false); - var nearest, nearestDist = Infinity; - while (cursor.findNext()) { - var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000; - if (!dist) dist = Math.abs(from.ch - start.ch); - if (dist < nearestDist) { nearest = from; nearestDist = dist; } - } - if (!nearest) return null; - - if (before.length == 1) - nearest.ch += before[0].length; - else - nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length); - if (data.start.line == data.end.line) - var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch)); - else - var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch); - return {start: nearest, end: end}; - } - - function atInterestingExpression(cm) { - var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos); - if (tok.start < pos.ch && tok.type == "comment") return false; - return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); - } - - // Variable renaming - - function rename(ts, cm) { - var token = cm.getTokenAt(cm.getCursor()); - if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable"); - dialog(cm, "New name for " + token.string, function(newName) { - ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) { - if (error) return showError(ts, cm, error); - applyChanges(ts, data.changes); - }); - }); - } - - function selectName(ts, cm) { - var name = findDoc(ts, cm.doc).name; - ts.request(cm, {type: "refs"}, function(error, data) { - if (error) return showError(ts, cm, error); - var ranges = [], cur = 0; - var curPos = cm.getCursor(); - for (var i = 0; i < data.refs.length; i++) { - var ref = data.refs[i]; - if (ref.file == name) { - ranges.push({anchor: ref.start, head: ref.end}); - if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0) - cur = ranges.length - 1; - } - } - cm.setSelections(ranges, cur); - }); - } - - var nextChangeOrig = 0; - function applyChanges(ts, changes) { - var perFile = Object.create(null); - for (var i = 0; i < changes.length; ++i) { - var ch = changes[i]; - (perFile[ch.file] || (perFile[ch.file] = [])).push(ch); - } - for (var file in perFile) { - var known = ts.docs[file], chs = perFile[file];; - if (!known) continue; - chs.sort(function(a, b) { return cmpPos(b.start, a.start); }); - var origin = "*rename" + (++nextChangeOrig); - for (var i = 0; i < chs.length; ++i) { - var ch = chs[i]; - known.doc.replaceRange(ch.text, ch.start, ch.end, origin); - } - } - } - - // Generic request-building helper - - function buildRequest(ts, doc, query, pos) { - var files = [], offsetLines = 0, allowFragments = !query.fullDocs; - if (!allowFragments) delete query.fullDocs; - if (typeof query == "string") query = {type: query}; - query.lineCharPositions = true; - if (query.end == null) { - query.end = pos || doc.doc.getCursor("end"); - if (doc.doc.somethingSelected()) - query.start = doc.doc.getCursor("start"); - } - var startPos = query.start || query.end; - - if (doc.changed) { - if (doc.doc.lineCount() > bigDoc && allowFragments !== false && - doc.changed.to - doc.changed.from < 100 && - doc.changed.from <= startPos.line && doc.changed.to > query.end.line) { - files.push(getFragmentAround(doc, startPos, query.end)); - query.file = "#0"; - var offsetLines = files[0].offsetLines; - if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch); - query.end = Pos(query.end.line - offsetLines, query.end.ch); - } else { - files.push({type: "full", - name: doc.name, - text: docValue(ts, doc)}); - query.file = doc.name; - doc.changed = null; - } - } else { - query.file = doc.name; - } - for (var name in ts.docs) { - var cur = ts.docs[name]; - if (cur.changed && cur != doc) { - files.push({type: "full", name: cur.name, text: docValue(ts, cur)}); - cur.changed = null; - } - } - - return {query: query, files: files}; - } - - function getFragmentAround(data, start, end) { - var doc = data.doc; - var minIndent = null, minLine = null, endLine, tabSize = 4; - for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) { - var line = doc.getLine(p), fn = line.search(/\bfunction\b/); - if (fn < 0) continue; - var indent = CodeMirror.countColumn(line, null, tabSize); - if (minIndent != null && minIndent <= indent) continue; - minIndent = indent; - minLine = p; - } - if (minLine == null) minLine = min; - var max = Math.min(doc.lastLine(), end.line + 20); - if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize)) - endLine = max; - else for (endLine = end.line + 1; endLine < max; ++endLine) { - var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize); - if (indent <= minIndent) break; - } - var from = Pos(minLine, 0); - - return {type: "part", - name: data.name, - offsetLines: from.line, - text: doc.getRange(from, Pos(endLine, 0))}; - } - - // Generic utilities - - var cmpPos = CodeMirror.cmpPos; - - function elt(tagname, cls /*, ... elts*/) { - var e = document.createElement(tagname); - if (cls) e.className = cls; - for (var i = 2; i < arguments.length; ++i) { - var elt = arguments[i]; - if (typeof elt == "string") elt = document.createTextNode(elt); - e.appendChild(elt); - } - return e; - } - - function dialog(cm, text, f) { - if (cm.openDialog) - cm.openDialog(text + ": ", f); - else - f(prompt(text, "")); - } - - // Tooltips - - function tempTooltip(cm, content, ts) { - if (cm.state.ternTooltip) remove(cm.state.ternTooltip); - var where = cm.cursorCoords(); - var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content); - function maybeClear() { - old = true; - if (!mouseOnTip) clear(); - } - function clear() { - cm.state.ternTooltip = null; - if (!tip.parentNode) return; - cm.off("cursorActivity", clear); - cm.off('blur', clear); - cm.off('scroll', clear); - fadeOut(tip); - } - var mouseOnTip = false, old = false; - CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; }); - CodeMirror.on(tip, "mouseout", function(e) { - if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) { - if (old) clear(); - else mouseOnTip = false; - } - }); - setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700); - cm.on("cursorActivity", clear); - cm.on('blur', clear); - cm.on('scroll', clear); - } - - function makeTooltip(x, y, content) { - var node = elt("div", cls + "tooltip", content); - node.style.left = x + "px"; - node.style.top = y + "px"; - document.body.appendChild(node); - return node; - } - - function remove(node) { - var p = node && node.parentNode; - if (p) p.removeChild(node); - } - - function fadeOut(tooltip) { - tooltip.style.opacity = "0"; - setTimeout(function() { remove(tooltip); }, 1100); - } - - function showError(ts, cm, msg) { - if (ts.options.showError) - ts.options.showError(cm, msg); - else - tempTooltip(cm, String(msg), ts); - } - - function closeArgHints(ts) { - if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; } - } - - function docValue(ts, doc) { - var val = doc.doc.getValue(); - if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc); - return val; - } - - // Worker wrapper - - function WorkerServer(ts) { - var worker = ts.worker = new Worker(ts.options.workerScript); - worker.postMessage({type: "init", - defs: ts.options.defs, - plugins: ts.options.plugins, - scripts: ts.options.workerDeps}); - var msgId = 0, pending = {}; - - function send(data, c) { - if (c) { - data.id = ++msgId; - pending[msgId] = c; - } - worker.postMessage(data); - } - worker.onmessage = function(e) { - var data = e.data; - if (data.type == "getFile") { - getFile(ts, data.name, function(err, text) { - send({type: "getFile", err: String(err), text: text, id: data.id}); - }); - } else if (data.type == "debug") { - window.console.log(data.message); - } else if (data.id && pending[data.id]) { - pending[data.id](data.err, data.body); - delete pending[data.id]; - } - }; - worker.onerror = function(e) { - for (var id in pending) pending[id](e); - pending = {}; - }; - - this.addFile = function(name, text) { send({type: "add", name: name, text: text}); }; - this.delFile = function(name) { send({type: "del", name: name}); }; - this.request = function(body, c) { send({type: "req", body: body}, c); }; - } -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Glue code between CodeMirror and Tern. +// +// Create a CodeMirror.TernServer to wrap an actual Tern server, +// register open documents (CodeMirror.Doc instances) with it, and +// call its methods to activate the assisting functions that Tern +// provides. +// +// Options supported (all optional): +// * defs: An array of JSON definition data structures. +// * plugins: An object mapping plugin names to configuration +// options. +// * getFile: A function(name, c) that can be used to access files in +// the project that haven't been loaded yet. Simply do c(null) to +// indicate that a file is not available. +// * fileFilter: A function(value, docName, doc) that will be applied +// to documents before passing them on to Tern. +// * switchToDoc: A function(name, doc) that should, when providing a +// multi-file view, switch the view or focus to the named file. +// * showError: A function(editor, message) that can be used to +// override the way errors are displayed. +// * completionTip: Customize the content in tooltips for completions. +// Is passed a single argument—the completion's data as returned by +// Tern—and may return a string, DOM node, or null to indicate that +// no tip should be shown. By default the docstring is shown. +// * typeTip: Like completionTip, but for the tooltips shown for type +// queries. +// * responseFilter: A function(doc, query, request, error, data) that +// will be applied to the Tern responses before treating them +// +// +// It is possible to run the Tern server in a web worker by specifying +// these additional options: +// * useWorker: Set to true to enable web worker mode. You'll probably +// want to feature detect the actual value you use here, for example +// !!window.Worker. +// * workerScript: The main script of the worker. Point this to +// wherever you are hosting worker.js from this directory. +// * workerDeps: An array of paths pointing (relative to workerScript) +// to the Acorn and Tern libraries and any Tern plugins you want to +// load. Or, if you minified those into a single script and included +// them in the workerScript, simply leave this undefined. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + // declare global: tern + + CodeMirror.TernServer = function(options) { + var self = this; + this.options = options || {}; + var plugins = this.options.plugins || (this.options.plugins = {}); + if (!plugins.doc_comment) plugins.doc_comment = true; + this.docs = Object.create(null); + if (this.options.useWorker) { + this.server = new WorkerServer(this); + } else { + this.server = new tern.Server({ + getFile: function(name, c) { return getFile(self, name, c); }, + async: true, + defs: this.options.defs || [], + plugins: plugins + }); + } + this.trackChange = function(doc, change) { trackChange(self, doc, change); }; + + this.cachedArgHints = null; + this.activeArgHints = null; + this.jumpStack = []; + + this.getHint = function(cm, c) { return hint(self, cm, c); }; + this.getHint.async = true; + }; + + CodeMirror.TernServer.prototype = { + addDoc: function(name, doc) { + var data = {doc: doc, name: name, changed: null}; + this.server.addFile(name, docValue(this, data)); + CodeMirror.on(doc, "change", this.trackChange); + return this.docs[name] = data; + }, + + delDoc: function(id) { + var found = resolveDoc(this, id); + if (!found) return; + CodeMirror.off(found.doc, "change", this.trackChange); + delete this.docs[found.name]; + this.server.delFile(found.name); + }, + + hideDoc: function(id) { + closeArgHints(this); + var found = resolveDoc(this, id); + if (found && found.changed) sendDoc(this, found); + }, + + complete: function(cm) { + cm.showHint({hint: this.getHint}); + }, + + showType: function(cm, pos, c) { showContextInfo(this, cm, pos, "type", c); }, + + showDocs: function(cm, pos, c) { showContextInfo(this, cm, pos, "documentation", c); }, + + updateArgHints: function(cm) { updateArgHints(this, cm); }, + + jumpToDef: function(cm) { jumpToDef(this, cm); }, + + jumpBack: function(cm) { jumpBack(this, cm); }, + + rename: function(cm) { rename(this, cm); }, + + selectName: function(cm) { selectName(this, cm); }, + + request: function (cm, query, c, pos) { + var self = this; + var doc = findDoc(this, cm.getDoc()); + var request = buildRequest(this, doc, query, pos); + var extraOptions = request.query && this.options.queryOptions && this.options.queryOptions[request.query.type] + if (extraOptions) for (var prop in extraOptions) request.query[prop] = extraOptions[prop]; + + this.server.request(request, function (error, data) { + if (!error && self.options.responseFilter) + data = self.options.responseFilter(doc, query, request, error, data); + c(error, data); + }); + }, + + destroy: function () { + closeArgHints(this) + if (this.worker) { + this.worker.terminate(); + this.worker = null; + } + } + }; + + var Pos = CodeMirror.Pos; + var cls = "CodeMirror-Tern-"; + var bigDoc = 250; + + function getFile(ts, name, c) { + var buf = ts.docs[name]; + if (buf) + c(docValue(ts, buf)); + else if (ts.options.getFile) + ts.options.getFile(name, c); + else + c(null); + } + + function findDoc(ts, doc, name) { + for (var n in ts.docs) { + var cur = ts.docs[n]; + if (cur.doc == doc) return cur; + } + if (!name) for (var i = 0;; ++i) { + n = "[doc" + (i || "") + "]"; + if (!ts.docs[n]) { name = n; break; } + } + return ts.addDoc(name, doc); + } + + function resolveDoc(ts, id) { + if (typeof id == "string") return ts.docs[id]; + if (id instanceof CodeMirror) id = id.getDoc(); + if (id instanceof CodeMirror.Doc) return findDoc(ts, id); + } + + function trackChange(ts, doc, change) { + var data = findDoc(ts, doc); + + var argHints = ts.cachedArgHints; + if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0) + ts.cachedArgHints = null; + + var changed = data.changed; + if (changed == null) + data.changed = changed = {from: change.from.line, to: change.from.line}; + var end = change.from.line + (change.text.length - 1); + if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end); + if (end >= changed.to) changed.to = end + 1; + if (changed.from > change.from.line) changed.from = change.from.line; + + if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() { + if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data); + }, 200); + } + + function sendDoc(ts, doc) { + ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) { + if (error) window.console.error(error); + else doc.changed = null; + }); + } + + // Completion + + function hint(ts, cm, c) { + ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) { + if (error) return showError(ts, cm, error); + var completions = [], after = ""; + var from = data.start, to = data.end; + if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" && + cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]") + after = "\"]"; + + for (var i = 0; i < data.completions.length; ++i) { + var completion = data.completions[i], className = typeToIcon(completion.type); + if (data.guess) className += " " + cls + "guess"; + completions.push({text: completion.name + after, + displayText: completion.displayName || completion.name, + className: className, + data: completion}); + } + + var obj = {from: from, to: to, list: completions}; + var tooltip = null; + CodeMirror.on(obj, "close", function() { remove(tooltip); }); + CodeMirror.on(obj, "update", function() { remove(tooltip); }); + CodeMirror.on(obj, "select", function(cur, node) { + remove(tooltip); + var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc; + if (content) { + tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset, + node.getBoundingClientRect().top + window.pageYOffset, content); + tooltip.className += " " + cls + "hint-doc"; + } + }); + c(obj); + }); + } + + function typeToIcon(type) { + var suffix; + if (type == "?") suffix = "unknown"; + else if (type == "number" || type == "string" || type == "bool") suffix = type; + else if (/^fn\(/.test(type)) suffix = "fn"; + else if (/^\[/.test(type)) suffix = "array"; + else suffix = "object"; + return cls + "completion " + cls + "completion-" + suffix; + } + + // Type queries + + function showContextInfo(ts, cm, pos, queryName, c) { + ts.request(cm, queryName, function(error, data) { + if (error) return showError(ts, cm, error); + if (ts.options.typeTip) { + var tip = ts.options.typeTip(data); + } else { + var tip = elt("span", null, elt("strong", null, data.type || "not found")); + if (data.doc) + tip.appendChild(document.createTextNode(" — " + data.doc)); + if (data.url) { + tip.appendChild(document.createTextNode(" ")); + var child = tip.appendChild(elt("a", null, "[docs]")); + child.href = data.url; + child.target = "_blank"; + } + } + tempTooltip(cm, tip, ts); + if (c) c(); + }, pos); + } + + // Maintaining argument hints + + function updateArgHints(ts, cm) { + closeArgHints(ts); + + if (cm.somethingSelected()) return; + var state = cm.getTokenAt(cm.getCursor()).state; + var inner = CodeMirror.innerMode(cm.getMode(), state); + if (inner.mode.name != "javascript") return; + var lex = inner.state.lexical; + if (lex.info != "call") return; + + var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize"); + for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) { + var str = cm.getLine(line), extra = 0; + for (var pos = 0;;) { + var tab = str.indexOf("\t", pos); + if (tab == -1) break; + extra += tabSize - (tab + extra) % tabSize - 1; + pos = tab + 1; + } + ch = lex.column - extra; + if (str.charAt(ch) == "(") {found = true; break;} + } + if (!found) return; + + var start = Pos(line, ch); + var cache = ts.cachedArgHints; + if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0) + return showArgHints(ts, cm, argPos); + + ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) { + if (error || !data.type || !(/^fn\(/).test(data.type)) return; + ts.cachedArgHints = { + start: start, + type: parseFnType(data.type), + name: data.exprName || data.name || "fn", + guess: data.guess, + doc: cm.getDoc() + }; + showArgHints(ts, cm, argPos); + }); + } + + function showArgHints(ts, cm, pos) { + closeArgHints(ts); + + var cache = ts.cachedArgHints, tp = cache.type; + var tip = elt("span", cache.guess ? cls + "fhint-guess" : null, + elt("span", cls + "fname", cache.name), "("); + for (var i = 0; i < tp.args.length; ++i) { + if (i) tip.appendChild(document.createTextNode(", ")); + var arg = tp.args[i]; + tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?")); + if (arg.type != "?") { + tip.appendChild(document.createTextNode(":\u00a0")); + tip.appendChild(elt("span", cls + "type", arg.type)); + } + } + tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")")); + if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype)); + var place = cm.cursorCoords(null, "page"); + ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip); + } + + function parseFnType(text) { + var args = [], pos = 3; + + function skipMatching(upto) { + var depth = 0, start = pos; + for (;;) { + var next = text.charAt(pos); + if (upto.test(next) && !depth) return text.slice(start, pos); + if (/[{\[\(]/.test(next)) ++depth; + else if (/[}\]\)]/.test(next)) --depth; + ++pos; + } + } + + // Parse arguments + if (text.charAt(pos) != ")") for (;;) { + var name = text.slice(pos).match(/^([^, \(\[\{]+): /); + if (name) { + pos += name[0].length; + name = name[1]; + } + args.push({name: name, type: skipMatching(/[\),]/)}); + if (text.charAt(pos) == ")") break; + pos += 2; + } + + var rettype = text.slice(pos).match(/^\) -> (.*)$/); + + return {args: args, rettype: rettype && rettype[1]}; + } + + // Moving to the definition of something + + function jumpToDef(ts, cm) { + function inner(varName) { + var req = {type: "definition", variable: varName || null}; + var doc = findDoc(ts, cm.getDoc()); + ts.server.request(buildRequest(ts, doc, req), function(error, data) { + if (error) return showError(ts, cm, error); + if (!data.file && data.url) { window.open(data.url); return; } + + if (data.file) { + var localDoc = ts.docs[data.file], found; + if (localDoc && (found = findContext(localDoc.doc, data))) { + ts.jumpStack.push({file: doc.name, + start: cm.getCursor("from"), + end: cm.getCursor("to")}); + moveTo(ts, doc, localDoc, found.start, found.end); + return; + } + } + showError(ts, cm, "Could not find a definition."); + }); + } + + if (!atInterestingExpression(cm)) + dialog(cm, "Jump to variable", function(name) { if (name) inner(name); }); + else + inner(); + } + + function jumpBack(ts, cm) { + var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file]; + if (!doc) return; + moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end); + } + + function moveTo(ts, curDoc, doc, start, end) { + doc.doc.setSelection(start, end); + if (curDoc != doc && ts.options.switchToDoc) { + closeArgHints(ts); + ts.options.switchToDoc(doc.name, doc.doc); + } + } + + // The {line,ch} representation of positions makes this rather awkward. + function findContext(doc, data) { + var before = data.context.slice(0, data.contextOffset).split("\n"); + var startLine = data.start.line - (before.length - 1); + var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length); + + var text = doc.getLine(startLine).slice(start.ch); + for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur) + text += "\n" + doc.getLine(cur); + if (text.slice(0, data.context.length) == data.context) return data; + + var cursor = doc.getSearchCursor(data.context, 0, false); + var nearest, nearestDist = Infinity; + while (cursor.findNext()) { + var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000; + if (!dist) dist = Math.abs(from.ch - start.ch); + if (dist < nearestDist) { nearest = from; nearestDist = dist; } + } + if (!nearest) return null; + + if (before.length == 1) + nearest.ch += before[0].length; + else + nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length); + if (data.start.line == data.end.line) + var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch)); + else + var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch); + return {start: nearest, end: end}; + } + + function atInterestingExpression(cm) { + var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos); + if (tok.start < pos.ch && tok.type == "comment") return false; + return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); + } + + // Variable renaming + + function rename(ts, cm) { + var token = cm.getTokenAt(cm.getCursor()); + if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable"); + dialog(cm, "New name for " + token.string, function(newName) { + ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) { + if (error) return showError(ts, cm, error); + applyChanges(ts, data.changes); + }); + }); + } + + function selectName(ts, cm) { + var name = findDoc(ts, cm.doc).name; + ts.request(cm, {type: "refs"}, function(error, data) { + if (error) return showError(ts, cm, error); + var ranges = [], cur = 0; + var curPos = cm.getCursor(); + for (var i = 0; i < data.refs.length; i++) { + var ref = data.refs[i]; + if (ref.file == name) { + ranges.push({anchor: ref.start, head: ref.end}); + if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0) + cur = ranges.length - 1; + } + } + cm.setSelections(ranges, cur); + }); + } + + var nextChangeOrig = 0; + function applyChanges(ts, changes) { + var perFile = Object.create(null); + for (var i = 0; i < changes.length; ++i) { + var ch = changes[i]; + (perFile[ch.file] || (perFile[ch.file] = [])).push(ch); + } + for (var file in perFile) { + var known = ts.docs[file], chs = perFile[file];; + if (!known) continue; + chs.sort(function(a, b) { return cmpPos(b.start, a.start); }); + var origin = "*rename" + (++nextChangeOrig); + for (var i = 0; i < chs.length; ++i) { + var ch = chs[i]; + known.doc.replaceRange(ch.text, ch.start, ch.end, origin); + } + } + } + + // Generic request-building helper + + function buildRequest(ts, doc, query, pos) { + var files = [], offsetLines = 0, allowFragments = !query.fullDocs; + if (!allowFragments) delete query.fullDocs; + if (typeof query == "string") query = {type: query}; + query.lineCharPositions = true; + if (query.end == null) { + query.end = pos || doc.doc.getCursor("end"); + if (doc.doc.somethingSelected()) + query.start = doc.doc.getCursor("start"); + } + var startPos = query.start || query.end; + + if (doc.changed) { + if (doc.doc.lineCount() > bigDoc && allowFragments !== false && + doc.changed.to - doc.changed.from < 100 && + doc.changed.from <= startPos.line && doc.changed.to > query.end.line) { + files.push(getFragmentAround(doc, startPos, query.end)); + query.file = "#0"; + var offsetLines = files[0].offsetLines; + if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch); + query.end = Pos(query.end.line - offsetLines, query.end.ch); + } else { + files.push({type: "full", + name: doc.name, + text: docValue(ts, doc)}); + query.file = doc.name; + doc.changed = null; + } + } else { + query.file = doc.name; + } + for (var name in ts.docs) { + var cur = ts.docs[name]; + if (cur.changed && cur != doc) { + files.push({type: "full", name: cur.name, text: docValue(ts, cur)}); + cur.changed = null; + } + } + + return {query: query, files: files}; + } + + function getFragmentAround(data, start, end) { + var doc = data.doc; + var minIndent = null, minLine = null, endLine, tabSize = 4; + for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) { + var line = doc.getLine(p), fn = line.search(/\bfunction\b/); + if (fn < 0) continue; + var indent = CodeMirror.countColumn(line, null, tabSize); + if (minIndent != null && minIndent <= indent) continue; + minIndent = indent; + minLine = p; + } + if (minLine == null) minLine = min; + var max = Math.min(doc.lastLine(), end.line + 20); + if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize)) + endLine = max; + else for (endLine = end.line + 1; endLine < max; ++endLine) { + var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize); + if (indent <= minIndent) break; + } + var from = Pos(minLine, 0); + + return {type: "part", + name: data.name, + offsetLines: from.line, + text: doc.getRange(from, Pos(endLine, 0))}; + } + + // Generic utilities + + var cmpPos = CodeMirror.cmpPos; + + function elt(tagname, cls /*, ... elts*/) { + var e = document.createElement(tagname); + if (cls) e.className = cls; + for (var i = 2; i < arguments.length; ++i) { + var elt = arguments[i]; + if (typeof elt == "string") elt = document.createTextNode(elt); + e.appendChild(elt); + } + return e; + } + + function dialog(cm, text, f) { + if (cm.openDialog) + cm.openDialog(text + ": ", f); + else + f(prompt(text, "")); + } + + // Tooltips + + function tempTooltip(cm, content, ts) { + if (cm.state.ternTooltip) remove(cm.state.ternTooltip); + var where = cm.cursorCoords(); + var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content); + function maybeClear() { + old = true; + if (!mouseOnTip) clear(); + } + function clear() { + cm.state.ternTooltip = null; + if (!tip.parentNode) return; + cm.off("cursorActivity", clear); + cm.off('blur', clear); + cm.off('scroll', clear); + fadeOut(tip); + } + var mouseOnTip = false, old = false; + CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; }); + CodeMirror.on(tip, "mouseout", function(e) { + if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) { + if (old) clear(); + else mouseOnTip = false; + } + }); + setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700); + cm.on("cursorActivity", clear); + cm.on('blur', clear); + cm.on('scroll', clear); + } + + function makeTooltip(x, y, content) { + var node = elt("div", cls + "tooltip", content); + node.style.left = x + "px"; + node.style.top = y + "px"; + document.body.appendChild(node); + return node; + } + + function remove(node) { + var p = node && node.parentNode; + if (p) p.removeChild(node); + } + + function fadeOut(tooltip) { + tooltip.style.opacity = "0"; + setTimeout(function() { remove(tooltip); }, 1100); + } + + function showError(ts, cm, msg) { + if (ts.options.showError) + ts.options.showError(cm, msg); + else + tempTooltip(cm, String(msg), ts); + } + + function closeArgHints(ts) { + if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; } + } + + function docValue(ts, doc) { + var val = doc.doc.getValue(); + if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc); + return val; + } + + // Worker wrapper + + function WorkerServer(ts) { + var worker = ts.worker = new Worker(ts.options.workerScript); + worker.postMessage({type: "init", + defs: ts.options.defs, + plugins: ts.options.plugins, + scripts: ts.options.workerDeps}); + var msgId = 0, pending = {}; + + function send(data, c) { + if (c) { + data.id = ++msgId; + pending[msgId] = c; + } + worker.postMessage(data); + } + worker.onmessage = function(e) { + var data = e.data; + if (data.type == "getFile") { + getFile(ts, data.name, function(err, text) { + send({type: "getFile", err: String(err), text: text, id: data.id}); + }); + } else if (data.type == "debug") { + window.console.log(data.message); + } else if (data.id && pending[data.id]) { + pending[data.id](data.err, data.body); + delete pending[data.id]; + } + }; + worker.onerror = function(e) { + for (var id in pending) pending[id](e); + pending = {}; + }; + + this.addFile = function(name, text) { send({type: "add", name: name, text: text}); }; + this.delFile = function(name) { send({type: "del", name: name}); }; + this.request = function(body, c) { send({type: "req", body: body}, c); }; + } +}); diff --git a/shared/codemirror/addon/tern/worker.js b/shared/codemirror/addon/tern/worker.js index 887f906..7e89e95 100644 --- a/shared/codemirror/addon/tern/worker.js +++ b/shared/codemirror/addon/tern/worker.js @@ -1,44 +1,44 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// declare global: tern, server - -var server; - -this.onmessage = function(e) { - var data = e.data; - switch (data.type) { - case "init": return startServer(data.defs, data.plugins, data.scripts); - case "add": return server.addFile(data.name, data.text); - case "del": return server.delFile(data.name); - case "req": return server.request(data.body, function(err, reqData) { - postMessage({id: data.id, body: reqData, err: err && String(err)}); - }); - case "getFile": - var c = pending[data.id]; - delete pending[data.id]; - return c(data.err, data.text); - default: throw new Error("Unknown message type: " + data.type); - } -}; - -var nextId = 0, pending = {}; -function getFile(file, c) { - postMessage({type: "getFile", name: file, id: ++nextId}); - pending[nextId] = c; -} - -function startServer(defs, plugins, scripts) { - if (scripts) importScripts.apply(null, scripts); - - server = new tern.Server({ - getFile: getFile, - async: true, - defs: defs, - plugins: plugins - }); -} - -this.console = { - log: function(v) { postMessage({type: "debug", message: v}); } -}; +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// declare global: tern, server + +var server; + +this.onmessage = function(e) { + var data = e.data; + switch (data.type) { + case "init": return startServer(data.defs, data.plugins, data.scripts); + case "add": return server.addFile(data.name, data.text); + case "del": return server.delFile(data.name); + case "req": return server.request(data.body, function(err, reqData) { + postMessage({id: data.id, body: reqData, err: err && String(err)}); + }); + case "getFile": + var c = pending[data.id]; + delete pending[data.id]; + return c(data.err, data.text); + default: throw new Error("Unknown message type: " + data.type); + } +}; + +var nextId = 0, pending = {}; +function getFile(file, c) { + postMessage({type: "getFile", name: file, id: ++nextId}); + pending[nextId] = c; +} + +function startServer(defs, plugins, scripts) { + if (scripts) importScripts.apply(null, scripts); + + server = new tern.Server({ + getFile: getFile, + async: true, + defs: defs, + plugins: plugins + }); +} + +this.console = { + log: function(v) { postMessage({type: "debug", message: v}); } +}; diff --git a/shared/codemirror/addon/wrap/hardwrap.js b/shared/codemirror/addon/wrap/hardwrap.js index 8806fbe..3b785d5 100644 --- a/shared/codemirror/addon/wrap/hardwrap.js +++ b/shared/codemirror/addon/wrap/hardwrap.js @@ -1,142 +1,142 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var Pos = CodeMirror.Pos; - - function findParagraph(cm, pos, options) { - var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart"); - for (var start = pos.line, first = cm.firstLine(); start > first; --start) { - var line = cm.getLine(start); - if (startRE && startRE.test(line)) break; - if (!/\S/.test(line)) { ++start; break; } - } - var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd"); - for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) { - var line = cm.getLine(end); - if (endRE && endRE.test(line)) { ++end; break; } - if (!/\S/.test(line)) break; - } - return {from: start, to: end}; - } - - function findBreakPoint(text, column, wrapOn, killTrailingSpace) { - for (var at = column; at > 0; --at) - if (wrapOn.test(text.slice(at - 1, at + 1))) break; - for (var first = true;; first = false) { - var endOfText = at; - if (killTrailingSpace) - while (text.charAt(endOfText - 1) == " ") --endOfText; - if (endOfText == 0 && first) at = column; - else return {from: endOfText, to: at}; - } - } - - function wrapRange(cm, from, to, options) { - from = cm.clipPos(from); to = cm.clipPos(to); - var column = options.column || 80; - var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/; - var killTrailing = options.killTrailingSpace !== false; - var changes = [], curLine = "", curNo = from.line; - var lines = cm.getRange(from, to, false); - if (!lines.length) return null; - var leadingSpace = lines[0].match(/^[ \t]*/)[0]; - - for (var i = 0; i < lines.length; ++i) { - var text = lines[i], oldLen = curLine.length, spaceInserted = 0; - if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) { - curLine += " "; - spaceInserted = 1; - } - var spaceTrimmed = ""; - if (i) { - spaceTrimmed = text.match(/^\s*/)[0]; - text = text.slice(spaceTrimmed.length); - } - curLine += text; - if (i) { - var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed && - findBreakPoint(curLine, column, wrapOn, killTrailing); - // If this isn't broken, or is broken at a different point, remove old break - if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) { - changes.push({text: [spaceInserted ? " " : ""], - from: Pos(curNo, oldLen), - to: Pos(curNo + 1, spaceTrimmed.length)}); - } else { - curLine = leadingSpace + text; - ++curNo; - } - } - while (curLine.length > column) { - var bp = findBreakPoint(curLine, column, wrapOn, killTrailing); - changes.push({text: ["", leadingSpace], - from: Pos(curNo, bp.from), - to: Pos(curNo, bp.to)}); - curLine = leadingSpace + curLine.slice(bp.to); - ++curNo; - } - } - if (changes.length) cm.operation(function() { - for (var i = 0; i < changes.length; ++i) { - var change = changes[i]; - if (change.text || CodeMirror.cmpPos(change.from, change.to)) - cm.replaceRange(change.text, change.from, change.to); - } - }); - return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null; - } - - CodeMirror.defineExtension("wrapParagraph", function(pos, options) { - options = options || {}; - if (!pos) pos = this.getCursor(); - var para = findParagraph(this, pos, options); - return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options); - }); - - CodeMirror.commands.wrapLines = function(cm) { - cm.operation(function() { - var ranges = cm.listSelections(), at = cm.lastLine() + 1; - for (var i = ranges.length - 1; i >= 0; i--) { - var range = ranges[i], span; - if (range.empty()) { - var para = findParagraph(cm, range.head, {}); - span = {from: Pos(para.from, 0), to: Pos(para.to - 1)}; - } else { - span = {from: range.from(), to: range.to()}; - } - if (span.to.line >= at) continue; - at = span.from.line; - wrapRange(cm, span.from, span.to, {}); - } - }); - }; - - CodeMirror.defineExtension("wrapRange", function(from, to, options) { - return wrapRange(this, from, to, options || {}); - }); - - CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) { - options = options || {}; - var cm = this, paras = []; - for (var line = from.line; line <= to.line;) { - var para = findParagraph(cm, Pos(line, 0), options); - paras.push(para); - line = para.to; - } - var madeChange = false; - if (paras.length) cm.operation(function() { - for (var i = paras.length - 1; i >= 0; --i) - madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options); - }); - return madeChange; - }); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var Pos = CodeMirror.Pos; + + function findParagraph(cm, pos, options) { + var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart"); + for (var start = pos.line, first = cm.firstLine(); start > first; --start) { + var line = cm.getLine(start); + if (startRE && startRE.test(line)) break; + if (!/\S/.test(line)) { ++start; break; } + } + var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd"); + for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) { + var line = cm.getLine(end); + if (endRE && endRE.test(line)) { ++end; break; } + if (!/\S/.test(line)) break; + } + return {from: start, to: end}; + } + + function findBreakPoint(text, column, wrapOn, killTrailingSpace) { + for (var at = column; at > 0; --at) + if (wrapOn.test(text.slice(at - 1, at + 1))) break; + for (var first = true;; first = false) { + var endOfText = at; + if (killTrailingSpace) + while (text.charAt(endOfText - 1) == " ") --endOfText; + if (endOfText == 0 && first) at = column; + else return {from: endOfText, to: at}; + } + } + + function wrapRange(cm, from, to, options) { + from = cm.clipPos(from); to = cm.clipPos(to); + var column = options.column || 80; + var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/; + var killTrailing = options.killTrailingSpace !== false; + var changes = [], curLine = "", curNo = from.line; + var lines = cm.getRange(from, to, false); + if (!lines.length) return null; + var leadingSpace = lines[0].match(/^[ \t]*/)[0]; + + for (var i = 0; i < lines.length; ++i) { + var text = lines[i], oldLen = curLine.length, spaceInserted = 0; + if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) { + curLine += " "; + spaceInserted = 1; + } + var spaceTrimmed = ""; + if (i) { + spaceTrimmed = text.match(/^\s*/)[0]; + text = text.slice(spaceTrimmed.length); + } + curLine += text; + if (i) { + var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed && + findBreakPoint(curLine, column, wrapOn, killTrailing); + // If this isn't broken, or is broken at a different point, remove old break + if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) { + changes.push({text: [spaceInserted ? " " : ""], + from: Pos(curNo, oldLen), + to: Pos(curNo + 1, spaceTrimmed.length)}); + } else { + curLine = leadingSpace + text; + ++curNo; + } + } + while (curLine.length > column) { + var bp = findBreakPoint(curLine, column, wrapOn, killTrailing); + changes.push({text: ["", leadingSpace], + from: Pos(curNo, bp.from), + to: Pos(curNo, bp.to)}); + curLine = leadingSpace + curLine.slice(bp.to); + ++curNo; + } + } + if (changes.length) cm.operation(function() { + for (var i = 0; i < changes.length; ++i) { + var change = changes[i]; + if (change.text || CodeMirror.cmpPos(change.from, change.to)) + cm.replaceRange(change.text, change.from, change.to); + } + }); + return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null; + } + + CodeMirror.defineExtension("wrapParagraph", function(pos, options) { + options = options || {}; + if (!pos) pos = this.getCursor(); + var para = findParagraph(this, pos, options); + return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options); + }); + + CodeMirror.commands.wrapLines = function(cm) { + cm.operation(function() { + var ranges = cm.listSelections(), at = cm.lastLine() + 1; + for (var i = ranges.length - 1; i >= 0; i--) { + var range = ranges[i], span; + if (range.empty()) { + var para = findParagraph(cm, range.head, {}); + span = {from: Pos(para.from, 0), to: Pos(para.to - 1)}; + } else { + span = {from: range.from(), to: range.to()}; + } + if (span.to.line >= at) continue; + at = span.from.line; + wrapRange(cm, span.from, span.to, {}); + } + }); + }; + + CodeMirror.defineExtension("wrapRange", function(from, to, options) { + return wrapRange(this, from, to, options || {}); + }); + + CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) { + options = options || {}; + var cm = this, paras = []; + for (var line = from.line; line <= to.line;) { + var para = findParagraph(cm, Pos(line, 0), options); + paras.push(para); + line = para.to; + } + var madeChange = false; + if (paras.length) cm.operation(function() { + for (var i = paras.length - 1; i >= 0; --i) + madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options); + }); + return madeChange; + }); +}); diff --git a/shared/codemirror/lib/codemirror.css b/shared/codemirror/lib/codemirror.css index 1cf66a9..6c0fb8c 100644 --- a/shared/codemirror/lib/codemirror.css +++ b/shared/codemirror/lib/codemirror.css @@ -1,338 +1,338 @@ -/* BASICS */ - -.CodeMirror { - /* Set height, width, borders, and global font properties here */ - font-family: monospace; - height: 300px; - color: black; -} - -/* PADDING */ - -.CodeMirror-lines { - padding: 4px 0; /* Vertical padding around content */ -} -.CodeMirror pre { - padding: 0 4px; /* Horizontal padding of content */ -} - -.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - background-color: white; /* The little square between H and V scrollbars */ -} - -/* GUTTER */ - -.CodeMirror-gutters { - border-right: 1px solid #ddd; - background-color: #f7f7f7; - white-space: nowrap; -} -.CodeMirror-linenumbers {} -.CodeMirror-linenumber { - padding: 0 3px 0 5px; - min-width: 20px; - text-align: right; - color: #999; - white-space: nowrap; -} - -.CodeMirror-guttermarker { color: black; } -.CodeMirror-guttermarker-subtle { color: #999; } - -/* CURSOR */ - -.CodeMirror-cursor { - border-left: 1px solid black; - border-right: none; - width: 0; -} -/* Shown when moving in bi-directional text */ -.CodeMirror div.CodeMirror-secondarycursor { - border-left: 1px solid silver; -} -.cm-fat-cursor .CodeMirror-cursor { - width: auto; - border: 0; - background: #7e7; -} -.cm-fat-cursor div.CodeMirror-cursors { - z-index: 1; -} - -.cm-animate-fat-cursor { - width: auto; - border: 0; - -webkit-animation: blink 1.06s steps(1) infinite; - -moz-animation: blink 1.06s steps(1) infinite; - animation: blink 1.06s steps(1) infinite; - background-color: #7e7; -} -@-moz-keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} -@-webkit-keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} -@keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} - -/* Can style cursor different in overwrite (non-insert) mode */ -.CodeMirror-overwrite .CodeMirror-cursor {} - -.cm-tab { display: inline-block; text-decoration: inherit; } - -.CodeMirror-ruler { - border-left: 1px solid #ccc; - position: absolute; -} - -/* DEFAULT THEME */ - -.cm-s-default .cm-header {color: blue;} -.cm-s-default .cm-quote {color: #090;} -.cm-negative {color: #d44;} -.cm-positive {color: #292;} -.cm-header, .cm-strong {font-weight: bold;} -.cm-em {font-style: italic;} -.cm-link {text-decoration: underline;} -.cm-strikethrough {text-decoration: line-through;} - -.cm-s-default .cm-keyword {color: #708;} -.cm-s-default .cm-atom {color: #219;} -.cm-s-default .cm-number {color: #164;} -.cm-s-default .cm-def {color: #00f;} -.cm-s-default .cm-variable, -.cm-s-default .cm-punctuation, -.cm-s-default .cm-property, -.cm-s-default .cm-operator {} -.cm-s-default .cm-variable-2 {color: #05a;} -.cm-s-default .cm-variable-3 {color: #085;} -.cm-s-default .cm-comment {color: #a50;} -.cm-s-default .cm-string {color: #a11;} -.cm-s-default .cm-string-2 {color: #f50;} -.cm-s-default .cm-meta {color: #555;} -.cm-s-default .cm-qualifier {color: #555;} -.cm-s-default .cm-builtin {color: #30a;} -.cm-s-default .cm-bracket {color: #997;} -.cm-s-default .cm-tag {color: #170;} -.cm-s-default .cm-attribute {color: #00c;} -.cm-s-default .cm-hr {color: #999;} -.cm-s-default .cm-link {color: #00c;} - -.cm-s-default .cm-error {color: #f00;} -.cm-invalidchar {color: #f00;} - -.CodeMirror-composing { border-bottom: 2px solid; } - -/* Default styles for common addons */ - -div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} -div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} -.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } -.CodeMirror-activeline-background {background: #e8f2ff;} - -/* STOP */ - -/* The rest of this file contains styles related to the mechanics of - the editor. You probably shouldn't touch them. */ - -.CodeMirror { - position: relative; - overflow: hidden; - background: white; -} - -.CodeMirror-scroll { - overflow: scroll !important; /* Things will break if this is overridden */ - /* 30px is the magic margin used to hide the element's real scrollbars */ - /* See overflow: hidden in .CodeMirror */ - margin-bottom: -30px; margin-right: -30px; - padding-bottom: 30px; - height: 100%; - outline: none; /* Prevent dragging from highlighting the element */ - position: relative; -} -.CodeMirror-sizer { - position: relative; - border-right: 30px solid transparent; -} - -/* The fake, visible scrollbars. Used to force redraw during scrolling - before actual scrolling happens, thus preventing shaking and - flickering artifacts. */ -.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - position: absolute; - z-index: 6; - display: none; -} -.CodeMirror-vscrollbar { - right: 0; top: 0; - overflow-x: hidden; - overflow-y: scroll; -} -.CodeMirror-hscrollbar { - bottom: 0; left: 0; - overflow-y: hidden; - overflow-x: scroll; -} -.CodeMirror-scrollbar-filler { - right: 0; bottom: 0; -} -.CodeMirror-gutter-filler { - left: 0; bottom: 0; -} - -.CodeMirror-gutters { - position: absolute; left: 0; top: 0; - min-height: 100%; - z-index: 3; -} -.CodeMirror-gutter { - white-space: normal; - height: 100%; - display: inline-block; - vertical-align: top; - margin-bottom: -30px; - /* Hack to make IE7 behave */ - *zoom:1; - *display:inline; -} -.CodeMirror-gutter-wrapper { - position: absolute; - z-index: 4; - background: none !important; - border: none !important; -} -.CodeMirror-gutter-background { - position: absolute; - top: 0; bottom: 0; - z-index: 4; -} -.CodeMirror-gutter-elt { - position: absolute; - cursor: default; - z-index: 4; -} -.CodeMirror-gutter-wrapper { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} - -.CodeMirror-lines { - cursor: text; - min-height: 1px; /* prevents collapsing before first draw */ -} -.CodeMirror pre { - /* Reset some styles that the rest of the page might have set */ - -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; - border-width: 0; - background: transparent; - font-family: inherit; - font-size: inherit; - margin: 0; - white-space: pre; - word-wrap: normal; - line-height: inherit; - color: inherit; - z-index: 2; - position: relative; - overflow: visible; - -webkit-tap-highlight-color: transparent; - -webkit-font-variant-ligatures: none; - font-variant-ligatures: none; -} -.CodeMirror-wrap pre { - word-wrap: break-word; - white-space: pre-wrap; - word-break: normal; -} - -.CodeMirror-linebackground { - position: absolute; - left: 0; right: 0; top: 0; bottom: 0; - z-index: 0; -} - -.CodeMirror-linewidget { - position: relative; - z-index: 2; - overflow: auto; -} - -.CodeMirror-widget {} - -.CodeMirror-code { - outline: none; -} - -/* Force content-box sizing for the elements where we expect it */ -.CodeMirror-scroll, -.CodeMirror-sizer, -.CodeMirror-gutter, -.CodeMirror-gutters, -.CodeMirror-linenumber { - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -.CodeMirror-measure { - position: absolute; - width: 100%; - height: 0; - overflow: hidden; - visibility: hidden; -} - -.CodeMirror-cursor { position: absolute; } -.CodeMirror-measure pre { position: static; } - -div.CodeMirror-cursors { - visibility: hidden; - position: relative; - z-index: 3; -} -div.CodeMirror-dragcursors { - visibility: visible; -} - -.CodeMirror-focused div.CodeMirror-cursors { - visibility: visible; -} - -.CodeMirror-selected { background: #d9d9d9; } -.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } -.CodeMirror-crosshair { cursor: crosshair; } -.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } -.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } - -.cm-searching { - background: #ffa; - background: rgba(255, 255, 0, .4); -} - -/* IE7 hack to prevent it from returning funny offsetTops on the spans */ -.CodeMirror span { *vertical-align: text-bottom; } - -/* Used to force a border model for a node */ -.cm-force-border { padding-right: .1px; } - -@media print { - /* Hide the cursor when printing */ - .CodeMirror div.CodeMirror-cursors { - visibility: hidden; - } -} - -/* See issue #2901 */ -.cm-tab-wrap-hack:after { content: ''; } - -/* Help users use markselection to safely style text background */ -span.CodeMirror-selectedtext { background: none; } +/* BASICS */ + +.CodeMirror { + /* Set height, width, borders, and global font properties here */ + font-family: monospace; + height: 300px; + color: black; +} + +/* PADDING */ + +.CodeMirror-lines { + padding: 4px 0; /* Vertical padding around content */ +} +.CodeMirror pre { + padding: 0 4px; /* Horizontal padding of content */ +} + +.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + background-color: white; /* The little square between H and V scrollbars */ +} + +/* GUTTER */ + +.CodeMirror-gutters { + border-right: 1px solid #ddd; + background-color: #f7f7f7; + white-space: nowrap; +} +.CodeMirror-linenumbers {} +.CodeMirror-linenumber { + padding: 0 3px 0 5px; + min-width: 20px; + text-align: right; + color: #999; + white-space: nowrap; +} + +.CodeMirror-guttermarker { color: black; } +.CodeMirror-guttermarker-subtle { color: #999; } + +/* CURSOR */ + +.CodeMirror-cursor { + border-left: 1px solid black; + border-right: none; + width: 0; +} +/* Shown when moving in bi-directional text */ +.CodeMirror div.CodeMirror-secondarycursor { + border-left: 1px solid silver; +} +.cm-fat-cursor .CodeMirror-cursor { + width: auto; + border: 0; + background: #7e7; +} +.cm-fat-cursor div.CodeMirror-cursors { + z-index: 1; +} + +.cm-animate-fat-cursor { + width: auto; + border: 0; + -webkit-animation: blink 1.06s steps(1) infinite; + -moz-animation: blink 1.06s steps(1) infinite; + animation: blink 1.06s steps(1) infinite; + background-color: #7e7; +} +@-moz-keyframes blink { + 0% {} + 50% { background-color: transparent; } + 100% {} +} +@-webkit-keyframes blink { + 0% {} + 50% { background-color: transparent; } + 100% {} +} +@keyframes blink { + 0% {} + 50% { background-color: transparent; } + 100% {} +} + +/* Can style cursor different in overwrite (non-insert) mode */ +.CodeMirror-overwrite .CodeMirror-cursor {} + +.cm-tab { display: inline-block; text-decoration: inherit; } + +.CodeMirror-ruler { + border-left: 1px solid #ccc; + position: absolute; +} + +/* DEFAULT THEME */ + +.cm-s-default .cm-header {color: blue;} +.cm-s-default .cm-quote {color: #090;} +.cm-negative {color: #d44;} +.cm-positive {color: #292;} +.cm-header, .cm-strong {font-weight: bold;} +.cm-em {font-style: italic;} +.cm-link {text-decoration: underline;} +.cm-strikethrough {text-decoration: line-through;} + +.cm-s-default .cm-keyword {color: #708;} +.cm-s-default .cm-atom {color: #219;} +.cm-s-default .cm-number {color: #164;} +.cm-s-default .cm-def {color: #00f;} +.cm-s-default .cm-variable, +.cm-s-default .cm-punctuation, +.cm-s-default .cm-property, +.cm-s-default .cm-operator {} +.cm-s-default .cm-variable-2 {color: #05a;} +.cm-s-default .cm-variable-3 {color: #085;} +.cm-s-default .cm-comment {color: #a50;} +.cm-s-default .cm-string {color: #a11;} +.cm-s-default .cm-string-2 {color: #f50;} +.cm-s-default .cm-meta {color: #555;} +.cm-s-default .cm-qualifier {color: #555;} +.cm-s-default .cm-builtin {color: #30a;} +.cm-s-default .cm-bracket {color: #997;} +.cm-s-default .cm-tag {color: #170;} +.cm-s-default .cm-attribute {color: #00c;} +.cm-s-default .cm-hr {color: #999;} +.cm-s-default .cm-link {color: #00c;} + +.cm-s-default .cm-error {color: #f00;} +.cm-invalidchar {color: #f00;} + +.CodeMirror-composing { border-bottom: 2px solid; } + +/* Default styles for common addons */ + +div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} +.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } +.CodeMirror-activeline-background {background: #e8f2ff;} + +/* STOP */ + +/* The rest of this file contains styles related to the mechanics of + the editor. You probably shouldn't touch them. */ + +.CodeMirror { + position: relative; + overflow: hidden; + background: white; +} + +.CodeMirror-scroll { + overflow: scroll !important; /* Things will break if this is overridden */ + /* 30px is the magic margin used to hide the element's real scrollbars */ + /* See overflow: hidden in .CodeMirror */ + margin-bottom: -30px; margin-right: -30px; + padding-bottom: 30px; + height: 100%; + outline: none; /* Prevent dragging from highlighting the element */ + position: relative; +} +.CodeMirror-sizer { + position: relative; + border-right: 30px solid transparent; +} + +/* The fake, visible scrollbars. Used to force redraw during scrolling + before actual scrolling happens, thus preventing shaking and + flickering artifacts. */ +.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + position: absolute; + z-index: 6; + display: none; +} +.CodeMirror-vscrollbar { + right: 0; top: 0; + overflow-x: hidden; + overflow-y: scroll; +} +.CodeMirror-hscrollbar { + bottom: 0; left: 0; + overflow-y: hidden; + overflow-x: scroll; +} +.CodeMirror-scrollbar-filler { + right: 0; bottom: 0; +} +.CodeMirror-gutter-filler { + left: 0; bottom: 0; +} + +.CodeMirror-gutters { + position: absolute; left: 0; top: 0; + min-height: 100%; + z-index: 3; +} +.CodeMirror-gutter { + white-space: normal; + height: 100%; + display: inline-block; + vertical-align: top; + margin-bottom: -30px; + /* Hack to make IE7 behave */ + *zoom:1; + *display:inline; +} +.CodeMirror-gutter-wrapper { + position: absolute; + z-index: 4; + background: none !important; + border: none !important; +} +.CodeMirror-gutter-background { + position: absolute; + top: 0; bottom: 0; + z-index: 4; +} +.CodeMirror-gutter-elt { + position: absolute; + cursor: default; + z-index: 4; +} +.CodeMirror-gutter-wrapper { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.CodeMirror-lines { + cursor: text; + min-height: 1px; /* prevents collapsing before first draw */ +} +.CodeMirror pre { + /* Reset some styles that the rest of the page might have set */ + -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; + border-width: 0; + background: transparent; + font-family: inherit; + font-size: inherit; + margin: 0; + white-space: pre; + word-wrap: normal; + line-height: inherit; + color: inherit; + z-index: 2; + position: relative; + overflow: visible; + -webkit-tap-highlight-color: transparent; + -webkit-font-variant-ligatures: none; + font-variant-ligatures: none; +} +.CodeMirror-wrap pre { + word-wrap: break-word; + white-space: pre-wrap; + word-break: normal; +} + +.CodeMirror-linebackground { + position: absolute; + left: 0; right: 0; top: 0; bottom: 0; + z-index: 0; +} + +.CodeMirror-linewidget { + position: relative; + z-index: 2; + overflow: auto; +} + +.CodeMirror-widget {} + +.CodeMirror-code { + outline: none; +} + +/* Force content-box sizing for the elements where we expect it */ +.CodeMirror-scroll, +.CodeMirror-sizer, +.CodeMirror-gutter, +.CodeMirror-gutters, +.CodeMirror-linenumber { + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +.CodeMirror-measure { + position: absolute; + width: 100%; + height: 0; + overflow: hidden; + visibility: hidden; +} + +.CodeMirror-cursor { position: absolute; } +.CodeMirror-measure pre { position: static; } + +div.CodeMirror-cursors { + visibility: hidden; + position: relative; + z-index: 3; +} +div.CodeMirror-dragcursors { + visibility: visible; +} + +.CodeMirror-focused div.CodeMirror-cursors { + visibility: visible; +} + +.CodeMirror-selected { background: #d9d9d9; } +.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } +.CodeMirror-crosshair { cursor: crosshair; } +.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } +.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } + +.cm-searching { + background: #ffa; + background: rgba(255, 255, 0, .4); +} + +/* IE7 hack to prevent it from returning funny offsetTops on the spans */ +.CodeMirror span { *vertical-align: text-bottom; } + +/* Used to force a border model for a node */ +.cm-force-border { padding-right: .1px; } + +@media print { + /* Hide the cursor when printing */ + .CodeMirror div.CodeMirror-cursors { + visibility: hidden; + } +} + +/* See issue #2901 */ +.cm-tab-wrap-hack:after { content: ''; } + +/* Help users use markselection to safely style text background */ +span.CodeMirror-selectedtext { background: none; } diff --git a/shared/codemirror/lib/codemirror.js b/shared/codemirror/lib/codemirror.js index aa0d3b4..d960098 100644 --- a/shared/codemirror/lib/codemirror.js +++ b/shared/codemirror/lib/codemirror.js @@ -1,8898 +1,8898 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// This is CodeMirror (http://codemirror.net), a code editor -// implemented in JavaScript on top of the browser's DOM. -// -// You can find some technical background for some of the code below -// at http://marijnhaverbeke.nl/blog/#cm-internals . - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - module.exports = mod(); - else if (typeof define == "function" && define.amd) // AMD - return define([], mod); - else // Plain browser env - (this || window).CodeMirror = mod(); -})(function() { - "use strict"; - - // BROWSER SNIFFING - - // Kludges for bugs and behavior differences that can't be feature - // detected are enabled based on userAgent etc sniffing. - var userAgent = navigator.userAgent; - var platform = navigator.platform; - - var gecko = /gecko\/\d/i.test(userAgent); - var ie_upto10 = /MSIE \d/.test(userAgent); - var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); - var ie = ie_upto10 || ie_11up; - var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); - var webkit = /WebKit\//.test(userAgent); - var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); - var chrome = /Chrome\//.test(userAgent); - var presto = /Opera\//.test(userAgent); - var safari = /Apple Computer/.test(navigator.vendor); - var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); - var phantom = /PhantomJS/.test(userAgent); - - var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); - // This is woefully incomplete. Suggestions for alternative methods welcome. - var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); - var mac = ios || /Mac/.test(platform); - var chromeOS = /\bCrOS\b/.test(userAgent); - var windows = /win/i.test(platform); - - var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); - if (presto_version) presto_version = Number(presto_version[1]); - if (presto_version && presto_version >= 15) { presto = false; webkit = true; } - // Some browsers use the wrong event properties to signal cmd/ctrl on OS X - var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); - var captureRightClick = gecko || (ie && ie_version >= 9); - - // Optimize some code when these features are not used. - var sawReadOnlySpans = false, sawCollapsedSpans = false; - - // EDITOR CONSTRUCTOR - - // A CodeMirror instance represents an editor. This is the object - // that user code is usually dealing with. - - function CodeMirror(place, options) { - if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); - - this.options = options = options ? copyObj(options) : {}; - // Determine effective options based on given values and defaults. - copyObj(defaults, options, false); - setGuttersForLineNumbers(options); - - var doc = options.value; - if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator); - this.doc = doc; - - var input = new CodeMirror.inputStyles[options.inputStyle](this); - var display = this.display = new Display(place, doc, input); - display.wrapper.CodeMirror = this; - updateGutters(this); - themeChanged(this); - if (options.lineWrapping) - this.display.wrapper.className += " CodeMirror-wrap"; - if (options.autofocus && !mobile) display.input.focus(); - initScrollbars(this); - - this.state = { - keyMaps: [], // stores maps added by addKeyMap - overlays: [], // highlighting overlays, as added by addOverlay - modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info - overwrite: false, - delayingBlurEvent: false, - focused: false, - suppressEdits: false, // used to disable editing during key handlers when in readOnly mode - pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll - selectingText: false, - draggingText: false, - highlight: new Delayed(), // stores highlight worker timeout - keySeq: null, // Unfinished key sequence - specialChars: null - }; - - var cm = this; - - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20); - - registerEventHandlers(this); - ensureGlobalHandlers(); - - startOperation(this); - this.curOp.forceUpdate = true; - attachDoc(this, doc); - - if ((options.autofocus && !mobile) || cm.hasFocus()) - setTimeout(bind(onFocus, this), 20); - else - onBlur(this); - - for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) - optionHandlers[opt](this, options[opt], Init); - maybeUpdateLineNumberWidth(this); - if (options.finishInit) options.finishInit(this); - for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); - endOperation(this); - // Suppress optimizelegibility in Webkit, since it breaks text - // measuring on line wrapping boundaries. - if (webkit && options.lineWrapping && - getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") - display.lineDiv.style.textRendering = "auto"; - } - - // DISPLAY CONSTRUCTOR - - // The display handles the DOM integration, both for input reading - // and content drawing. It holds references to DOM nodes and - // display-related state. - - function Display(place, doc, input) { - var d = this; - this.input = input; - - // Covers bottom-right square when both scrollbars are present. - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); - d.scrollbarFiller.setAttribute("cm-not-content", "true"); - // Covers bottom of gutter when coverGutterNextToScrollbar is on - // and h scrollbar is present. - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); - d.gutterFiller.setAttribute("cm-not-content", "true"); - // Will contain the actual code, positioned to cover the viewport. - d.lineDiv = elt("div", null, "CodeMirror-code"); - // Elements are added to these to represent selection and cursors. - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); - d.cursorDiv = elt("div", null, "CodeMirror-cursors"); - // A visibility: hidden element used to find the size of things. - d.measure = elt("div", null, "CodeMirror-measure"); - // When lines outside of the viewport are measured, they are drawn in this. - d.lineMeasure = elt("div", null, "CodeMirror-measure"); - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], - null, "position: relative; outline: none"); - // Moved around its parent to cover visible view. - d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); - // Set to the height of the document, allowing scrolling. - d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); - d.sizerWidth = null; - // Behavior of elts with overflow: auto and padding is - // inconsistent across browsers. This is used to ensure the - // scrollable area is big enough. - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); - // Will contain the gutters, if any. - d.gutters = elt("div", null, "CodeMirror-gutters"); - d.lineGutter = null; - // Actual scrollable element. - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); - d.scroller.setAttribute("tabIndex", "-1"); - // The element in which the editor lives. - d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); - - // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) - if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } - if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; - - if (place) { - if (place.appendChild) place.appendChild(d.wrapper); - else place(d.wrapper); - } - - // Current rendered range (may be bigger than the view window). - d.viewFrom = d.viewTo = doc.first; - d.reportedViewFrom = d.reportedViewTo = doc.first; - // Information about the rendered lines. - d.view = []; - d.renderedView = null; - // Holds info about a single rendered line when it was rendered - // for measurement, while not in view. - d.externalMeasured = null; - // Empty space (in pixels) above the view - d.viewOffset = 0; - d.lastWrapHeight = d.lastWrapWidth = 0; - d.updateLineNumbers = null; - - d.nativeBarWidth = d.barHeight = d.barWidth = 0; - d.scrollbarsClipped = false; - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; - // Set to true when a non-horizontal-scrolling line widget is - // added. As an optimization, line widget aligning is skipped when - // this is false. - d.alignWidgets = false; - - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null; - d.maxLineLength = 0; - d.maxLineChanged = false; - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - - // True when shift is held down. - d.shift = false; - - // Used to track whether anything happened since the context menu - // was opened. - d.selForContextMenu = null; - - d.activeTouch = null; - - input.init(d); - } - - // STATE UPDATES - - // Used to get the editor into a consistent state again when options change. - - function loadMode(cm) { - cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); - resetModeState(cm); - } - - function resetModeState(cm) { - cm.doc.iter(function(line) { - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - }); - cm.doc.frontier = cm.doc.first; - startWorker(cm, 100); - cm.state.modeGen++; - if (cm.curOp) regChange(cm); - } - - function wrappingChanged(cm) { - if (cm.options.lineWrapping) { - addClass(cm.display.wrapper, "CodeMirror-wrap"); - cm.display.sizer.style.minWidth = ""; - cm.display.sizerWidth = null; - } else { - rmClass(cm.display.wrapper, "CodeMirror-wrap"); - findMaxLine(cm); - } - estimateLineHeights(cm); - regChange(cm); - clearCaches(cm); - setTimeout(function(){updateScrollbars(cm);}, 100); - } - - // Returns a function that estimates the height of a line, to use as - // first approximation until the line becomes visible (and is thus - // properly measurable). - function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); - return function(line) { - if (lineIsHidden(cm.doc, line)) return 0; - - var widgetsHeight = 0; - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { - if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; - } - - if (wrapping) - return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; - else - return widgetsHeight + th; - }; - } - - function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm); - doc.iter(function(line) { - var estHeight = est(line); - if (estHeight != line.height) updateLineHeight(line, estHeight); - }); - } - - function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); - clearCaches(cm); - } - - function guttersChanged(cm) { - updateGutters(cm); - regChange(cm); - setTimeout(function(){alignHorizontally(cm);}, 20); - } - - // Rebuild the gutter elements, ensure the margin to the left of the - // code matches their width. - function updateGutters(cm) { - var gutters = cm.display.gutters, specs = cm.options.gutters; - removeChildren(gutters); - for (var i = 0; i < specs.length; ++i) { - var gutterClass = specs[i]; - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); - if (gutterClass == "CodeMirror-linenumbers") { - cm.display.lineGutter = gElt; - gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; - } - } - gutters.style.display = i ? "" : "none"; - updateGutterSpace(cm); - } - - function updateGutterSpace(cm) { - var width = cm.display.gutters.offsetWidth; - cm.display.sizer.style.marginLeft = width + "px"; - } - - // Compute the character length of a line, taking into account - // collapsed ranges (see markText) that might hide parts, and join - // other lines onto it. - function lineLength(line) { - if (line.height == 0) return 0; - var len = line.text.length, merged, cur = line; - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(0, true); - cur = found.from.line; - len += found.from.ch - found.to.ch; - } - cur = line; - while (merged = collapsedSpanAtEnd(cur)) { - var found = merged.find(0, true); - len -= cur.text.length - found.from.ch; - cur = found.to.line; - len += cur.text.length - found.to.ch; - } - return len; - } - - // Find the longest line in the document. - function findMaxLine(cm) { - var d = cm.display, doc = cm.doc; - d.maxLine = getLine(doc, doc.first); - d.maxLineLength = lineLength(d.maxLine); - d.maxLineChanged = true; - doc.iter(function(line) { - var len = lineLength(line); - if (len > d.maxLineLength) { - d.maxLineLength = len; - d.maxLine = line; - } - }); - } - - // Make sure the gutters options contains the element - // "CodeMirror-linenumbers" when the lineNumbers option is true. - function setGuttersForLineNumbers(options) { - var found = indexOf(options.gutters, "CodeMirror-linenumbers"); - if (found == -1 && options.lineNumbers) { - options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); - } else if (found > -1 && !options.lineNumbers) { - options.gutters = options.gutters.slice(0); - options.gutters.splice(found, 1); - } - } - - // SCROLLBARS - - // Prepare DOM reads needed to update the scrollbars. Done in one - // shot to minimize update/measure roundtrips. - function measureForScrollbars(cm) { - var d = cm.display, gutterW = d.gutters.offsetWidth; - var docH = Math.round(cm.doc.height + paddingVert(cm.display)); - return { - clientHeight: d.scroller.clientHeight, - viewHeight: d.wrapper.clientHeight, - scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, - viewWidth: d.wrapper.clientWidth, - barLeft: cm.options.fixedGutter ? gutterW : 0, - docHeight: docH, - scrollHeight: docH + scrollGap(cm) + d.barHeight, - nativeBarWidth: d.nativeBarWidth, - gutterWidth: gutterW - }; - } - - function NativeScrollbars(place, scroll, cm) { - this.cm = cm; - var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); - var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); - place(vert); place(horiz); - - on(vert, "scroll", function() { - if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); - }); - on(horiz, "scroll", function() { - if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); - }); - - this.checkedZeroWidth = false; - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; - } - - NativeScrollbars.prototype = copyObj({ - update: function(measure) { - var needsH = measure.scrollWidth > measure.clientWidth + 1; - var needsV = measure.scrollHeight > measure.clientHeight + 1; - var sWidth = measure.nativeBarWidth; - - if (needsV) { - this.vert.style.display = "block"; - this.vert.style.bottom = needsH ? sWidth + "px" : "0"; - var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); - // A bug in IE8 can cause this value to be negative, so guard it. - this.vert.firstChild.style.height = - Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; - } else { - this.vert.style.display = ""; - this.vert.firstChild.style.height = "0"; - } - - if (needsH) { - this.horiz.style.display = "block"; - this.horiz.style.right = needsV ? sWidth + "px" : "0"; - this.horiz.style.left = measure.barLeft + "px"; - var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); - this.horiz.firstChild.style.width = - (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; - } else { - this.horiz.style.display = ""; - this.horiz.firstChild.style.width = "0"; - } - - if (!this.checkedZeroWidth && measure.clientHeight > 0) { - if (sWidth == 0) this.zeroWidthHack(); - this.checkedZeroWidth = true; - } - - return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}; - }, - setScrollLeft: function(pos) { - if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; - if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz); - }, - setScrollTop: function(pos) { - if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; - if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert); - }, - zeroWidthHack: function() { - var w = mac && !mac_geMountainLion ? "12px" : "18px"; - this.horiz.style.height = this.vert.style.width = w; - this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; - this.disableHoriz = new Delayed; - this.disableVert = new Delayed; - }, - enableZeroWidthBar: function(bar, delay) { - bar.style.pointerEvents = "auto"; - function maybeDisable() { - // To find out whether the scrollbar is still visible, we - // check whether the element under the pixel in the bottom - // left corner of the scrollbar box is the scrollbar box - // itself (when the bar is still visible) or its filler child - // (when the bar is hidden). If it is still visible, we keep - // it enabled, if it's hidden, we disable pointer events. - var box = bar.getBoundingClientRect(); - var elt = document.elementFromPoint(box.left + 1, box.bottom - 1); - if (elt != bar) bar.style.pointerEvents = "none"; - else delay.set(1000, maybeDisable); - } - delay.set(1000, maybeDisable); - }, - clear: function() { - var parent = this.horiz.parentNode; - parent.removeChild(this.horiz); - parent.removeChild(this.vert); - } - }, NativeScrollbars.prototype); - - function NullScrollbars() {} - - NullScrollbars.prototype = copyObj({ - update: function() { return {bottom: 0, right: 0}; }, - setScrollLeft: function() {}, - setScrollTop: function() {}, - clear: function() {} - }, NullScrollbars.prototype); - - CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; - - function initScrollbars(cm) { - if (cm.display.scrollbars) { - cm.display.scrollbars.clear(); - if (cm.display.scrollbars.addClass) - rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); - } - - cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) { - cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); - // Prevent clicks in the scrollbars from killing focus - on(node, "mousedown", function() { - if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0); - }); - node.setAttribute("cm-not-content", "true"); - }, function(pos, axis) { - if (axis == "horizontal") setScrollLeft(cm, pos); - else setScrollTop(cm, pos); - }, cm); - if (cm.display.scrollbars.addClass) - addClass(cm.display.wrapper, cm.display.scrollbars.addClass); - } - - function updateScrollbars(cm, measure) { - if (!measure) measure = measureForScrollbars(cm); - var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; - updateScrollbarsInner(cm, measure); - for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { - if (startWidth != cm.display.barWidth && cm.options.lineWrapping) - updateHeightsInViewport(cm); - updateScrollbarsInner(cm, measureForScrollbars(cm)); - startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; - } - } - - // Re-synchronize the fake scrollbars with the actual size of the - // content. - function updateScrollbarsInner(cm, measure) { - var d = cm.display; - var sizes = d.scrollbars.update(measure); - - d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; - d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; - d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" - - if (sizes.right && sizes.bottom) { - d.scrollbarFiller.style.display = "block"; - d.scrollbarFiller.style.height = sizes.bottom + "px"; - d.scrollbarFiller.style.width = sizes.right + "px"; - } else d.scrollbarFiller.style.display = ""; - if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block"; - d.gutterFiller.style.height = sizes.bottom + "px"; - d.gutterFiller.style.width = measure.gutterWidth + "px"; - } else d.gutterFiller.style.display = ""; - } - - // Compute the lines that are visible in a given viewport (defaults - // the the current scroll position). viewport may contain top, - // height, and ensure (see op.scrollToPos) properties. - function visibleLines(display, doc, viewport) { - var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; - top = Math.floor(top - paddingTop(display)); - var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; - - var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); - // Ensure is a {from: {line, ch}, to: {line, ch}} object, and - // forces those lines into the viewport (if possible). - if (viewport && viewport.ensure) { - var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; - if (ensureFrom < from) { - from = ensureFrom; - to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); - } else if (Math.min(ensureTo, doc.lastLine()) >= to) { - from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); - to = ensureTo; - } - } - return {from: from, to: Math.max(to, from + 1)}; - } - - // LINE NUMBERS - - // Re-align line numbers and gutter marks to compensate for - // horizontal scrolling. - function alignHorizontally(cm) { - var display = cm.display, view = display.view; - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; - var gutterW = display.gutters.offsetWidth, left = comp + "px"; - for (var i = 0; i < view.length; i++) if (!view[i].hidden) { - if (cm.options.fixedGutter && view[i].gutter) - view[i].gutter.style.left = left; - var align = view[i].alignable; - if (align) for (var j = 0; j < align.length; j++) - align[j].style.left = left; - } - if (cm.options.fixedGutter) - display.gutters.style.left = (comp + gutterW) + "px"; - } - - // Used to ensure that the line number gutter is still the right - // size for the current document size. Returns true when an update - // is needed. - function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) return false; - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")); - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; - display.lineGutter.style.width = ""; - display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; - display.lineNumWidth = display.lineNumInnerWidth + padding; - display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; - display.lineGutter.style.width = display.lineNumWidth + "px"; - updateGutterSpace(cm); - return true; - } - return false; - } - - function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)); - } - - // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, - // but using getBoundingClientRect to get a sub-pixel-accurate - // result. - function compensateForHScroll(display) { - return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; - } - - // DISPLAY DRAWING - - function DisplayUpdate(cm, viewport, force) { - var display = cm.display; - - this.viewport = viewport; - // Store some values that we'll need later (but don't want to force a relayout for) - this.visible = visibleLines(display, cm.doc, viewport); - this.editorIsHidden = !display.wrapper.offsetWidth; - this.wrapperHeight = display.wrapper.clientHeight; - this.wrapperWidth = display.wrapper.clientWidth; - this.oldDisplayWidth = displayWidth(cm); - this.force = force; - this.dims = getDimensions(cm); - this.events = []; - } - - DisplayUpdate.prototype.signal = function(emitter, type) { - if (hasHandler(emitter, type)) - this.events.push(arguments); - }; - DisplayUpdate.prototype.finish = function() { - for (var i = 0; i < this.events.length; i++) - signal.apply(null, this.events[i]); - }; - - function maybeClipScrollbars(cm) { - var display = cm.display; - if (!display.scrollbarsClipped && display.scroller.offsetWidth) { - display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; - display.heightForcer.style.height = scrollGap(cm) + "px"; - display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; - display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; - display.scrollbarsClipped = true; - } - } - - // Does the actual updating of the line display. Bails out - // (returning false) when there is nothing to be done and forced is - // false. - function updateDisplayIfNeeded(cm, update) { - var display = cm.display, doc = cm.doc; - - if (update.editorIsHidden) { - resetView(cm); - return false; - } - - // Bail out if the visible area is already rendered and nothing changed. - if (!update.force && - update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && - display.renderedView == display.view && countDirtyView(cm) == 0) - return false; - - if (maybeUpdateLineNumberWidth(cm)) { - resetView(cm); - update.dims = getDimensions(cm); - } - - // Compute a suitable new viewport (from & to) - var end = doc.first + doc.size; - var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); - var to = Math.min(end, update.visible.to + cm.options.viewportMargin); - if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); - if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); - if (sawCollapsedSpans) { - from = visualLineNo(cm.doc, from); - to = visualLineEndNo(cm.doc, to); - } - - var different = from != display.viewFrom || to != display.viewTo || - display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; - adjustView(cm, from, to); - - display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); - // Position the mover div to align with the current scroll position - cm.display.mover.style.top = display.viewOffset + "px"; - - var toUpdate = countDirtyView(cm); - if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) - return false; - - // For big changes, we hide the enclosing element during the - // update, since that speeds up the operations on most browsers. - var focused = activeElt(); - if (toUpdate > 4) display.lineDiv.style.display = "none"; - patchDisplay(cm, display.updateLineNumbers, update.dims); - if (toUpdate > 4) display.lineDiv.style.display = ""; - display.renderedView = display.view; - // There might have been a widget with a focused element that got - // hidden or updated, if so re-focus it. - if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); - - // Prevent selection and cursors from interfering with the scroll - // width and height. - removeChildren(display.cursorDiv); - removeChildren(display.selectionDiv); - display.gutters.style.height = display.sizer.style.minHeight = 0; - - if (different) { - display.lastWrapHeight = update.wrapperHeight; - display.lastWrapWidth = update.wrapperWidth; - startWorker(cm, 400); - } - - display.updateLineNumbers = null; - - return true; - } - - function postUpdateDisplay(cm, update) { - var viewport = update.viewport; - - for (var first = true;; first = false) { - if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { - // Clip forced viewport to actual scrollable area. - if (viewport && viewport.top != null) - viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; - // Updated line heights might result in the drawn area not - // actually covering the viewport. Keep looping until it does. - update.visible = visibleLines(cm.display, cm.doc, viewport); - if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) - break; - } - if (!updateDisplayIfNeeded(cm, update)) break; - updateHeightsInViewport(cm); - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - updateScrollbars(cm, barMeasure); - setDocumentHeight(cm, barMeasure); - } - - update.signal(cm, "update", cm); - if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { - update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); - cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; - } - } - - function updateDisplaySimple(cm, viewport) { - var update = new DisplayUpdate(cm, viewport); - if (updateDisplayIfNeeded(cm, update)) { - updateHeightsInViewport(cm); - postUpdateDisplay(cm, update); - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - updateScrollbars(cm, barMeasure); - setDocumentHeight(cm, barMeasure); - update.finish(); - } - } - - function setDocumentHeight(cm, measure) { - cm.display.sizer.style.minHeight = measure.docHeight + "px"; - cm.display.heightForcer.style.top = measure.docHeight + "px"; - cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px"; - } - - // Read the actual heights of the rendered lines, and update their - // stored heights to match. - function updateHeightsInViewport(cm) { - var display = cm.display; - var prevBottom = display.lineDiv.offsetTop; - for (var i = 0; i < display.view.length; i++) { - var cur = display.view[i], height; - if (cur.hidden) continue; - if (ie && ie_version < 8) { - var bot = cur.node.offsetTop + cur.node.offsetHeight; - height = bot - prevBottom; - prevBottom = bot; - } else { - var box = cur.node.getBoundingClientRect(); - height = box.bottom - box.top; - } - var diff = cur.line.height - height; - if (height < 2) height = textHeight(display); - if (diff > .001 || diff < -.001) { - updateLineHeight(cur.line, height); - updateWidgetHeight(cur.line); - if (cur.rest) for (var j = 0; j < cur.rest.length; j++) - updateWidgetHeight(cur.rest[j]); - } - } - } - - // Read and store the height of line widgets associated with the - // given line. - function updateWidgetHeight(line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) - line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight; - } - - // Do a bulk-read of the DOM positions and sizes needed to draw the - // view, so that we don't interleave reading and writing to the DOM. - function getDimensions(cm) { - var d = cm.display, left = {}, width = {}; - var gutterLeft = d.gutters.clientLeft; - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; - width[cm.options.gutters[i]] = n.clientWidth; - } - return {fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth}; - } - - // Sync the actual display DOM structure with display.view, removing - // nodes for lines that are no longer in view, and creating the ones - // that are not there yet, and updating the ones that are out of - // date. - function patchDisplay(cm, updateNumbersFrom, dims) { - var display = cm.display, lineNumbers = cm.options.lineNumbers; - var container = display.lineDiv, cur = container.firstChild; - - function rm(node) { - var next = node.nextSibling; - // Works around a throw-scroll bug in OS X Webkit - if (webkit && mac && cm.display.currentWheelTarget == node) - node.style.display = "none"; - else - node.parentNode.removeChild(node); - return next; - } - - var view = display.view, lineN = display.viewFrom; - // Loop over the elements in the view, syncing cur (the DOM nodes - // in display.lineDiv) with the view as we go. - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (lineView.hidden) { - } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet - var node = buildLineElement(cm, lineView, lineN, dims); - container.insertBefore(node, cur); - } else { // Already drawn - while (cur != lineView.node) cur = rm(cur); - var updateNumber = lineNumbers && updateNumbersFrom != null && - updateNumbersFrom <= lineN && lineView.lineNumber; - if (lineView.changes) { - if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; - updateLineForChanges(cm, lineView, lineN, dims); - } - if (updateNumber) { - removeChildren(lineView.lineNumber); - lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); - } - cur = lineView.node.nextSibling; - } - lineN += lineView.size; - } - while (cur) cur = rm(cur); - } - - // When an aspect of a line changes, a string is added to - // lineView.changes. This updates the relevant part of the line's - // DOM structure. - function updateLineForChanges(cm, lineView, lineN, dims) { - for (var j = 0; j < lineView.changes.length; j++) { - var type = lineView.changes[j]; - if (type == "text") updateLineText(cm, lineView); - else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); - else if (type == "class") updateLineClasses(lineView); - else if (type == "widget") updateLineWidgets(cm, lineView, dims); - } - lineView.changes = null; - } - - // Lines with gutter elements, widgets or a background class need to - // be wrapped, and have the extra elements added to the wrapper div - function ensureLineWrapped(lineView) { - if (lineView.node == lineView.text) { - lineView.node = elt("div", null, null, "position: relative"); - if (lineView.text.parentNode) - lineView.text.parentNode.replaceChild(lineView.node, lineView.text); - lineView.node.appendChild(lineView.text); - if (ie && ie_version < 8) lineView.node.style.zIndex = 2; - } - return lineView.node; - } - - function updateLineBackground(lineView) { - var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; - if (cls) cls += " CodeMirror-linebackground"; - if (lineView.background) { - if (cls) lineView.background.className = cls; - else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } - } else if (cls) { - var wrap = ensureLineWrapped(lineView); - lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); - } - } - - // Wrapper around buildLineContent which will reuse the structure - // in display.externalMeasured when possible. - function getLineContent(cm, lineView) { - var ext = cm.display.externalMeasured; - if (ext && ext.line == lineView.line) { - cm.display.externalMeasured = null; - lineView.measure = ext.measure; - return ext.built; - } - return buildLineContent(cm, lineView); - } - - // Redraw the line's text. Interacts with the background and text - // classes because the mode may output tokens that influence these - // classes. - function updateLineText(cm, lineView) { - var cls = lineView.text.className; - var built = getLineContent(cm, lineView); - if (lineView.text == lineView.node) lineView.node = built.pre; - lineView.text.parentNode.replaceChild(built.pre, lineView.text); - lineView.text = built.pre; - if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { - lineView.bgClass = built.bgClass; - lineView.textClass = built.textClass; - updateLineClasses(lineView); - } else if (cls) { - lineView.text.className = cls; - } - } - - function updateLineClasses(lineView) { - updateLineBackground(lineView); - if (lineView.line.wrapClass) - ensureLineWrapped(lineView).className = lineView.line.wrapClass; - else if (lineView.node != lineView.text) - lineView.node.className = ""; - var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; - lineView.text.className = textClass || ""; - } - - function updateLineGutter(cm, lineView, lineN, dims) { - if (lineView.gutter) { - lineView.node.removeChild(lineView.gutter); - lineView.gutter = null; - } - if (lineView.gutterBackground) { - lineView.node.removeChild(lineView.gutterBackground); - lineView.gutterBackground = null; - } - if (lineView.line.gutterClass) { - var wrap = ensureLineWrapped(lineView); - lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, - "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + - "px; width: " + dims.gutterTotalWidth + "px"); - wrap.insertBefore(lineView.gutterBackground, lineView.text); - } - var markers = lineView.line.gutterMarkers; - if (cm.options.lineNumbers || markers) { - var wrap = ensureLineWrapped(lineView); - var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + - (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"); - cm.display.input.setUneditable(gutterWrap); - wrap.insertBefore(gutterWrap, lineView.text); - if (lineView.line.gutterClass) - gutterWrap.className += " " + lineView.line.gutterClass; - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) - lineView.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineN), - "CodeMirror-linenumber CodeMirror-gutter-elt", - "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " - + cm.display.lineNumInnerWidth + "px")); - if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { - var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; - if (found) - gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + - dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); - } - } - } - - function updateLineWidgets(cm, lineView, dims) { - if (lineView.alignable) lineView.alignable = null; - for (var node = lineView.node.firstChild, next; node; node = next) { - var next = node.nextSibling; - if (node.className == "CodeMirror-linewidget") - lineView.node.removeChild(node); - } - insertLineWidgets(cm, lineView, dims); - } - - // Build a line's DOM representation from scratch - function buildLineElement(cm, lineView, lineN, dims) { - var built = getLineContent(cm, lineView); - lineView.text = lineView.node = built.pre; - if (built.bgClass) lineView.bgClass = built.bgClass; - if (built.textClass) lineView.textClass = built.textClass; - - updateLineClasses(lineView); - updateLineGutter(cm, lineView, lineN, dims); - insertLineWidgets(cm, lineView, dims); - return lineView.node; - } - - // A lineView may contain multiple logical lines (when merged by - // collapsed spans). The widgets for all of them need to be drawn. - function insertLineWidgets(cm, lineView, dims) { - insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); - } - - function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { - if (!line.widgets) return; - var wrap = ensureLineWrapped(lineView); - for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); - if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true"); - positionLineWidget(widget, node, lineView, dims); - cm.display.input.setUneditable(node); - if (allowAbove && widget.above) - wrap.insertBefore(node, lineView.gutter || lineView.text); - else - wrap.appendChild(node); - signalLater(widget, "redraw"); - } - } - - function positionLineWidget(widget, node, lineView, dims) { - if (widget.noHScroll) { - (lineView.alignable || (lineView.alignable = [])).push(node); - var width = dims.wrapperWidth; - node.style.left = dims.fixedPos + "px"; - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth; - node.style.paddingLeft = dims.gutterTotalWidth + "px"; - } - node.style.width = width + "px"; - } - if (widget.coverGutter) { - node.style.zIndex = 5; - node.style.position = "relative"; - if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; - } - } - - // POSITION OBJECT - - // A Pos instance represents a position within the text. - var Pos = CodeMirror.Pos = function(line, ch) { - if (!(this instanceof Pos)) return new Pos(line, ch); - this.line = line; this.ch = ch; - }; - - // Compare two positions, return 0 if they are the same, a negative - // number when a is less, and a positive number otherwise. - var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; - - function copyPos(x) {return Pos(x.line, x.ch);} - function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } - function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } - - // INPUT HANDLING - - function ensureFocus(cm) { - if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } - } - - // This will be set to an array of strings when copying, so that, - // when pasting, we know what kind of selections the copied text - // was made out of. - var lastCopied = null; - - function applyTextInput(cm, inserted, deleted, sel, origin) { - var doc = cm.doc; - cm.display.shift = false; - if (!sel) sel = doc.sel; - - var paste = cm.state.pasteIncoming || origin == "paste"; - var textLines = doc.splitLines(inserted), multiPaste = null; - // When pasing N lines into N selections, insert one line per selection - if (paste && sel.ranges.length > 1) { - if (lastCopied && lastCopied.join("\n") == inserted) { - if (sel.ranges.length % lastCopied.length == 0) { - multiPaste = []; - for (var i = 0; i < lastCopied.length; i++) - multiPaste.push(doc.splitLines(lastCopied[i])); - } - } else if (textLines.length == sel.ranges.length) { - multiPaste = map(textLines, function(l) { return [l]; }); - } - } - - // Normal behavior is to insert the new text into every selection - for (var i = sel.ranges.length - 1; i >= 0; i--) { - var range = sel.ranges[i]; - var from = range.from(), to = range.to(); - if (range.empty()) { - if (deleted && deleted > 0) // Handle deletion - from = Pos(from.line, from.ch - deleted); - else if (cm.state.overwrite && !paste) // Handle overwrite - to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); - } - var updateInput = cm.curOp.updateInput; - var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, - origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")}; - makeChange(cm.doc, changeEvent); - signalLater(cm, "inputRead", cm, changeEvent); - } - if (inserted && !paste) - triggerElectric(cm, inserted); - - ensureCursorVisible(cm); - cm.curOp.updateInput = updateInput; - cm.curOp.typing = true; - cm.state.pasteIncoming = cm.state.cutIncoming = false; - } - - function handlePaste(e, cm) { - var pasted = e.clipboardData && e.clipboardData.getData("text/plain"); - if (pasted) { - e.preventDefault(); - if (!cm.isReadOnly() && !cm.options.disableInput) - runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); }); - return true; - } - } - - function triggerElectric(cm, inserted) { - // When an 'electric' character is inserted, immediately trigger a reindent - if (!cm.options.electricChars || !cm.options.smartIndent) return; - var sel = cm.doc.sel; - - for (var i = sel.ranges.length - 1; i >= 0; i--) { - var range = sel.ranges[i]; - if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; - var mode = cm.getModeAt(range.head); - var indented = false; - if (mode.electricChars) { - for (var j = 0; j < mode.electricChars.length; j++) - if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { - indented = indentLine(cm, range.head.line, "smart"); - break; - } - } else if (mode.electricInput) { - if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) - indented = indentLine(cm, range.head.line, "smart"); - } - if (indented) signalLater(cm, "electricInput", cm, range.head.line); - } - } - - function copyableRanges(cm) { - var text = [], ranges = []; - for (var i = 0; i < cm.doc.sel.ranges.length; i++) { - var line = cm.doc.sel.ranges[i].head.line; - var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; - ranges.push(lineRange); - text.push(cm.getRange(lineRange.anchor, lineRange.head)); - } - return {text: text, ranges: ranges}; - } - - function disableBrowserMagic(field) { - field.setAttribute("autocorrect", "off"); - field.setAttribute("autocapitalize", "off"); - field.setAttribute("spellcheck", "false"); - } - - // TEXTAREA INPUT STYLE - - function TextareaInput(cm) { - this.cm = cm; - // See input.poll and input.reset - this.prevInput = ""; - - // Flag that indicates whether we expect input to appear real soon - // now (after some event like 'keypress' or 'input') and are - // polling intensively. - this.pollingFast = false; - // Self-resetting timeout for the poller - this.polling = new Delayed(); - // Tracks when input.reset has punted to just putting a short - // string into the textarea instead of the full selection. - this.inaccurateSelection = false; - // Used to work around IE issue with selection being forgotten when focus moves away from textarea - this.hasSelection = false; - this.composing = null; - }; - - function hiddenTextarea() { - var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); - var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); - // The textarea is kept positioned near the cursor to prevent the - // fact that it'll be scrolled into view on input from scrolling - // our fake cursor out of view. On webkit, when wrap=off, paste is - // very slow. So make the area wide instead. - if (webkit) te.style.width = "1000px"; - else te.setAttribute("wrap", "off"); - // If border: 0; -- iOS fails to open keyboard (issue #1287) - if (ios) te.style.border = "1px solid black"; - disableBrowserMagic(te); - return div; - } - - TextareaInput.prototype = copyObj({ - init: function(display) { - var input = this, cm = this.cm; - - // Wraps and hides input textarea - var div = this.wrapper = hiddenTextarea(); - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var te = this.textarea = div.firstChild; - display.wrapper.insertBefore(div, display.wrapper.firstChild); - - // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) - if (ios) te.style.width = "0px"; - - on(te, "input", function() { - if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; - input.poll(); - }); - - on(te, "paste", function(e) { - if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return - - cm.state.pasteIncoming = true; - input.fastPoll(); - }); - - function prepareCopyCut(e) { - if (signalDOMEvent(cm, e)) return - if (cm.somethingSelected()) { - lastCopied = cm.getSelections(); - if (input.inaccurateSelection) { - input.prevInput = ""; - input.inaccurateSelection = false; - te.value = lastCopied.join("\n"); - selectInput(te); - } - } else if (!cm.options.lineWiseCopyCut) { - return; - } else { - var ranges = copyableRanges(cm); - lastCopied = ranges.text; - if (e.type == "cut") { - cm.setSelections(ranges.ranges, null, sel_dontScroll); - } else { - input.prevInput = ""; - te.value = ranges.text.join("\n"); - selectInput(te); - } - } - if (e.type == "cut") cm.state.cutIncoming = true; - } - on(te, "cut", prepareCopyCut); - on(te, "copy", prepareCopyCut); - - on(display.scroller, "paste", function(e) { - if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return; - cm.state.pasteIncoming = true; - input.focus(); - }); - - // Prevent normal selection in the editor (we handle our own) - on(display.lineSpace, "selectstart", function(e) { - if (!eventInWidget(display, e)) e_preventDefault(e); - }); - - on(te, "compositionstart", function() { - var start = cm.getCursor("from"); - if (input.composing) input.composing.range.clear() - input.composing = { - start: start, - range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) - }; - }); - on(te, "compositionend", function() { - if (input.composing) { - input.poll(); - input.composing.range.clear(); - input.composing = null; - } - }); - }, - - prepareSelection: function() { - // Redraw the selection and/or cursor - var cm = this.cm, display = cm.display, doc = cm.doc; - var result = prepareSelection(cm); - - // Move the hidden textarea near the cursor to prevent scrolling artifacts - if (cm.options.moveInputWithCursor) { - var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); - var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); - result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, - headPos.top + lineOff.top - wrapOff.top)); - result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, - headPos.left + lineOff.left - wrapOff.left)); - } - - return result; - }, - - showSelection: function(drawn) { - var cm = this.cm, display = cm.display; - removeChildrenAndAdd(display.cursorDiv, drawn.cursors); - removeChildrenAndAdd(display.selectionDiv, drawn.selection); - if (drawn.teTop != null) { - this.wrapper.style.top = drawn.teTop + "px"; - this.wrapper.style.left = drawn.teLeft + "px"; - } - }, - - // Reset the input to correspond to the selection (or to be empty, - // when not typing and nothing is selected) - reset: function(typing) { - if (this.contextMenuPending) return; - var minimal, selected, cm = this.cm, doc = cm.doc; - if (cm.somethingSelected()) { - this.prevInput = ""; - var range = doc.sel.primary(); - minimal = hasCopyEvent && - (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); - var content = minimal ? "-" : selected || cm.getSelection(); - this.textarea.value = content; - if (cm.state.focused) selectInput(this.textarea); - if (ie && ie_version >= 9) this.hasSelection = content; - } else if (!typing) { - this.prevInput = this.textarea.value = ""; - if (ie && ie_version >= 9) this.hasSelection = null; - } - this.inaccurateSelection = minimal; - }, - - getField: function() { return this.textarea; }, - - supportsTouch: function() { return false; }, - - focus: function() { - if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { - try { this.textarea.focus(); } - catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM - } - }, - - blur: function() { this.textarea.blur(); }, - - resetPosition: function() { - this.wrapper.style.top = this.wrapper.style.left = 0; - }, - - receivedFocus: function() { this.slowPoll(); }, - - // Poll for input changes, using the normal rate of polling. This - // runs as long as the editor is focused. - slowPoll: function() { - var input = this; - if (input.pollingFast) return; - input.polling.set(this.cm.options.pollInterval, function() { - input.poll(); - if (input.cm.state.focused) input.slowPoll(); - }); - }, - - // When an event has just come in that is likely to add or change - // something in the input textarea, we poll faster, to ensure that - // the change appears on the screen quickly. - fastPoll: function() { - var missed = false, input = this; - input.pollingFast = true; - function p() { - var changed = input.poll(); - if (!changed && !missed) {missed = true; input.polling.set(60, p);} - else {input.pollingFast = false; input.slowPoll();} - } - input.polling.set(20, p); - }, - - // Read input from the textarea, and update the document to match. - // When something is selected, it is present in the textarea, and - // selected (unless it is huge, in which case a placeholder is - // used). When nothing is selected, the cursor sits after previously - // seen text (can be empty), which is stored in prevInput (we must - // not reset the textarea when typing, because that breaks IME). - poll: function() { - var cm = this.cm, input = this.textarea, prevInput = this.prevInput; - // Since this is called a *lot*, try to bail out as cheaply as - // possible when it is clear that nothing happened. hasSelection - // will be the case when there is a lot of text in the textarea, - // in which case reading its value would be expensive. - if (this.contextMenuPending || !cm.state.focused || - (hasSelection(input) && !prevInput && !this.composing) || - cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) - return false; - - var text = input.value; - // If nothing changed, bail. - if (text == prevInput && !cm.somethingSelected()) return false; - // Work around nonsensical selection resetting in IE9/10, and - // inexplicable appearance of private area unicode characters on - // some key combos in Mac (#2689). - if (ie && ie_version >= 9 && this.hasSelection === text || - mac && /[\uf700-\uf7ff]/.test(text)) { - cm.display.input.reset(); - return false; - } - - if (cm.doc.sel == cm.display.selForContextMenu) { - var first = text.charCodeAt(0); - if (first == 0x200b && !prevInput) prevInput = "\u200b"; - if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } - } - // Find the part of the input that is actually new - var same = 0, l = Math.min(prevInput.length, text.length); - while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; - - var self = this; - runInOp(cm, function() { - applyTextInput(cm, text.slice(same), prevInput.length - same, - null, self.composing ? "*compose" : null); - - // Don't leave long text in the textarea, since it makes further polling slow - if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; - else self.prevInput = text; - - if (self.composing) { - self.composing.range.clear(); - self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), - {className: "CodeMirror-composing"}); - } - }); - return true; - }, - - ensurePolled: function() { - if (this.pollingFast && this.poll()) this.pollingFast = false; - }, - - onKeyPress: function() { - if (ie && ie_version >= 9) this.hasSelection = null; - this.fastPoll(); - }, - - onContextMenu: function(e) { - var input = this, cm = input.cm, display = cm.display, te = input.textarea; - var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; - if (!pos || presto) return; // Opera is difficult. - - // Reset the current text selection only if the click is done outside of the selection - // and 'resetSelectionOnContextMenu' option is true. - var reset = cm.options.resetSelectionOnContextMenu; - if (reset && cm.doc.sel.contains(pos) == -1) - operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); - - var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText; - input.wrapper.style.cssText = "position: absolute" - var wrapperBox = input.wrapper.getBoundingClientRect() - te.style.cssText = "position: absolute; width: 30px; height: 30px; top: " + (e.clientY - wrapperBox.top - 5) + - "px; left: " + (e.clientX - wrapperBox.left - 5) + "px; z-index: 1000; background: " + - (ie ? "rgba(255, 255, 255, .05)" : "transparent") + - "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; - if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) - display.input.focus(); - if (webkit) window.scrollTo(null, oldScrollY); - display.input.reset(); - // Adds "Select all" to context menu in FF - if (!cm.somethingSelected()) te.value = input.prevInput = " "; - input.contextMenuPending = true; - display.selForContextMenu = cm.doc.sel; - clearTimeout(display.detectingSelectAll); - - // Select-all will be greyed out if there's nothing to select, so - // this adds a zero-width space so that we can later check whether - // it got selected. - function prepareSelectAllHack() { - if (te.selectionStart != null) { - var selected = cm.somethingSelected(); - var extval = "\u200b" + (selected ? te.value : ""); - te.value = "\u21da"; // Used to catch context-menu undo - te.value = extval; - input.prevInput = selected ? "" : "\u200b"; - te.selectionStart = 1; te.selectionEnd = extval.length; - // Re-set this, in case some other handler touched the - // selection in the meantime. - display.selForContextMenu = cm.doc.sel; - } - } - function rehide() { - input.contextMenuPending = false; - input.wrapper.style.cssText = oldWrapperCSS - te.style.cssText = oldCSS; - if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); - - // Try to detect the user choosing select-all - if (te.selectionStart != null) { - if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); - var i = 0, poll = function() { - if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && - te.selectionEnd > 0 && input.prevInput == "\u200b") - operation(cm, commands.selectAll)(cm); - else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); - else display.input.reset(); - }; - display.detectingSelectAll = setTimeout(poll, 200); - } - } - - if (ie && ie_version >= 9) prepareSelectAllHack(); - if (captureRightClick) { - e_stop(e); - var mouseup = function() { - off(window, "mouseup", mouseup); - setTimeout(rehide, 20); - }; - on(window, "mouseup", mouseup); - } else { - setTimeout(rehide, 50); - } - }, - - readOnlyChanged: function(val) { - if (!val) this.reset(); - }, - - setUneditable: nothing, - - needsContentAttribute: false - }, TextareaInput.prototype); - - // CONTENTEDITABLE INPUT STYLE - - function ContentEditableInput(cm) { - this.cm = cm; - this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; - this.polling = new Delayed(); - this.gracePeriod = false; - } - - ContentEditableInput.prototype = copyObj({ - init: function(display) { - var input = this, cm = input.cm; - var div = input.div = display.lineDiv; - disableBrowserMagic(div); - - on(div, "paste", function(e) { - if (!signalDOMEvent(cm, e)) handlePaste(e, cm); - }) - - on(div, "compositionstart", function(e) { - var data = e.data; - input.composing = {sel: cm.doc.sel, data: data, startData: data}; - if (!data) return; - var prim = cm.doc.sel.primary(); - var line = cm.getLine(prim.head.line); - var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); - if (found > -1 && found <= prim.head.ch) - input.composing.sel = simpleSelection(Pos(prim.head.line, found), - Pos(prim.head.line, found + data.length)); - }); - on(div, "compositionupdate", function(e) { - input.composing.data = e.data; - }); - on(div, "compositionend", function(e) { - var ours = input.composing; - if (!ours) return; - if (e.data != ours.startData && !/\u200b/.test(e.data)) - ours.data = e.data; - // Need a small delay to prevent other code (input event, - // selection polling) from doing damage when fired right after - // compositionend. - setTimeout(function() { - if (!ours.handled) - input.applyComposition(ours); - if (input.composing == ours) - input.composing = null; - }, 50); - }); - - on(div, "touchstart", function() { - input.forceCompositionEnd(); - }); - - on(div, "input", function() { - if (input.composing) return; - if (cm.isReadOnly() || !input.pollContent()) - runInOp(input.cm, function() {regChange(cm);}); - }); - - function onCopyCut(e) { - if (signalDOMEvent(cm, e)) return - if (cm.somethingSelected()) { - lastCopied = cm.getSelections(); - if (e.type == "cut") cm.replaceSelection("", null, "cut"); - } else if (!cm.options.lineWiseCopyCut) { - return; - } else { - var ranges = copyableRanges(cm); - lastCopied = ranges.text; - if (e.type == "cut") { - cm.operation(function() { - cm.setSelections(ranges.ranges, 0, sel_dontScroll); - cm.replaceSelection("", null, "cut"); - }); - } - } - // iOS exposes the clipboard API, but seems to discard content inserted into it - if (e.clipboardData && !ios) { - e.preventDefault(); - e.clipboardData.clearData(); - e.clipboardData.setData("text/plain", lastCopied.join("\n")); - } else { - // Old-fashioned briefly-focus-a-textarea hack - var kludge = hiddenTextarea(), te = kludge.firstChild; - cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); - te.value = lastCopied.join("\n"); - var hadFocus = document.activeElement; - selectInput(te); - setTimeout(function() { - cm.display.lineSpace.removeChild(kludge); - hadFocus.focus(); - }, 50); - } - } - on(div, "copy", onCopyCut); - on(div, "cut", onCopyCut); - }, - - prepareSelection: function() { - var result = prepareSelection(this.cm, false); - result.focus = this.cm.state.focused; - return result; - }, - - showSelection: function(info) { - if (!info || !this.cm.display.view.length) return; - if (info.focus) this.showPrimarySelection(); - this.showMultipleSelections(info); - }, - - showPrimarySelection: function() { - var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); - var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); - var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); - if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && - cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && - cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) - return; - - var start = posToDOM(this.cm, prim.from()); - var end = posToDOM(this.cm, prim.to()); - if (!start && !end) return; - - var view = this.cm.display.view; - var old = sel.rangeCount && sel.getRangeAt(0); - if (!start) { - start = {node: view[0].measure.map[2], offset: 0}; - } else if (!end) { // FIXME dangerously hacky - var measure = view[view.length - 1].measure; - var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; - end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}; - } - - try { var rng = range(start.node, start.offset, end.offset, end.node); } - catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible - if (rng) { - if (!gecko && this.cm.state.focused) { - sel.collapse(start.node, start.offset); - if (!rng.collapsed) sel.addRange(rng); - } else { - sel.removeAllRanges(); - sel.addRange(rng); - } - if (old && sel.anchorNode == null) sel.addRange(old); - else if (gecko) this.startGracePeriod(); - } - this.rememberSelection(); - }, - - startGracePeriod: function() { - var input = this; - clearTimeout(this.gracePeriod); - this.gracePeriod = setTimeout(function() { - input.gracePeriod = false; - if (input.selectionChanged()) - input.cm.operation(function() { input.cm.curOp.selectionChanged = true; }); - }, 20); - }, - - showMultipleSelections: function(info) { - removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); - removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); - }, - - rememberSelection: function() { - var sel = window.getSelection(); - this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; - this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; - }, - - selectionInEditor: function() { - var sel = window.getSelection(); - if (!sel.rangeCount) return false; - var node = sel.getRangeAt(0).commonAncestorContainer; - return contains(this.div, node); - }, - - focus: function() { - if (this.cm.options.readOnly != "nocursor") this.div.focus(); - }, - blur: function() { this.div.blur(); }, - getField: function() { return this.div; }, - - supportsTouch: function() { return true; }, - - receivedFocus: function() { - var input = this; - if (this.selectionInEditor()) - this.pollSelection(); - else - runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; }); - - function poll() { - if (input.cm.state.focused) { - input.pollSelection(); - input.polling.set(input.cm.options.pollInterval, poll); - } - } - this.polling.set(this.cm.options.pollInterval, poll); - }, - - selectionChanged: function() { - var sel = window.getSelection(); - return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || - sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; - }, - - pollSelection: function() { - if (!this.composing && !this.gracePeriod && this.selectionChanged()) { - var sel = window.getSelection(), cm = this.cm; - this.rememberSelection(); - var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); - var head = domToPos(cm, sel.focusNode, sel.focusOffset); - if (anchor && head) runInOp(cm, function() { - setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); - if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; - }); - } - }, - - pollContent: function() { - var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); - var from = sel.from(), to = sel.to(); - if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; - - var fromIndex; - if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { - var fromLine = lineNo(display.view[0].line); - var fromNode = display.view[0].node; - } else { - var fromLine = lineNo(display.view[fromIndex].line); - var fromNode = display.view[fromIndex - 1].node.nextSibling; - } - var toIndex = findViewIndex(cm, to.line); - if (toIndex == display.view.length - 1) { - var toLine = display.viewTo - 1; - var toNode = display.lineDiv.lastChild; - } else { - var toLine = lineNo(display.view[toIndex + 1].line) - 1; - var toNode = display.view[toIndex + 1].node.previousSibling; - } - - var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); - var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); - while (newText.length > 1 && oldText.length > 1) { - if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } - else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } - else break; - } - - var cutFront = 0, cutEnd = 0; - var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); - while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) - ++cutFront; - var newBot = lst(newText), oldBot = lst(oldText); - var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), - oldBot.length - (oldText.length == 1 ? cutFront : 0)); - while (cutEnd < maxCutEnd && - newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) - ++cutEnd; - - newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); - newText[0] = newText[0].slice(cutFront); - - var chFrom = Pos(fromLine, cutFront); - var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); - if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { - replaceRange(cm.doc, newText, chFrom, chTo, "+input"); - return true; - } - }, - - ensurePolled: function() { - this.forceCompositionEnd(); - }, - reset: function() { - this.forceCompositionEnd(); - }, - forceCompositionEnd: function() { - if (!this.composing || this.composing.handled) return; - this.applyComposition(this.composing); - this.composing.handled = true; - this.div.blur(); - this.div.focus(); - }, - applyComposition: function(composing) { - if (this.cm.isReadOnly()) - operation(this.cm, regChange)(this.cm) - else if (composing.data && composing.data != composing.startData) - operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); - }, - - setUneditable: function(node) { - node.contentEditable = "false" - }, - - onKeyPress: function(e) { - e.preventDefault(); - if (!this.cm.isReadOnly()) - operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); - }, - - readOnlyChanged: function(val) { - this.div.contentEditable = String(val != "nocursor") - }, - - onContextMenu: nothing, - resetPosition: nothing, - - needsContentAttribute: true - }, ContentEditableInput.prototype); - - function posToDOM(cm, pos) { - var view = findViewForLine(cm, pos.line); - if (!view || view.hidden) return null; - var line = getLine(cm.doc, pos.line); - var info = mapFromLineView(view, line, pos.line); - - var order = getOrder(line), side = "left"; - if (order) { - var partPos = getBidiPartAt(order, pos.ch); - side = partPos % 2 ? "right" : "left"; - } - var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); - result.offset = result.collapse == "right" ? result.end : result.start; - return result; - } - - function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } - - function domToPos(cm, node, offset) { - var lineNode; - if (node == cm.display.lineDiv) { - lineNode = cm.display.lineDiv.childNodes[offset]; - if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); - node = null; offset = 0; - } else { - for (lineNode = node;; lineNode = lineNode.parentNode) { - if (!lineNode || lineNode == cm.display.lineDiv) return null; - if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; - } - } - for (var i = 0; i < cm.display.view.length; i++) { - var lineView = cm.display.view[i]; - if (lineView.node == lineNode) - return locateNodeInLineView(lineView, node, offset); - } - } - - function locateNodeInLineView(lineView, node, offset) { - var wrapper = lineView.text.firstChild, bad = false; - if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); - if (node == wrapper) { - bad = true; - node = wrapper.childNodes[offset]; - offset = 0; - if (!node) { - var line = lineView.rest ? lst(lineView.rest) : lineView.line; - return badPos(Pos(lineNo(line), line.text.length), bad); - } - } - - var textNode = node.nodeType == 3 ? node : null, topNode = node; - if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { - textNode = node.firstChild; - if (offset) offset = textNode.nodeValue.length; - } - while (topNode.parentNode != wrapper) topNode = topNode.parentNode; - var measure = lineView.measure, maps = measure.maps; - - function find(textNode, topNode, offset) { - for (var i = -1; i < (maps ? maps.length : 0); i++) { - var map = i < 0 ? measure.map : maps[i]; - for (var j = 0; j < map.length; j += 3) { - var curNode = map[j + 2]; - if (curNode == textNode || curNode == topNode) { - var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); - var ch = map[j] + offset; - if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; - return Pos(line, ch); - } - } - } - } - var found = find(textNode, topNode, offset); - if (found) return badPos(found, bad); - - // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems - for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { - found = find(after, after.firstChild, 0); - if (found) - return badPos(Pos(found.line, found.ch - dist), bad); - else - dist += after.textContent.length; - } - for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { - found = find(before, before.firstChild, -1); - if (found) - return badPos(Pos(found.line, found.ch + dist), bad); - else - dist += after.textContent.length; - } - } - - function domTextBetween(cm, from, to, fromLine, toLine) { - var text = "", closing = false, lineSep = cm.doc.lineSeparator(); - function recognizeMarker(id) { return function(marker) { return marker.id == id; }; } - function walk(node) { - if (node.nodeType == 1) { - var cmText = node.getAttribute("cm-text"); - if (cmText != null) { - if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); - text += cmText; - return; - } - var markerID = node.getAttribute("cm-marker"), range; - if (markerID) { - var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); - if (found.length && (range = found[0].find())) - text += getBetween(cm.doc, range.from, range.to).join(lineSep); - return; - } - if (node.getAttribute("contenteditable") == "false") return; - for (var i = 0; i < node.childNodes.length; i++) - walk(node.childNodes[i]); - if (/^(pre|div|p)$/i.test(node.nodeName)) - closing = true; - } else if (node.nodeType == 3) { - var val = node.nodeValue; - if (!val) return; - if (closing) { - text += lineSep; - closing = false; - } - text += val; - } - } - for (;;) { - walk(from); - if (from == to) break; - from = from.nextSibling; - } - return text; - } - - CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}; - - // SELECTION / CURSOR - - // Selection objects are immutable. A new one is created every time - // the selection changes. A selection is one or more non-overlapping - // (and non-touching) ranges, sorted, and an integer that indicates - // which one is the primary selection (the one that's scrolled into - // view, that getCursor returns, etc). - function Selection(ranges, primIndex) { - this.ranges = ranges; - this.primIndex = primIndex; - } - - Selection.prototype = { - primary: function() { return this.ranges[this.primIndex]; }, - equals: function(other) { - if (other == this) return true; - if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; - for (var i = 0; i < this.ranges.length; i++) { - var here = this.ranges[i], there = other.ranges[i]; - if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; - } - return true; - }, - deepCopy: function() { - for (var out = [], i = 0; i < this.ranges.length; i++) - out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); - return new Selection(out, this.primIndex); - }, - somethingSelected: function() { - for (var i = 0; i < this.ranges.length; i++) - if (!this.ranges[i].empty()) return true; - return false; - }, - contains: function(pos, end) { - if (!end) end = pos; - for (var i = 0; i < this.ranges.length; i++) { - var range = this.ranges[i]; - if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) - return i; - } - return -1; - } - }; - - function Range(anchor, head) { - this.anchor = anchor; this.head = head; - } - - Range.prototype = { - from: function() { return minPos(this.anchor, this.head); }, - to: function() { return maxPos(this.anchor, this.head); }, - empty: function() { - return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; - } - }; - - // Take an unsorted, potentially overlapping set of ranges, and - // build a selection out of it. 'Consumes' ranges array (modifying - // it). - function normalizeSelection(ranges, primIndex) { - var prim = ranges[primIndex]; - ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); - primIndex = indexOf(ranges, prim); - for (var i = 1; i < ranges.length; i++) { - var cur = ranges[i], prev = ranges[i - 1]; - if (cmp(prev.to(), cur.from()) >= 0) { - var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); - var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; - if (i <= primIndex) --primIndex; - ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); - } - } - return new Selection(ranges, primIndex); - } - - function simpleSelection(anchor, head) { - return new Selection([new Range(anchor, head || anchor)], 0); - } - - // Most of the external API clips given positions to make sure they - // actually exist within the document. - function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} - function clipPos(doc, pos) { - if (pos.line < doc.first) return Pos(doc.first, 0); - var last = doc.first + doc.size - 1; - if (pos.line > last) return Pos(last, getLine(doc, last).text.length); - return clipToLen(pos, getLine(doc, pos.line).text.length); - } - function clipToLen(pos, linelen) { - var ch = pos.ch; - if (ch == null || ch > linelen) return Pos(pos.line, linelen); - else if (ch < 0) return Pos(pos.line, 0); - else return pos; - } - function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} - function clipPosArray(doc, array) { - for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); - return out; - } - - // SELECTION UPDATES - - // The 'scroll' parameter given to many of these indicated whether - // the new cursor position should be scrolled into view after - // modifying the selection. - - // If shift is held or the extend flag is set, extends a range to - // include a given position (and optionally a second position). - // Otherwise, simply returns the range between the given positions. - // Used for cursor motion and such. - function extendRange(doc, range, head, other) { - if (doc.cm && doc.cm.display.shift || doc.extend) { - var anchor = range.anchor; - if (other) { - var posBefore = cmp(head, anchor) < 0; - if (posBefore != (cmp(other, anchor) < 0)) { - anchor = head; - head = other; - } else if (posBefore != (cmp(head, other) < 0)) { - head = other; - } - } - return new Range(anchor, head); - } else { - return new Range(other || head, head); - } - } - - // Extend the primary selection range, discard the rest. - function extendSelection(doc, head, other, options) { - setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); - } - - // Extend all selections (pos is an array of selections with length - // equal the number of selections) - function extendSelections(doc, heads, options) { - for (var out = [], i = 0; i < doc.sel.ranges.length; i++) - out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); - var newSel = normalizeSelection(out, doc.sel.primIndex); - setSelection(doc, newSel, options); - } - - // Updates a single range in the selection. - function replaceOneSelection(doc, i, range, options) { - var ranges = doc.sel.ranges.slice(0); - ranges[i] = range; - setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); - } - - // Reset the selection to a single range. - function setSimpleSelection(doc, anchor, head, options) { - setSelection(doc, simpleSelection(anchor, head), options); - } - - // Give beforeSelectionChange handlers a change to influence a - // selection update. - function filterSelectionChange(doc, sel, options) { - var obj = { - ranges: sel.ranges, - update: function(ranges) { - this.ranges = []; - for (var i = 0; i < ranges.length; i++) - this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), - clipPos(doc, ranges[i].head)); - }, - origin: options && options.origin - }; - signal(doc, "beforeSelectionChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); - if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); - else return sel; - } - - function setSelectionReplaceHistory(doc, sel, options) { - var done = doc.history.done, last = lst(done); - if (last && last.ranges) { - done[done.length - 1] = sel; - setSelectionNoUndo(doc, sel, options); - } else { - setSelection(doc, sel, options); - } - } - - // Set a new selection. - function setSelection(doc, sel, options) { - setSelectionNoUndo(doc, sel, options); - addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); - } - - function setSelectionNoUndo(doc, sel, options) { - if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) - sel = filterSelectionChange(doc, sel, options); - - var bias = options && options.bias || - (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); - setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); - - if (!(options && options.scroll === false) && doc.cm) - ensureCursorVisible(doc.cm); - } - - function setSelectionInner(doc, sel) { - if (sel.equals(doc.sel)) return; - - doc.sel = sel; - - if (doc.cm) { - doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; - signalCursorActivity(doc.cm); - } - signalLater(doc, "cursorActivity", doc); - } - - // Verify that the selection does not partially select any atomic - // marked ranges. - function reCheckSelection(doc) { - setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); - } - - // Return a selection that does not partially select any atomic - // ranges. - function skipAtomicInSelection(doc, sel, bias, mayClear) { - var out; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; - var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); - var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); - if (out || newAnchor != range.anchor || newHead != range.head) { - if (!out) out = sel.ranges.slice(0, i); - out[i] = new Range(newAnchor, newHead); - } - } - return out ? normalizeSelection(out, sel.primIndex) : sel; - } - - function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { - var line = getLine(doc, pos.line); - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker; - if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && - (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter"); - if (m.explicitlyCleared) { - if (!line.markedSpans) break; - else {--i; continue;} - } - } - if (!m.atomic) continue; - - if (oldPos) { - var near = m.find(dir < 0 ? 1 : -1), diff; - if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) - near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); - if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) - return skipAtomicInner(doc, near, pos, dir, mayClear); - } - - var far = m.find(dir < 0 ? -1 : 1); - if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) - far = movePos(doc, far, dir, far.line == pos.line ? line : null); - return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null; - } - } - return pos; - } - - // Ensure a given position is not inside an atomic range. - function skipAtomic(doc, pos, oldPos, bias, mayClear) { - var dir = bias || 1; - var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || - skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)); - if (!found) { - doc.cantEdit = true; - return Pos(doc.first, 0); - } - return found; - } - - function movePos(doc, pos, dir, line) { - if (dir < 0 && pos.ch == 0) { - if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1)); - else return null; - } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { - if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0); - else return null; - } else { - return new Pos(pos.line, pos.ch + dir); - } - } - - // SELECTION DRAWING - - function updateSelection(cm) { - cm.display.input.showSelection(cm.display.input.prepareSelection()); - } - - function prepareSelection(cm, primary) { - var doc = cm.doc, result = {}; - var curFragment = result.cursors = document.createDocumentFragment(); - var selFragment = result.selection = document.createDocumentFragment(); - - for (var i = 0; i < doc.sel.ranges.length; i++) { - if (primary === false && i == doc.sel.primIndex) continue; - var range = doc.sel.ranges[i]; - if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue; - var collapsed = range.empty(); - if (collapsed || cm.options.showCursorWhenSelecting) - drawSelectionCursor(cm, range.head, curFragment); - if (!collapsed) - drawSelectionRange(cm, range, selFragment); - } - return result; - } - - // Draws a cursor for the given range - function drawSelectionCursor(cm, head, output) { - var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); - - var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); - cursor.style.left = pos.left + "px"; - cursor.style.top = pos.top + "px"; - cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; - - if (pos.other) { - // Secondary cursor, shown when on a 'jump' in bi-directional text - var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); - otherCursor.style.display = ""; - otherCursor.style.left = pos.other.left + "px"; - otherCursor.style.top = pos.other.top + "px"; - otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; - } - } - - // Draws the given range as a highlighted selection - function drawSelectionRange(cm, range, output) { - var display = cm.display, doc = cm.doc; - var fragment = document.createDocumentFragment(); - var padding = paddingH(cm.display), leftSide = padding.left; - var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; - - function add(left, top, width, bottom) { - if (top < 0) top = 0; - top = Math.round(top); - bottom = Math.round(bottom); - fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + - "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + - "px; height: " + (bottom - top) + "px")); - } - - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line); - var lineLen = lineObj.text.length; - var start, end; - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias); - } - - iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { - var leftPos = coords(from, "left"), rightPos, left, right; - if (from == to) { - rightPos = leftPos; - left = right = leftPos.left; - } else { - rightPos = coords(to - 1, "right"); - if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } - left = leftPos.left; - right = rightPos.right; - } - if (fromArg == null && from == 0) left = leftSide; - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom); - left = leftSide; - if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); - } - if (toArg == null && to == lineLen) right = rightSide; - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - start = leftPos; - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - end = rightPos; - if (left < leftSide + 1) left = leftSide; - add(left, rightPos.top, right - left, rightPos.bottom); - }); - return {start: start, end: end}; - } - - var sFrom = range.from(), sTo = range.to(); - if (sFrom.line == sTo.line) { - drawForLine(sFrom.line, sFrom.ch, sTo.ch); - } else { - var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); - var singleVLine = visualLine(fromLine) == visualLine(toLine); - var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; - var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); - add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); - } - } - if (leftEnd.bottom < rightStart.top) - add(leftSide, leftEnd.bottom, null, rightStart.top); - } - - output.appendChild(fragment); - } - - // Cursor-blinking - function restartBlink(cm) { - if (!cm.state.focused) return; - var display = cm.display; - clearInterval(display.blinker); - var on = true; - display.cursorDiv.style.visibility = ""; - if (cm.options.cursorBlinkRate > 0) - display.blinker = setInterval(function() { - display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; - }, cm.options.cursorBlinkRate); - else if (cm.options.cursorBlinkRate < 0) - display.cursorDiv.style.visibility = "hidden"; - } - - // HIGHLIGHT WORKER - - function startWorker(cm, time) { - if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) - cm.state.highlight.set(time, bind(highlightWorker, cm)); - } - - function highlightWorker(cm) { - var doc = cm.doc; - if (doc.frontier < doc.first) doc.frontier = doc.first; - if (doc.frontier >= cm.display.viewTo) return; - var end = +new Date + cm.options.workTime; - var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); - var changedLines = []; - - doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { - if (doc.frontier >= cm.display.viewFrom) { // Visible - var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength; - var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true); - line.styles = highlighted.styles; - var oldCls = line.styleClasses, newCls = highlighted.classes; - if (newCls) line.styleClasses = newCls; - else if (oldCls) line.styleClasses = null; - var ischange = !oldStyles || oldStyles.length != line.styles.length || - oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); - for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; - if (ischange) changedLines.push(doc.frontier); - line.stateAfter = tooLong ? state : copyState(doc.mode, state); - } else { - if (line.text.length <= cm.options.maxHighlightLength) - processLine(cm, line.text, state); - line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; - } - ++doc.frontier; - if (+new Date > end) { - startWorker(cm, cm.options.workDelay); - return true; - } - }); - if (changedLines.length) runInOp(cm, function() { - for (var i = 0; i < changedLines.length; i++) - regLineChange(cm, changedLines[i], "text"); - }); - } - - // Finds the line to start with when starting a parse. Tries to - // find a line with a stateAfter, so that it can start with a - // valid state. If that fails, it returns the line with the - // smallest indentation, which tends to need the least context to - // parse correctly. - function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc; - var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); - for (var search = n; search > lim; --search) { - if (search <= doc.first) return doc.first; - var line = getLine(doc, search - 1); - if (line.stateAfter && (!precise || search <= doc.frontier)) return search; - var indented = countColumn(line.text, null, cm.options.tabSize); - if (minline == null || minindent > indented) { - minline = search - 1; - minindent = indented; - } - } - return minline; - } - - function getStateBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display; - if (!doc.mode.startState) return true; - var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; - if (!state) state = startState(doc.mode); - else state = copyState(doc.mode, state); - doc.iter(pos, n, function(line) { - processLine(cm, line.text, state); - var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; - line.stateAfter = save ? copyState(doc.mode, state) : null; - ++pos; - }); - if (precise) doc.frontier = pos; - return state; - } - - // POSITION MEASUREMENT - - function paddingTop(display) {return display.lineSpace.offsetTop;} - function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} - function paddingH(display) { - if (display.cachedPaddingH) return display.cachedPaddingH; - var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); - var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; - var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; - if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; - return data; - } - - function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } - function displayWidth(cm) { - return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; - } - function displayHeight(cm) { - return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; - } - - // Ensure the lineView.wrapping.heights array is populated. This is - // an array of bottom offsets for the lines that make up a drawn - // line. When lineWrapping is on, there might be more than one - // height. - function ensureLineHeights(cm, lineView, rect) { - var wrapping = cm.options.lineWrapping; - var curWidth = wrapping && displayWidth(cm); - if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { - var heights = lineView.measure.heights = []; - if (wrapping) { - lineView.measure.width = curWidth; - var rects = lineView.text.firstChild.getClientRects(); - for (var i = 0; i < rects.length - 1; i++) { - var cur = rects[i], next = rects[i + 1]; - if (Math.abs(cur.bottom - next.bottom) > 2) - heights.push((cur.bottom + next.top) / 2 - rect.top); - } - } - heights.push(rect.bottom - rect.top); - } - } - - // Find a line map (mapping character offsets to text nodes) and a - // measurement cache for the given line number. (A line view might - // contain multiple lines when collapsed ranges are present.) - function mapFromLineView(lineView, line, lineN) { - if (lineView.line == line) - return {map: lineView.measure.map, cache: lineView.measure.cache}; - for (var i = 0; i < lineView.rest.length; i++) - if (lineView.rest[i] == line) - return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; - for (var i = 0; i < lineView.rest.length; i++) - if (lineNo(lineView.rest[i]) > lineN) - return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; - } - - // Render a line into the hidden node display.externalMeasured. Used - // when measurement is needed for a line that's not in the viewport. - function updateExternalMeasurement(cm, line) { - line = visualLine(line); - var lineN = lineNo(line); - var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); - view.lineN = lineN; - var built = view.built = buildLineContent(cm, view); - view.text = built.pre; - removeChildrenAndAdd(cm.display.lineMeasure, built.pre); - return view; - } - - // Get a {top, bottom, left, right} box (in line-local coordinates) - // for a given character. - function measureChar(cm, line, ch, bias) { - return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); - } - - // Find a line view that corresponds to the given line number. - function findViewForLine(cm, lineN) { - if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) - return cm.display.view[findViewIndex(cm, lineN)]; - var ext = cm.display.externalMeasured; - if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) - return ext; - } - - // Measurement can be split in two steps, the set-up work that - // applies to the whole line, and the measurement of the actual - // character. Functions like coordsChar, that need to do a lot of - // measurements in a row, can thus ensure that the set-up work is - // only done once. - function prepareMeasureForLine(cm, line) { - var lineN = lineNo(line); - var view = findViewForLine(cm, lineN); - if (view && !view.text) { - view = null; - } else if (view && view.changes) { - updateLineForChanges(cm, view, lineN, getDimensions(cm)); - cm.curOp.forceUpdate = true; - } - if (!view) - view = updateExternalMeasurement(cm, line); - - var info = mapFromLineView(view, line, lineN); - return { - line: line, view: view, rect: null, - map: info.map, cache: info.cache, before: info.before, - hasHeights: false - }; - } - - // Given a prepared measurement object, measures the position of an - // actual character (or fetches it from the cache). - function measureCharPrepared(cm, prepared, ch, bias, varHeight) { - if (prepared.before) ch = -1; - var key = ch + (bias || ""), found; - if (prepared.cache.hasOwnProperty(key)) { - found = prepared.cache[key]; - } else { - if (!prepared.rect) - prepared.rect = prepared.view.text.getBoundingClientRect(); - if (!prepared.hasHeights) { - ensureLineHeights(cm, prepared.view, prepared.rect); - prepared.hasHeights = true; - } - found = measureCharInner(cm, prepared, ch, bias); - if (!found.bogus) prepared.cache[key] = found; - } - return {left: found.left, right: found.right, - top: varHeight ? found.rtop : found.top, - bottom: varHeight ? found.rbottom : found.bottom}; - } - - var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; - - function nodeAndOffsetInLineMap(map, ch, bias) { - var node, start, end, collapse; - // First, search the line map for the text node corresponding to, - // or closest to, the target character. - for (var i = 0; i < map.length; i += 3) { - var mStart = map[i], mEnd = map[i + 1]; - if (ch < mStart) { - start = 0; end = 1; - collapse = "left"; - } else if (ch < mEnd) { - start = ch - mStart; - end = start + 1; - } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { - end = mEnd - mStart; - start = end - 1; - if (ch >= mEnd) collapse = "right"; - } - if (start != null) { - node = map[i + 2]; - if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) - collapse = bias; - if (bias == "left" && start == 0) - while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { - node = map[(i -= 3) + 2]; - collapse = "left"; - } - if (bias == "right" && start == mEnd - mStart) - while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { - node = map[(i += 3) + 2]; - collapse = "right"; - } - break; - } - } - return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}; - } - - function measureCharInner(cm, prepared, ch, bias) { - var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); - var node = place.node, start = place.start, end = place.end, collapse = place.collapse; - - var rect; - if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned - while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; - while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; - if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { - rect = node.parentNode.getBoundingClientRect(); - } else if (ie && cm.options.lineWrapping) { - var rects = range(node, start, end).getClientRects(); - if (rects.length) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = nullRect; - } else { - rect = range(node, start, end).getBoundingClientRect() || nullRect; - } - if (rect.left || rect.right || start == 0) break; - end = start; - start = start - 1; - collapse = "right"; - } - if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); - } else { // If it is a widget, simply get the box for the whole widget. - if (start > 0) collapse = bias = "right"; - var rects; - if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = node.getBoundingClientRect(); - } - if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { - var rSpan = node.parentNode.getClientRects()[0]; - if (rSpan) - rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; - else - rect = nullRect; - } - - var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; - var mid = (rtop + rbot) / 2; - var heights = prepared.view.measure.heights; - for (var i = 0; i < heights.length - 1; i++) - if (mid < heights[i]) break; - var top = i ? heights[i - 1] : 0, bot = heights[i]; - var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, - right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, - top: top, bottom: bot}; - if (!rect.left && !rect.right) result.bogus = true; - if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } - - return result; - } - - // Work around problem with bounding client rects on ranges being - // returned incorrectly when zoomed on IE10 and below. - function maybeUpdateRectForZooming(measure, rect) { - if (!window.screen || screen.logicalXDPI == null || - screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) - return rect; - var scaleX = screen.logicalXDPI / screen.deviceXDPI; - var scaleY = screen.logicalYDPI / screen.deviceYDPI; - return {left: rect.left * scaleX, right: rect.right * scaleX, - top: rect.top * scaleY, bottom: rect.bottom * scaleY}; - } - - function clearLineMeasurementCacheFor(lineView) { - if (lineView.measure) { - lineView.measure.cache = {}; - lineView.measure.heights = null; - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - lineView.measure.caches[i] = {}; - } - } - - function clearLineMeasurementCache(cm) { - cm.display.externalMeasure = null; - removeChildren(cm.display.lineMeasure); - for (var i = 0; i < cm.display.view.length; i++) - clearLineMeasurementCacheFor(cm.display.view[i]); - } - - function clearCaches(cm) { - clearLineMeasurementCache(cm); - cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; - if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; - cm.display.lineNumChars = null; - } - - function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } - function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } - - // Converts a {top, bottom, left, right} box from line-local - // coordinates into another coordinate system. Context may be one of - // "line", "div" (display.lineDiv), "local"/null (editor), "window", - // or "page". - function intoCoordSystem(cm, lineObj, rect, context) { - if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { - var size = widgetHeight(lineObj.widgets[i]); - rect.top += size; rect.bottom += size; - } - if (context == "line") return rect; - if (!context) context = "local"; - var yOff = heightAtLine(lineObj); - if (context == "local") yOff += paddingTop(cm.display); - else yOff -= cm.display.viewOffset; - if (context == "page" || context == "window") { - var lOff = cm.display.lineSpace.getBoundingClientRect(); - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); - rect.left += xOff; rect.right += xOff; - } - rect.top += yOff; rect.bottom += yOff; - return rect; - } - - // Coverts a box from "div" coords to another coordinate system. - // Context may be "window", "page", "div", or "local"/null. - function fromCoordSystem(cm, coords, context) { - if (context == "div") return coords; - var left = coords.left, top = coords.top; - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX(); - top -= pageScrollY(); - } else if (context == "local" || !context) { - var localBox = cm.display.sizer.getBoundingClientRect(); - left += localBox.left; - top += localBox.top; - } - - var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); - return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; - } - - function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) lineObj = getLine(cm.doc, pos.line); - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); - } - - // Returns a box for a given cursor position, which may have an - // 'other' property containing the position of the secondary cursor - // on a bidi boundary. - function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { - lineObj = lineObj || getLine(cm.doc, pos.line); - if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); - function get(ch, right) { - var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); - if (right) m.left = m.right; else m.right = m.left; - return intoCoordSystem(cm, lineObj, m, context); - } - function getBidi(ch, partPos) { - var part = order[partPos], right = part.level % 2; - if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { - part = order[--partPos]; - ch = bidiRight(part) - (part.level % 2 ? 0 : 1); - right = true; - } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { - part = order[++partPos]; - ch = bidiLeft(part) - part.level % 2; - right = false; - } - if (right && ch == part.to && ch > part.from) return get(ch - 1); - return get(ch, right); - } - var order = getOrder(lineObj), ch = pos.ch; - if (!order) return get(ch); - var partPos = getBidiPartAt(order, ch); - var val = getBidi(ch, partPos); - if (bidiOther != null) val.other = getBidi(ch, bidiOther); - return val; - } - - // Used to cheaply estimate the coordinates for a position. Used for - // intermediate scroll updates. - function estimateCoords(cm, pos) { - var left = 0, pos = clipPos(cm.doc, pos); - if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; - var lineObj = getLine(cm.doc, pos.line); - var top = heightAtLine(lineObj) + paddingTop(cm.display); - return {left: left, right: left, top: top, bottom: top + lineObj.height}; - } - - // Positions returned by coordsChar contain some extra information. - // xRel is the relative x position of the input coordinates compared - // to the found position (so xRel > 0 means the coordinates are to - // the right of the character position, for example). When outside - // is true, that means the coordinates lie outside the line's - // vertical range. - function PosWithInfo(line, ch, outside, xRel) { - var pos = Pos(line, ch); - pos.xRel = xRel; - if (outside) pos.outside = true; - return pos; - } - - // Compute the character position closest to the given coordinates. - // Input must be lineSpace-local ("div" coordinate system). - function coordsChar(cm, x, y) { - var doc = cm.doc; - y += cm.display.viewOffset; - if (y < 0) return PosWithInfo(doc.first, 0, true, -1); - var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; - if (lineN > last) - return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); - if (x < 0) x = 0; - - var lineObj = getLine(doc, lineN); - for (;;) { - var found = coordsCharInner(cm, lineObj, lineN, x, y); - var merged = collapsedSpanAtEnd(lineObj); - var mergedPos = merged && merged.find(0, true); - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - lineN = lineNo(lineObj = mergedPos.to.line); - else - return found; - } - } - - function coordsCharInner(cm, lineObj, lineNo, x, y) { - var innerOff = y - heightAtLine(lineObj); - var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; - var preparedMeasure = prepareMeasureForLine(cm, lineObj); - - function getX(ch) { - var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); - wrongLine = true; - if (innerOff > sp.bottom) return sp.left - adjust; - else if (innerOff < sp.top) return sp.left + adjust; - else wrongLine = false; - return sp.left; - } - - var bidi = getOrder(lineObj), dist = lineObj.text.length; - var from = lineLeft(lineObj), to = lineRight(lineObj); - var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; - - if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); - // Do a binary search between these bounds. - for (;;) { - if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { - var ch = x < fromX || x - fromX <= toX - x ? from : to; - var xDiff = x - (ch == from ? fromX : toX); - while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; - var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, - xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); - return pos; - } - var step = Math.ceil(dist / 2), middle = from + step; - if (bidi) { - middle = from; - for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); - } - var middleX = getX(middle); - if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} - else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} - } - } - - var measureText; - // Compute the default text height. - function textHeight(display) { - if (display.cachedTextHeight != null) return display.cachedTextHeight; - if (measureText == null) { - measureText = elt("pre"); - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")); - measureText.appendChild(elt("br")); - } - measureText.appendChild(document.createTextNode("x")); - } - removeChildrenAndAdd(display.measure, measureText); - var height = measureText.offsetHeight / 50; - if (height > 3) display.cachedTextHeight = height; - removeChildren(display.measure); - return height || 1; - } - - // Compute the default character width. - function charWidth(display) { - if (display.cachedCharWidth != null) return display.cachedCharWidth; - var anchor = elt("span", "xxxxxxxxxx"); - var pre = elt("pre", [anchor]); - removeChildrenAndAdd(display.measure, pre); - var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; - if (width > 2) display.cachedCharWidth = width; - return width || 10; - } - - // OPERATIONS - - // Operations are used to wrap a series of changes to the editor - // state in such a way that each change won't have to update the - // cursor and display (which would be awkward, slow, and - // error-prone). Instead, display updates are batched and then all - // combined and executed at once. - - var operationGroup = null; - - var nextOpId = 0; - // Start a new operation. - function startOperation(cm) { - cm.curOp = { - cm: cm, - viewChanged: false, // Flag that indicates that lines might need to be redrawn - startHeight: cm.doc.height, // Used to detect need to update scrollbar - forceUpdate: false, // Used to force a redraw - updateInput: null, // Whether to reset the input textarea - typing: false, // Whether this reset should be careful to leave existing text (for compositing) - changeObjs: null, // Accumulated changes, for firing change events - cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on - cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already - selectionChanged: false, // Whether the selection needs to be redrawn - updateMaxLine: false, // Set when the widest line needs to be determined anew - scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet - scrollToPos: null, // Used to scroll to a specific position - focus: false, - id: ++nextOpId // Unique ID - }; - if (operationGroup) { - operationGroup.ops.push(cm.curOp); - } else { - cm.curOp.ownsGroup = operationGroup = { - ops: [cm.curOp], - delayedCallbacks: [] - }; - } - } - - function fireCallbacksForOps(group) { - // Calls delayed callbacks and cursorActivity handlers until no - // new ones appear - var callbacks = group.delayedCallbacks, i = 0; - do { - for (; i < callbacks.length; i++) - callbacks[i].call(null); - for (var j = 0; j < group.ops.length; j++) { - var op = group.ops[j]; - if (op.cursorActivityHandlers) - while (op.cursorActivityCalled < op.cursorActivityHandlers.length) - op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); - } - } while (i < callbacks.length); - } - - // Finish an operation, updating the display and signalling delayed events - function endOperation(cm) { - var op = cm.curOp, group = op.ownsGroup; - if (!group) return; - - try { fireCallbacksForOps(group); } - finally { - operationGroup = null; - for (var i = 0; i < group.ops.length; i++) - group.ops[i].cm.curOp = null; - endOperations(group); - } - } - - // The DOM updates done when an operation finishes are batched so - // that the minimum number of relayouts are required. - function endOperations(group) { - var ops = group.ops; - for (var i = 0; i < ops.length; i++) // Read DOM - endOperation_R1(ops[i]); - for (var i = 0; i < ops.length; i++) // Write DOM (maybe) - endOperation_W1(ops[i]); - for (var i = 0; i < ops.length; i++) // Read DOM - endOperation_R2(ops[i]); - for (var i = 0; i < ops.length; i++) // Write DOM (maybe) - endOperation_W2(ops[i]); - for (var i = 0; i < ops.length; i++) // Read DOM - endOperation_finish(ops[i]); - } - - function endOperation_R1(op) { - var cm = op.cm, display = cm.display; - maybeClipScrollbars(cm); - if (op.updateMaxLine) findMaxLine(cm); - - op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || - op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || - op.scrollToPos.to.line >= display.viewTo) || - display.maxLineChanged && cm.options.lineWrapping; - op.update = op.mustUpdate && - new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); - } - - function endOperation_W1(op) { - op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); - } - - function endOperation_R2(op) { - var cm = op.cm, display = cm.display; - if (op.updatedDisplay) updateHeightsInViewport(cm); - - op.barMeasure = measureForScrollbars(cm); - - // If the max line changed since it was last measured, measure it, - // and ensure the document's width matches it. - // updateDisplay_W2 will use these properties to do the actual resizing - if (display.maxLineChanged && !cm.options.lineWrapping) { - op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; - cm.display.sizerWidth = op.adjustWidthTo; - op.barMeasure.scrollWidth = - Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); - op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); - } - - if (op.updatedDisplay || op.selectionChanged) - op.preparedSelection = display.input.prepareSelection(); - } - - function endOperation_W2(op) { - var cm = op.cm; - - if (op.adjustWidthTo != null) { - cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; - if (op.maxScrollLeft < cm.doc.scrollLeft) - setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); - cm.display.maxLineChanged = false; - } - - if (op.preparedSelection) - cm.display.input.showSelection(op.preparedSelection); - if (op.updatedDisplay || op.startHeight != cm.doc.height) - updateScrollbars(cm, op.barMeasure); - if (op.updatedDisplay) - setDocumentHeight(cm, op.barMeasure); - - if (op.selectionChanged) restartBlink(cm); - - if (cm.state.focused && op.updateInput) - cm.display.input.reset(op.typing); - if (op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus())) - ensureFocus(op.cm); - } - - function endOperation_finish(op) { - var cm = op.cm, display = cm.display, doc = cm.doc; - - if (op.updatedDisplay) postUpdateDisplay(cm, op.update); - - // Abort mouse wheel delta measurement, when scrolling explicitly - if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) - display.wheelStartX = display.wheelStartY = null; - - // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { - doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); - display.scrollbars.setScrollTop(doc.scrollTop); - display.scroller.scrollTop = doc.scrollTop; - } - if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { - doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); - display.scrollbars.setScrollLeft(doc.scrollLeft); - display.scroller.scrollLeft = doc.scrollLeft; - alignHorizontally(cm); - } - // If we need to scroll a specific position into view, do so. - if (op.scrollToPos) { - var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), - clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); - if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); - } - - // Fire events for markers that are hidden/unidden by editing or - // undoing - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; - if (hidden) for (var i = 0; i < hidden.length; ++i) - if (!hidden[i].lines.length) signal(hidden[i], "hide"); - if (unhidden) for (var i = 0; i < unhidden.length; ++i) - if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); - - if (display.wrapper.offsetHeight) - doc.scrollTop = cm.display.scroller.scrollTop; - - // Fire change events, and delayed event handlers - if (op.changeObjs) - signal(cm, "changes", cm, op.changeObjs); - if (op.update) - op.update.finish(); - } - - // Run the given function in an operation - function runInOp(cm, f) { - if (cm.curOp) return f(); - startOperation(cm); - try { return f(); } - finally { endOperation(cm); } - } - // Wraps a function in an operation. Returns the wrapped function. - function operation(cm, f) { - return function() { - if (cm.curOp) return f.apply(cm, arguments); - startOperation(cm); - try { return f.apply(cm, arguments); } - finally { endOperation(cm); } - }; - } - // Used to add methods to editor and doc instances, wrapping them in - // operations. - function methodOp(f) { - return function() { - if (this.curOp) return f.apply(this, arguments); - startOperation(this); - try { return f.apply(this, arguments); } - finally { endOperation(this); } - }; - } - function docMethodOp(f) { - return function() { - var cm = this.cm; - if (!cm || cm.curOp) return f.apply(this, arguments); - startOperation(cm); - try { return f.apply(this, arguments); } - finally { endOperation(cm); } - }; - } - - // VIEW TRACKING - - // These objects are used to represent the visible (currently drawn) - // part of the document. A LineView may correspond to multiple - // logical lines, if those are connected by collapsed ranges. - function LineView(doc, line, lineN) { - // The starting line - this.line = line; - // Continuing lines, if any - this.rest = visualLineContinued(line); - // Number of logical lines in this visual line - this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; - this.node = this.text = null; - this.hidden = lineIsHidden(doc, line); - } - - // Create a range of LineView objects for the given lines. - function buildViewArray(cm, from, to) { - var array = [], nextPos; - for (var pos = from; pos < to; pos = nextPos) { - var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); - nextPos = pos + view.size; - array.push(view); - } - return array; - } - - // Updates the display.view data structure for a given change to the - // document. From and to are in pre-change coordinates. Lendiff is - // the amount of lines added or subtracted by the change. This is - // used for changes that span multiple lines, or change the way - // lines are divided into visual lines. regLineChange (below) - // registers single-line changes. - function regChange(cm, from, to, lendiff) { - if (from == null) from = cm.doc.first; - if (to == null) to = cm.doc.first + cm.doc.size; - if (!lendiff) lendiff = 0; - - var display = cm.display; - if (lendiff && to < display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers > from)) - display.updateLineNumbers = from; - - cm.curOp.viewChanged = true; - - if (from >= display.viewTo) { // Change after - if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) - resetView(cm); - } else if (to <= display.viewFrom) { // Change before - if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { - resetView(cm); - } else { - display.viewFrom += lendiff; - display.viewTo += lendiff; - } - } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap - resetView(cm); - } else if (from <= display.viewFrom) { // Top overlap - var cut = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cut) { - display.view = display.view.slice(cut.index); - display.viewFrom = cut.lineN; - display.viewTo += lendiff; - } else { - resetView(cm); - } - } else if (to >= display.viewTo) { // Bottom overlap - var cut = viewCuttingPoint(cm, from, from, -1); - if (cut) { - display.view = display.view.slice(0, cut.index); - display.viewTo = cut.lineN; - } else { - resetView(cm); - } - } else { // Gap in the middle - var cutTop = viewCuttingPoint(cm, from, from, -1); - var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cutTop && cutBot) { - display.view = display.view.slice(0, cutTop.index) - .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) - .concat(display.view.slice(cutBot.index)); - display.viewTo += lendiff; - } else { - resetView(cm); - } - } - - var ext = display.externalMeasured; - if (ext) { - if (to < ext.lineN) - ext.lineN += lendiff; - else if (from < ext.lineN + ext.size) - display.externalMeasured = null; - } - } - - // Register a change to a single line. Type must be one of "text", - // "gutter", "class", "widget" - function regLineChange(cm, line, type) { - cm.curOp.viewChanged = true; - var display = cm.display, ext = cm.display.externalMeasured; - if (ext && line >= ext.lineN && line < ext.lineN + ext.size) - display.externalMeasured = null; - - if (line < display.viewFrom || line >= display.viewTo) return; - var lineView = display.view[findViewIndex(cm, line)]; - if (lineView.node == null) return; - var arr = lineView.changes || (lineView.changes = []); - if (indexOf(arr, type) == -1) arr.push(type); - } - - // Clear the view. - function resetView(cm) { - cm.display.viewFrom = cm.display.viewTo = cm.doc.first; - cm.display.view = []; - cm.display.viewOffset = 0; - } - - // Find the view element corresponding to a given line. Return null - // when the line isn't visible. - function findViewIndex(cm, n) { - if (n >= cm.display.viewTo) return null; - n -= cm.display.viewFrom; - if (n < 0) return null; - var view = cm.display.view; - for (var i = 0; i < view.length; i++) { - n -= view[i].size; - if (n < 0) return i; - } - } - - function viewCuttingPoint(cm, oldN, newN, dir) { - var index = findViewIndex(cm, oldN), diff, view = cm.display.view; - if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) - return {index: index, lineN: newN}; - for (var i = 0, n = cm.display.viewFrom; i < index; i++) - n += view[i].size; - if (n != oldN) { - if (dir > 0) { - if (index == view.length - 1) return null; - diff = (n + view[index].size) - oldN; - index++; - } else { - diff = n - oldN; - } - oldN += diff; newN += diff; - } - while (visualLineNo(cm.doc, newN) != newN) { - if (index == (dir < 0 ? 0 : view.length - 1)) return null; - newN += dir * view[index - (dir < 0 ? 1 : 0)].size; - index += dir; - } - return {index: index, lineN: newN}; - } - - // Force the view to cover a given range, adding empty view element - // or clipping off existing ones as needed. - function adjustView(cm, from, to) { - var display = cm.display, view = display.view; - if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { - display.view = buildViewArray(cm, from, to); - display.viewFrom = from; - } else { - if (display.viewFrom > from) - display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); - else if (display.viewFrom < from) - display.view = display.view.slice(findViewIndex(cm, from)); - display.viewFrom = from; - if (display.viewTo < to) - display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); - else if (display.viewTo > to) - display.view = display.view.slice(0, findViewIndex(cm, to)); - } - display.viewTo = to; - } - - // Count the number of lines in the view whose DOM representation is - // out of date (or nonexistent). - function countDirtyView(cm) { - var view = cm.display.view, dirty = 0; - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; - } - return dirty; - } - - // EVENT HANDLERS - - // Attach the necessary event handlers when initializing the editor - function registerEventHandlers(cm) { - var d = cm.display; - on(d.scroller, "mousedown", operation(cm, onMouseDown)); - // Older IE's will not fire a second mousedown for a double click - if (ie && ie_version < 11) - on(d.scroller, "dblclick", operation(cm, function(e) { - if (signalDOMEvent(cm, e)) return; - var pos = posFromMouse(cm, e); - if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; - e_preventDefault(e); - var word = cm.findWordAt(pos); - extendSelection(cm.doc, word.anchor, word.head); - })); - else - on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); - // Some browsers fire contextmenu *after* opening the menu, at - // which point we can't mess with it anymore. Context menu is - // handled in onMouseDown for these browsers. - if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); - - // Used to suppress mouse event handling when a touch happens - var touchFinished, prevTouch = {end: 0}; - function finishTouch() { - if (d.activeTouch) { - touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000); - prevTouch = d.activeTouch; - prevTouch.end = +new Date; - } - }; - function isMouseLikeTouchEvent(e) { - if (e.touches.length != 1) return false; - var touch = e.touches[0]; - return touch.radiusX <= 1 && touch.radiusY <= 1; - } - function farAway(touch, other) { - if (other.left == null) return true; - var dx = other.left - touch.left, dy = other.top - touch.top; - return dx * dx + dy * dy > 20 * 20; - } - on(d.scroller, "touchstart", function(e) { - if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { - clearTimeout(touchFinished); - var now = +new Date; - d.activeTouch = {start: now, moved: false, - prev: now - prevTouch.end <= 300 ? prevTouch : null}; - if (e.touches.length == 1) { - d.activeTouch.left = e.touches[0].pageX; - d.activeTouch.top = e.touches[0].pageY; - } - } - }); - on(d.scroller, "touchmove", function() { - if (d.activeTouch) d.activeTouch.moved = true; - }); - on(d.scroller, "touchend", function(e) { - var touch = d.activeTouch; - if (touch && !eventInWidget(d, e) && touch.left != null && - !touch.moved && new Date - touch.start < 300) { - var pos = cm.coordsChar(d.activeTouch, "page"), range; - if (!touch.prev || farAway(touch, touch.prev)) // Single tap - range = new Range(pos, pos); - else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap - range = cm.findWordAt(pos); - else // Triple tap - range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); - cm.setSelection(range.anchor, range.head); - cm.focus(); - e_preventDefault(e); - } - finishTouch(); - }); - on(d.scroller, "touchcancel", finishTouch); - - // Sync scrolling between fake scrollbars and real scrollable - // area, ensure viewport is updated when scrolling. - on(d.scroller, "scroll", function() { - if (d.scroller.clientHeight) { - setScrollTop(cm, d.scroller.scrollTop); - setScrollLeft(cm, d.scroller.scrollLeft, true); - signal(cm, "scroll", cm); - } - }); - - // Listen to wheel events in order to try and update the viewport on time. - on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); - on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); - - // Prevent wrapper from ever scrolling - on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); - - d.dragFunctions = { - enter: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);}, - over: function(e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }}, - start: function(e){onDragStart(cm, e);}, - drop: operation(cm, onDrop), - leave: function(e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); }} - }; - - var inp = d.input.getField(); - on(inp, "keyup", function(e) { onKeyUp.call(cm, e); }); - on(inp, "keydown", operation(cm, onKeyDown)); - on(inp, "keypress", operation(cm, onKeyPress)); - on(inp, "focus", bind(onFocus, cm)); - on(inp, "blur", bind(onBlur, cm)); - } - - function dragDropChanged(cm, value, old) { - var wasOn = old && old != CodeMirror.Init; - if (!value != !wasOn) { - var funcs = cm.display.dragFunctions; - var toggle = value ? on : off; - toggle(cm.display.scroller, "dragstart", funcs.start); - toggle(cm.display.scroller, "dragenter", funcs.enter); - toggle(cm.display.scroller, "dragover", funcs.over); - toggle(cm.display.scroller, "dragleave", funcs.leave); - toggle(cm.display.scroller, "drop", funcs.drop); - } - } - - // Called when the window resizes - function onResize(cm) { - var d = cm.display; - if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) - return; - // Might be a text scaling operation, clear size caches. - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - d.scrollbarsClipped = false; - cm.setSize(); - } - - // MOUSE EVENTS - - // Return true when the given mouse event happened in a widget - function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || - (n.parentNode == display.sizer && n != display.mover)) - return true; - } - } - - // Given a mouse event, find the corresponding position. If liberal - // is false, it checks whether a gutter or scrollbar was clicked, - // and returns null if it was. forRect is used by rectangular - // selections, and tries to estimate a character position even for - // coordinates beyond the right of the text. - function posFromMouse(cm, e, liberal, forRect) { - var display = cm.display; - if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; - - var x, y, space = display.lineSpace.getBoundingClientRect(); - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX - space.left; y = e.clientY - space.top; } - catch (e) { return null; } - var coords = coordsChar(cm, x, y), line; - if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { - var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; - coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); - } - return coords; - } - - // A mouse down can be a single click, double click, triple click, - // start of selection drag, start of text drag, new cursor - // (ctrl-click), rectangle drag (alt-drag), or xwin - // middle-click-paste. Or it might be a click on something we should - // not interfere with, such as a scrollbar or widget. - function onMouseDown(e) { - var cm = this, display = cm.display; - if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return; - display.shift = e.shiftKey; - - if (eventInWidget(display, e)) { - if (!webkit) { - // Briefly turn off draggability, to allow widgets to do - // normal dragging things. - display.scroller.draggable = false; - setTimeout(function(){display.scroller.draggable = true;}, 100); - } - return; - } - if (clickInGutter(cm, e)) return; - var start = posFromMouse(cm, e); - window.focus(); - - switch (e_button(e)) { - case 1: - // #3261: make sure, that we're not starting a second selection - if (cm.state.selectingText) - cm.state.selectingText(e); - else if (start) - leftButtonDown(cm, e, start); - else if (e_target(e) == display.scroller) - e_preventDefault(e); - break; - case 2: - if (webkit) cm.state.lastMiddleDown = +new Date; - if (start) extendSelection(cm.doc, start); - setTimeout(function() {display.input.focus();}, 20); - e_preventDefault(e); - break; - case 3: - if (captureRightClick) onContextMenu(cm, e); - else delayBlurEvent(cm); - break; - } - } - - var lastClick, lastDoubleClick; - function leftButtonDown(cm, e, start) { - if (ie) setTimeout(bind(ensureFocus, cm), 0); - else cm.curOp.focus = activeElt(); - - var now = +new Date, type; - if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { - type = "triple"; - } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { - type = "double"; - lastDoubleClick = {time: now, pos: start}; - } else { - type = "single"; - lastClick = {time: now, pos: start}; - } - - var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; - if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && - type == "single" && (contained = sel.contains(start)) > -1 && - (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && - (cmp(contained.to(), start) > 0 || start.xRel < 0)) - leftButtonStartDrag(cm, e, start, modifier); - else - leftButtonSelect(cm, e, start, type, modifier); - } - - // Start a text drag. When it ends, see if any dragging actually - // happen, and treat as a click if it didn't. - function leftButtonStartDrag(cm, e, start, modifier) { - var display = cm.display, startTime = +new Date; - var dragEnd = operation(cm, function(e2) { - if (webkit) display.scroller.draggable = false; - cm.state.draggingText = false; - off(document, "mouseup", dragEnd); - off(display.scroller, "drop", dragEnd); - if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { - e_preventDefault(e2); - if (!modifier && +new Date - 200 < startTime) - extendSelection(cm.doc, start); - // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) - if (webkit || ie && ie_version == 9) - setTimeout(function() {document.body.focus(); display.input.focus();}, 20); - else - display.input.focus(); - } - }); - // Let the drag handler handle this. - if (webkit) display.scroller.draggable = true; - cm.state.draggingText = dragEnd; - // IE's approach to draggable - if (display.scroller.dragDrop) display.scroller.dragDrop(); - on(document, "mouseup", dragEnd); - on(display.scroller, "drop", dragEnd); - } - - // Normal selection, as opposed to text dragging. - function leftButtonSelect(cm, e, start, type, addNew) { - var display = cm.display, doc = cm.doc; - e_preventDefault(e); - - var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; - if (addNew && !e.shiftKey) { - ourIndex = doc.sel.contains(start); - if (ourIndex > -1) - ourRange = ranges[ourIndex]; - else - ourRange = new Range(start, start); - } else { - ourRange = doc.sel.primary(); - ourIndex = doc.sel.primIndex; - } - - if (chromeOS ? e.shiftKey && e.metaKey : e.altKey) { - type = "rect"; - if (!addNew) ourRange = new Range(start, start); - start = posFromMouse(cm, e, true, true); - ourIndex = -1; - } else if (type == "double") { - var word = cm.findWordAt(start); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, word.anchor, word.head); - else - ourRange = word; - } else if (type == "triple") { - var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, line.anchor, line.head); - else - ourRange = line; - } else { - ourRange = extendRange(doc, ourRange, start); - } - - if (!addNew) { - ourIndex = 0; - setSelection(doc, new Selection([ourRange], 0), sel_mouse); - startSel = doc.sel; - } else if (ourIndex == -1) { - ourIndex = ranges.length; - setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), - {scroll: false, origin: "*mouse"}); - } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { - setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), - {scroll: false, origin: "*mouse"}); - startSel = doc.sel; - } else { - replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); - } - - var lastPos = start; - function extendTo(pos) { - if (cmp(lastPos, pos) == 0) return; - lastPos = pos; - - if (type == "rect") { - var ranges = [], tabSize = cm.options.tabSize; - var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); - var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); - var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); - for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); - line <= end; line++) { - var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); - if (left == right) - ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); - else if (text.length > leftPos) - ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); - } - if (!ranges.length) ranges.push(new Range(start, start)); - setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), - {origin: "*mouse", scroll: false}); - cm.scrollIntoView(pos); - } else { - var oldRange = ourRange; - var anchor = oldRange.anchor, head = pos; - if (type != "single") { - if (type == "double") - var range = cm.findWordAt(pos); - else - var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); - if (cmp(range.anchor, anchor) > 0) { - head = range.head; - anchor = minPos(oldRange.from(), range.anchor); - } else { - head = range.anchor; - anchor = maxPos(oldRange.to(), range.head); - } - } - var ranges = startSel.ranges.slice(0); - ranges[ourIndex] = new Range(clipPos(doc, anchor), head); - setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); - } - } - - var editorSize = display.wrapper.getBoundingClientRect(); - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0; - - function extend(e) { - var curCount = ++counter; - var cur = posFromMouse(cm, e, true, type == "rect"); - if (!cur) return; - if (cmp(cur, lastPos) != 0) { - cm.curOp.focus = activeElt(); - extendTo(cur); - var visible = visibleLines(display, doc); - if (cur.line >= visible.to || cur.line < visible.from) - setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; - if (outside) setTimeout(operation(cm, function() { - if (counter != curCount) return; - display.scroller.scrollTop += outside; - extend(e); - }), 50); - } - } - - function done(e) { - cm.state.selectingText = false; - counter = Infinity; - e_preventDefault(e); - display.input.focus(); - off(document, "mousemove", move); - off(document, "mouseup", up); - doc.history.lastSelOrigin = null; - } - - var move = operation(cm, function(e) { - if (!e_button(e)) done(e); - else extend(e); - }); - var up = operation(cm, done); - cm.state.selectingText = up; - on(document, "mousemove", move); - on(document, "mouseup", up); - } - - // Determines whether an event happened in the gutter, and fires the - // handlers for the corresponding event. - function gutterEvent(cm, e, type, prevent) { - try { var mX = e.clientX, mY = e.clientY; } - catch(e) { return false; } - if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; - if (prevent) e_preventDefault(e); - - var display = cm.display; - var lineBox = display.lineDiv.getBoundingClientRect(); - - if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); - mY -= lineBox.top - display.viewOffset; - - for (var i = 0; i < cm.options.gutters.length; ++i) { - var g = display.gutters.childNodes[i]; - if (g && g.getBoundingClientRect().right >= mX) { - var line = lineAtHeight(cm.doc, mY); - var gutter = cm.options.gutters[i]; - signal(cm, type, cm, line, gutter, e); - return e_defaultPrevented(e); - } - } - } - - function clickInGutter(cm, e) { - return gutterEvent(cm, e, "gutterClick", true); - } - - // Kludge to work around strange IE behavior where it'll sometimes - // re-fire a series of drag-related events right after the drop (#1551) - var lastDrop = 0; - - function onDrop(e) { - var cm = this; - clearDragCursor(cm); - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) - return; - e_preventDefault(e); - if (ie) lastDrop = +new Date; - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; - if (!pos || cm.isReadOnly()) return; - // Might be a file drop, in which case we simply extract the text - // and insert it. - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0; - var loadFile = function(file, i) { - if (cm.options.allowDropFileTypes && - indexOf(cm.options.allowDropFileTypes, file.type) == -1) - return; - - var reader = new FileReader; - reader.onload = operation(cm, function() { - var content = reader.result; - if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = ""; - text[i] = content; - if (++read == n) { - pos = clipPos(cm.doc, pos); - var change = {from: pos, to: pos, - text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), - origin: "paste"}; - makeChange(cm.doc, change); - setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); - } - }); - reader.readAsText(file); - }; - for (var i = 0; i < n; ++i) loadFile(files[i], i); - } else { // Normal drop - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { - cm.state.draggingText(e); - // Ensure the editor is re-focused - setTimeout(function() {cm.display.input.focus();}, 20); - return; - } - try { - var text = e.dataTransfer.getData("Text"); - if (text) { - if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey)) - var selected = cm.listSelections(); - setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); - if (selected) for (var i = 0; i < selected.length; ++i) - replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); - cm.replaceSelection(text, "around", "paste"); - cm.display.input.focus(); - } - } - catch(e){} - } - } - - function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; - - e.dataTransfer.setData("Text", cm.getSelection()); - e.dataTransfer.effectAllowed = "copyMove" - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (presto) { - img.width = img.height = 1; - cm.display.wrapper.appendChild(img); - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop; - } - e.dataTransfer.setDragImage(img, 0, 0); - if (presto) img.parentNode.removeChild(img); - } - } - - function onDragOver(cm, e) { - var pos = posFromMouse(cm, e); - if (!pos) return; - var frag = document.createDocumentFragment(); - drawSelectionCursor(cm, pos, frag); - if (!cm.display.dragCursor) { - cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); - cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); - } - removeChildrenAndAdd(cm.display.dragCursor, frag); - } - - function clearDragCursor(cm) { - if (cm.display.dragCursor) { - cm.display.lineSpace.removeChild(cm.display.dragCursor); - cm.display.dragCursor = null; - } - } - - // SCROLL EVENTS - - // Sync the scrollable area and scrollbars, ensure the viewport - // covers the visible area. - function setScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) return; - cm.doc.scrollTop = val; - if (!gecko) updateDisplaySimple(cm, {top: val}); - if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; - cm.display.scrollbars.setScrollTop(val); - if (gecko) updateDisplaySimple(cm); - startWorker(cm, 100); - } - // Sync scroller and scrollbar, ensure the gutter elements are - // aligned. - function setScrollLeft(cm, val, isScroller) { - if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; - val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); - cm.doc.scrollLeft = val; - alignHorizontally(cm); - if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; - cm.display.scrollbars.setScrollLeft(val); - } - - // Since the delta values reported on mouse wheel events are - // unstandardized between browsers and even browser versions, and - // generally horribly unpredictable, this code starts by measuring - // the scroll effect that the first few mouse wheel events have, - // and, from that, detects the way it can convert deltas to pixel - // offsets afterwards. - // - // The reason we want to know the amount a wheel event will scroll - // is that it gives us a chance to update the display before the - // actual scrolling happens, reducing flickering. - - var wheelSamples = 0, wheelPixelsPerUnit = null; - // Fill in a browser-detected starting value on browsers where we - // know one. These don't have to be accurate -- the result of them - // being wrong would just be a slight flicker on the first wheel - // scroll (if it is large enough). - if (ie) wheelPixelsPerUnit = -.53; - else if (gecko) wheelPixelsPerUnit = 15; - else if (chrome) wheelPixelsPerUnit = -.7; - else if (safari) wheelPixelsPerUnit = -1/3; - - var wheelEventDelta = function(e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY; - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; - else if (dy == null) dy = e.wheelDelta; - return {x: dx, y: dy}; - }; - CodeMirror.wheelEventPixels = function(e) { - var delta = wheelEventDelta(e); - delta.x *= wheelPixelsPerUnit; - delta.y *= wheelPixelsPerUnit; - return delta; - }; - - function onScrollWheel(cm, e) { - var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; - - var display = cm.display, scroll = display.scroller; - // Quit if there's nothing to scroll here - var canScrollX = scroll.scrollWidth > scroll.clientWidth; - var canScrollY = scroll.scrollHeight > scroll.clientHeight; - if (!(dx && canScrollX || dy && canScrollY)) return; - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { - for (var i = 0; i < view.length; i++) { - if (view[i].node == cur) { - cm.display.currentWheelTarget = cur; - break outer; - } - } - } - } - - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { - if (dy && canScrollY) - setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); - setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); - // Only prevent default scrolling if vertical scrolling is - // actually possible. Otherwise, it causes vertical scroll - // jitter on OSX trackpads when deltaX is small and deltaY - // is large (issue #3579) - if (!dy || (dy && canScrollY)) - e_preventDefault(e); - display.wheelStartX = null; // Abort measurement, if in progress - return; - } - - // 'Project' the visible viewport to cover the area that is being - // scrolled into view (if we know enough to estimate it). - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit; - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; - if (pixels < 0) top = Math.max(0, top + pixels - 50); - else bot = Math.min(cm.doc.height, bot + pixels + 50); - updateDisplaySimple(cm, {top: top, bottom: bot}); - } - - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; - display.wheelDX = dx; display.wheelDY = dy; - setTimeout(function() { - if (display.wheelStartX == null) return; - var movedX = scroll.scrollLeft - display.wheelStartX; - var movedY = scroll.scrollTop - display.wheelStartY; - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX); - display.wheelStartX = display.wheelStartY = null; - if (!sample) return; - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); - ++wheelSamples; - }, 200); - } else { - display.wheelDX += dx; display.wheelDY += dy; - } - } - } - - // KEY EVENTS - - // Run a handler that was bound to a key. - function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound]; - if (!bound) return false; - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - cm.display.input.ensurePolled(); - var prevShift = cm.display.shift, done = false; - try { - if (cm.isReadOnly()) cm.state.suppressEdits = true; - if (dropShift) cm.display.shift = false; - done = bound(cm) != Pass; - } finally { - cm.display.shift = prevShift; - cm.state.suppressEdits = false; - } - return done; - } - - function lookupKeyForEditor(cm, name, handle) { - for (var i = 0; i < cm.state.keyMaps.length; i++) { - var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); - if (result) return result; - } - return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) - || lookupKey(name, cm.options.keyMap, handle, cm); - } - - var stopSeq = new Delayed; - function dispatchKey(cm, name, e, handle) { - var seq = cm.state.keySeq; - if (seq) { - if (isModifierKey(name)) return "handled"; - stopSeq.set(50, function() { - if (cm.state.keySeq == seq) { - cm.state.keySeq = null; - cm.display.input.reset(); - } - }); - name = seq + " " + name; - } - var result = lookupKeyForEditor(cm, name, handle); - - if (result == "multi") - cm.state.keySeq = name; - if (result == "handled") - signalLater(cm, "keyHandled", cm, name, e); - - if (result == "handled" || result == "multi") { - e_preventDefault(e); - restartBlink(cm); - } - - if (seq && !result && /\'$/.test(name)) { - e_preventDefault(e); - return true; - } - return !!result; - } - - // Handle a key from the keydown event. - function handleKeyBinding(cm, e) { - var name = keyName(e, true); - if (!name) return false; - - if (e.shiftKey && !cm.state.keySeq) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);}) - || dispatchKey(cm, name, e, function(b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) - return doHandleBinding(cm, b); - }); - } else { - return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); }); - } - } - - // Handle a key from the keypress event - function handleCharBinding(cm, e, ch) { - return dispatchKey(cm, "'" + ch + "'", e, - function(b) { return doHandleBinding(cm, b, true); }); - } - - var lastStoppedKey = null; - function onKeyDown(e) { - var cm = this; - cm.curOp.focus = activeElt(); - if (signalDOMEvent(cm, e)) return; - // IE does strange things with escape. - if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; - var code = e.keyCode; - cm.display.shift = code == 16 || e.shiftKey; - var handled = handleKeyBinding(cm, e); - if (presto) { - lastStoppedKey = handled ? code : null; - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) - cm.replaceSelection("", null, "cut"); - } - - // Turn mouse into crosshair when Alt is held on Mac. - if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) - showCrossHair(cm); - } - - function showCrossHair(cm) { - var lineDiv = cm.display.lineDiv; - addClass(lineDiv, "CodeMirror-crosshair"); - - function up(e) { - if (e.keyCode == 18 || !e.altKey) { - rmClass(lineDiv, "CodeMirror-crosshair"); - off(document, "keyup", up); - off(document, "mouseover", up); - } - } - on(document, "keyup", up); - on(document, "mouseover", up); - } - - function onKeyUp(e) { - if (e.keyCode == 16) this.doc.sel.shift = false; - signalDOMEvent(this, e); - } - - function onKeyPress(e) { - var cm = this; - if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; - var keyCode = e.keyCode, charCode = e.charCode; - if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} - if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; - var ch = String.fromCharCode(charCode == null ? keyCode : charCode); - if (handleCharBinding(cm, e, ch)) return; - cm.display.input.onKeyPress(e); - } - - // FOCUS/BLUR EVENTS - - function delayBlurEvent(cm) { - cm.state.delayingBlurEvent = true; - setTimeout(function() { - if (cm.state.delayingBlurEvent) { - cm.state.delayingBlurEvent = false; - onBlur(cm); - } - }, 100); - } - - function onFocus(cm) { - if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; - - if (cm.options.readOnly == "nocursor") return; - if (!cm.state.focused) { - signal(cm, "focus", cm); - cm.state.focused = true; - addClass(cm.display.wrapper, "CodeMirror-focused"); - // This test prevents this from firing when a context - // menu is closed (since the input reset would kill the - // select-all detection hack) - if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { - cm.display.input.reset(); - if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730 - } - cm.display.input.receivedFocus(); - } - restartBlink(cm); - } - function onBlur(cm) { - if (cm.state.delayingBlurEvent) return; - - if (cm.state.focused) { - signal(cm, "blur", cm); - cm.state.focused = false; - rmClass(cm.display.wrapper, "CodeMirror-focused"); - } - clearInterval(cm.display.blinker); - setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); - } - - // CONTEXT MENU HANDLING - - // To make the context menu work, we need to briefly unhide the - // textarea (making it as unobtrusive as possible) to let the - // right-click take effect on it. - function onContextMenu(cm, e) { - if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; - if (signalDOMEvent(cm, e, "contextmenu")) return; - cm.display.input.onContextMenu(e); - } - - function contextMenuInGutter(cm, e) { - if (!hasHandler(cm, "gutterContextMenu")) return false; - return gutterEvent(cm, e, "gutterContextMenu", false); - } - - // UPDATING - - // Compute the position of the end of a change (its 'to' property - // refers to the pre-change end). - var changeEnd = CodeMirror.changeEnd = function(change) { - if (!change.text) return change.to; - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); - }; - - // Adjust a position to refer to the post-change position of the - // same text, or the end of the change if the change covers it. - function adjustForChange(pos, change) { - if (cmp(pos, change.from) < 0) return pos; - if (cmp(pos, change.to) <= 0) return changeEnd(change); - - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; - if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; - return Pos(line, ch); - } - - function computeSelAfterChange(doc, change) { - var out = []; - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - out.push(new Range(adjustForChange(range.anchor, change), - adjustForChange(range.head, change))); - } - return normalizeSelection(out, doc.sel.primIndex); - } - - function offsetPos(pos, old, nw) { - if (pos.line == old.line) - return Pos(nw.line, pos.ch - old.ch + nw.ch); - else - return Pos(nw.line + (pos.line - old.line), pos.ch); - } - - // Used by replaceSelections to allow moving the selection to the - // start or around the replaced test. Hint may be "start" or "around". - function computeReplacedSel(doc, changes, hint) { - var out = []; - var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - var from = offsetPos(change.from, oldPrev, newPrev); - var to = offsetPos(changeEnd(change), oldPrev, newPrev); - oldPrev = change.to; - newPrev = to; - if (hint == "around") { - var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; - out[i] = new Range(inv ? to : from, inv ? from : to); - } else { - out[i] = new Range(from, from); - } - } - return new Selection(out, doc.sel.primIndex); - } - - // Allow "beforeChange" event handlers to influence a change - function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function() { this.canceled = true; } - }; - if (update) obj.update = function(from, to, text, origin) { - if (from) this.from = clipPos(doc, from); - if (to) this.to = clipPos(doc, to); - if (text) this.text = text; - if (origin !== undefined) this.origin = origin; - }; - signal(doc, "beforeChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); - - if (obj.canceled) return null; - return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; - } - - // Apply a change to a document, and add it to the document's - // history, and propagating it to all linked documents. - function makeChange(doc, change, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); - if (doc.cm.state.suppressEdits) return; - } - - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true); - if (!change) return; - } - - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); - if (split) { - for (var i = split.length - 1; i >= 0; --i) - makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); - } else { - makeChangeInner(doc, change); - } - } - - function makeChangeInner(doc, change) { - if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; - var selAfter = computeSelAfterChange(doc, change); - addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); - - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); - var rebased = []; - - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); - }); - } - - // Revert a change stored in a document's history. - function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits) return; - - var hist = doc.history, event, selAfter = doc.sel; - var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; - - // Verify that there is a useable event (so that ctrl-z won't - // needlessly clear selection events) - for (var i = 0; i < source.length; i++) { - event = source[i]; - if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) - break; - } - if (i == source.length) return; - hist.lastOrigin = hist.lastSelOrigin = null; - - for (;;) { - event = source.pop(); - if (event.ranges) { - pushSelectionToHistory(event, dest); - if (allowSelectionOnly && !event.equals(doc.sel)) { - setSelection(doc, event, {clearRedo: false}); - return; - } - selAfter = event; - } - else break; - } - - // Build up a reverse change object to add to the opposite history - // stack (redo when undoing, and vice versa). - var antiChanges = []; - pushSelectionToHistory(selAfter, dest); - dest.push({changes: antiChanges, generation: hist.generation}); - hist.generation = event.generation || ++hist.maxGeneration; - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); - - for (var i = event.changes.length - 1; i >= 0; --i) { - var change = event.changes[i]; - change.origin = type; - if (filter && !filterChange(doc, change, false)) { - source.length = 0; - return; - } - - antiChanges.push(historyChangeFromChange(doc, change)); - - var after = i ? computeSelAfterChange(doc, change) : lst(source); - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); - if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); - var rebased = []; - - // Propagate to the linked documents - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); - }); - } - } - - // Sub-views need their line numbers shifted when text is added - // above or below them in the parent document. - function shiftDoc(doc, distance) { - if (distance == 0) return; - doc.first += distance; - doc.sel = new Selection(map(doc.sel.ranges, function(range) { - return new Range(Pos(range.anchor.line + distance, range.anchor.ch), - Pos(range.head.line + distance, range.head.ch)); - }), doc.sel.primIndex); - if (doc.cm) { - regChange(doc.cm, doc.first, doc.first - distance, distance); - for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) - regLineChange(doc.cm, l, "gutter"); - } - } - - // More lower-level change function, handling only a single document - // (not linked ones). - function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) - return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); - - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); - return; - } - if (change.from.line > doc.lastLine()) return; - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line); - shiftDoc(doc, shift); - change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin}; - } - var last = doc.lastLine(); - if (change.to.line > last) { - change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin}; - } - - change.removed = getBetween(doc, change.from, change.to); - - if (!selAfter) selAfter = computeSelAfterChange(doc, change); - if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); - else updateDoc(doc, change, spans); - setSelectionNoUndo(doc, selAfter, sel_dontScroll); - } - - // Handle the interaction of a change to a document with the editor - // that this document is part of. - function makeChangeSingleDocInEditor(cm, change, spans) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to; - - var recomputeMaxLength = false, checkWidthStart = from.line; - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); - doc.iter(checkWidthStart, to.line + 1, function(line) { - if (line == display.maxLine) { - recomputeMaxLength = true; - return true; - } - }); - } - - if (doc.sel.contains(change.from, change.to) > -1) - signalCursorActivity(cm); - - updateDoc(doc, change, spans, estimateHeight(cm)); - - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function(line) { - var len = lineLength(line); - if (len > display.maxLineLength) { - display.maxLine = line; - display.maxLineLength = len; - display.maxLineChanged = true; - recomputeMaxLength = false; - } - }); - if (recomputeMaxLength) cm.curOp.updateMaxLine = true; - } - - // Adjust frontier, schedule worker - doc.frontier = Math.min(doc.frontier, from.line); - startWorker(cm, 400); - - var lendiff = change.text.length - (to.line - from.line) - 1; - // Remember that these lines changed, for updating the display - if (change.full) - regChange(cm); - else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) - regLineChange(cm, from.line, "text"); - else - regChange(cm, from.line, to.line + 1, lendiff); - - var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); - if (changeHandler || changesHandler) { - var obj = { - from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin - }; - if (changeHandler) signalLater(cm, "change", cm, obj); - if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); - } - cm.display.selForContextMenu = null; - } - - function replaceRange(doc, code, from, to, origin) { - if (!to) to = from; - if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } - if (typeof code == "string") code = doc.splitLines(code); - makeChange(doc, {from: from, to: to, text: code, origin: origin}); - } - - // SCROLLING THINGS INTO VIEW - - // If an editor sits on the top or bottom of the window, partially - // scrolled out of view, this ensures that the cursor is visible. - function maybeScrollWindow(cm, coords) { - if (signalDOMEvent(cm, "scrollCursorIntoView")) return; - - var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; - if (coords.top + box.top < 0) doScroll = true; - else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; - if (doScroll != null && !phantom) { - var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + - (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + - (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + - coords.left + "px; width: 2px;"); - cm.display.lineSpace.appendChild(scrollNode); - scrollNode.scrollIntoView(doScroll); - cm.display.lineSpace.removeChild(scrollNode); - } - } - - // Scroll a given position into view (immediately), verifying that - // it actually became visible (as line heights are accurately - // measured, the position of something may 'drift' during drawing). - function scrollPosIntoView(cm, pos, end, margin) { - if (margin == null) margin = 0; - for (var limit = 0; limit < 5; limit++) { - var changed = false, coords = cursorCoords(cm, pos); - var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); - var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), - Math.min(coords.top, endCoords.top) - margin, - Math.max(coords.left, endCoords.left), - Math.max(coords.bottom, endCoords.bottom) + margin); - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; - if (scrollPos.scrollTop != null) { - setScrollTop(cm, scrollPos.scrollTop); - if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft); - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; - } - if (!changed) break; - } - return coords; - } - - // Scroll a given set of coordinates into view (immediately). - function scrollIntoView(cm, x1, y1, x2, y2) { - var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); - if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); - if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); - } - - // Calculate a new scroll position needed to scroll the given - // rectangle into view. Returns an object with scrollTop and - // scrollLeft properties. When these are undefined, the - // vertical/horizontal position does not need to be adjusted. - function calculateScrollPos(cm, x1, y1, x2, y2) { - var display = cm.display, snapMargin = textHeight(cm.display); - if (y1 < 0) y1 = 0; - var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; - var screen = displayHeight(cm), result = {}; - if (y2 - y1 > screen) y2 = y1 + screen; - var docBottom = cm.doc.height + paddingVert(display); - var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; - if (y1 < screentop) { - result.scrollTop = atTop ? 0 : y1; - } else if (y2 > screentop + screen) { - var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); - if (newTop != screentop) result.scrollTop = newTop; - } - - var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; - var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); - var tooWide = x2 - x1 > screenw; - if (tooWide) x2 = x1 + screenw; - if (x1 < 10) - result.scrollLeft = 0; - else if (x1 < screenleft) - result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); - else if (x2 > screenw + screenleft - 3) - result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; - return result; - } - - // Store a relative adjustment to the scroll position in the current - // operation (to be applied when the operation finishes). - function addToScrollPos(cm, left, top) { - if (left != null || top != null) resolveScrollToPos(cm); - if (left != null) - cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; - if (top != null) - cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; - } - - // Make sure that at the end of the operation the current cursor is - // shown. - function ensureCursorVisible(cm) { - resolveScrollToPos(cm); - var cur = cm.getCursor(), from = cur, to = cur; - if (!cm.options.lineWrapping) { - from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; - to = Pos(cur.line, cur.ch + 1); - } - cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; - } - - // When an operation has its scrollToPos property set, and another - // scroll action is applied before the end of the operation, this - // 'simulates' scrolling that position into view in a cheap way, so - // that the effect of intermediate scroll commands is not ignored. - function resolveScrollToPos(cm) { - var range = cm.curOp.scrollToPos; - if (range) { - cm.curOp.scrollToPos = null; - var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); - var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), - Math.min(from.top, to.top) - range.margin, - Math.max(from.right, to.right), - Math.max(from.bottom, to.bottom) + range.margin); - cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - } - - // API UTILITIES - - // Indent the given line. The how parameter can be "smart", - // "add"/null, "subtract", or "prev". When aggressive is false - // (typically set to true for forced single-line indents), empty - // lines are not indented, and places where the mode returns Pass - // are left alone. - function indentLine(cm, n, how, aggressive) { - var doc = cm.doc, state; - if (how == null) how = "add"; - if (how == "smart") { - // Fall back to "prev" when the mode doesn't have an indentation - // method. - if (!doc.mode.indent) how = "prev"; - else state = getStateBefore(cm, n); - } - - var tabSize = cm.options.tabSize; - var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); - if (line.stateAfter) line.stateAfter = null; - var curSpaceString = line.text.match(/^\s*/)[0], indentation; - if (!aggressive && !/\S/.test(line.text)) { - indentation = 0; - how = "not"; - } else if (how == "smart") { - indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); - if (indentation == Pass || indentation > 150) { - if (!aggressive) return; - how = "prev"; - } - } - if (how == "prev") { - if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); - else indentation = 0; - } else if (how == "add") { - indentation = curSpace + cm.options.indentUnit; - } else if (how == "subtract") { - indentation = curSpace - cm.options.indentUnit; - } else if (typeof how == "number") { - indentation = curSpace + how; - } - indentation = Math.max(0, indentation); - - var indentString = "", pos = 0; - if (cm.options.indentWithTabs) - for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} - if (pos < indentation) indentString += spaceStr(indentation - pos); - - if (indentString != curSpaceString) { - replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); - line.stateAfter = null; - return true; - } else { - // Ensure that, if the cursor was in the whitespace at the start - // of the line, it is moved to the end of that space. - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - if (range.head.line == n && range.head.ch < curSpaceString.length) { - var pos = Pos(n, curSpaceString.length); - replaceOneSelection(doc, i, new Range(pos, pos)); - break; - } - } - } - } - - // Utility for applying a change to a line by handle or number, - // returning the number and optionally registering the line as - // changed. - function changeLine(doc, handle, changeType, op) { - var no = handle, line = handle; - if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); - else no = lineNo(handle); - if (no == null) return null; - if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); - return line; - } - - // Helper for deleting text near the selection(s), used to implement - // backspace, delete, and similar functionality. - function deleteNearSelection(cm, compute) { - var ranges = cm.doc.sel.ranges, kill = []; - // Build up a set of ranges to kill first, merging overlapping - // ranges. - for (var i = 0; i < ranges.length; i++) { - var toKill = compute(ranges[i]); - while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { - var replaced = kill.pop(); - if (cmp(replaced.from, toKill.from) < 0) { - toKill.from = replaced.from; - break; - } - } - kill.push(toKill); - } - // Next, remove those actual ranges. - runInOp(cm, function() { - for (var i = kill.length - 1; i >= 0; i--) - replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); - ensureCursorVisible(cm); - }); - } - - // Used for horizontal relative motion. Dir is -1 or 1 (left or - // right), unit can be "char", "column" (like char, but doesn't - // cross line boundaries), "word" (across next word), or "group" (to - // the start of next group of word or non-word-non-whitespace - // chars). The visually param controls whether, in right-to-left - // text, direction 1 means to move towards the next index in the - // string, or towards the character to the right of the current - // position. The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosH(doc, pos, dir, unit, visually) { - var line = pos.line, ch = pos.ch, origDir = dir; - var lineObj = getLine(doc, line); - function findNextLine() { - var l = line + dir; - if (l < doc.first || l >= doc.first + doc.size) return false - line = l; - return lineObj = getLine(doc, l); - } - function moveOnce(boundToLine) { - var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); - if (next == null) { - if (!boundToLine && findNextLine()) { - if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); - else ch = dir < 0 ? lineObj.text.length : 0; - } else return false - } else ch = next; - return true; - } - - if (unit == "char") { - moveOnce() - } else if (unit == "column") { - moveOnce(true) - } else if (unit == "word" || unit == "group") { - var sawType = null, group = unit == "group"; - var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); - for (var first = true;; first = false) { - if (dir < 0 && !moveOnce(!first)) break; - var cur = lineObj.text.charAt(ch) || "\n"; - var type = isWordChar(cur, helper) ? "w" - : group && cur == "\n" ? "n" - : !group || /\s/.test(cur) ? null - : "p"; - if (group && !first && !type) type = "s"; - if (sawType && sawType != type) { - if (dir < 0) {dir = 1; moveOnce();} - break; - } - - if (type) sawType = type; - if (dir > 0 && !moveOnce(!first)) break; - } - } - var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true); - if (!cmp(pos, result)) result.hitSide = true; - return result; - } - - // For relative vertical movement. Dir may be -1 or 1. Unit can be - // "page" or "line". The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosV(cm, pos, dir, unit) { - var doc = cm.doc, x = pos.left, y; - if (unit == "page") { - var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); - y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); - } else if (unit == "line") { - y = dir > 0 ? pos.bottom + 3 : pos.top - 3; - } - for (;;) { - var target = coordsChar(cm, x, y); - if (!target.outside) break; - if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } - y += dir * 5; - } - return target; - } - - // EDITOR METHODS - - // The publicly visible API. Note that methodOp(f) means - // 'wrap f in an operation, performed on its `this` parameter'. - - // This is not the complete set of editor methods. Most of the - // methods defined on the Doc type are also injected into - // CodeMirror.prototype, for backwards compatibility and - // convenience. - - CodeMirror.prototype = { - constructor: CodeMirror, - focus: function(){window.focus(); this.display.input.focus();}, - - setOption: function(option, value) { - var options = this.options, old = options[option]; - if (options[option] == value && option != "mode") return; - options[option] = value; - if (optionHandlers.hasOwnProperty(option)) - operation(this, optionHandlers[option])(this, value, old); - }, - - getOption: function(option) {return this.options[option];}, - getDoc: function() {return this.doc;}, - - addKeyMap: function(map, bottom) { - this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); - }, - removeKeyMap: function(map) { - var maps = this.state.keyMaps; - for (var i = 0; i < maps.length; ++i) - if (maps[i] == map || maps[i].name == map) { - maps.splice(i, 1); - return true; - } - }, - - addOverlay: methodOp(function(spec, options) { - var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); - if (mode.startState) throw new Error("Overlays may not be stateful."); - this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); - this.state.modeGen++; - regChange(this); - }), - removeOverlay: methodOp(function(spec) { - var overlays = this.state.overlays; - for (var i = 0; i < overlays.length; ++i) { - var cur = overlays[i].modeSpec; - if (cur == spec || typeof spec == "string" && cur.name == spec) { - overlays.splice(i, 1); - this.state.modeGen++; - regChange(this); - return; - } - } - }), - - indentLine: methodOp(function(n, dir, aggressive) { - if (typeof dir != "string" && typeof dir != "number") { - if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; - else dir = dir ? "add" : "subtract"; - } - if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); - }), - indentSelection: methodOp(function(how) { - var ranges = this.doc.sel.ranges, end = -1; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - if (!range.empty()) { - var from = range.from(), to = range.to(); - var start = Math.max(end, from.line); - end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; - for (var j = start; j < end; ++j) - indentLine(this, j, how); - var newRanges = this.doc.sel.ranges; - if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) - replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); - } else if (range.head.line > end) { - indentLine(this, range.head.line, how, true); - end = range.head.line; - if (i == this.doc.sel.primIndex) ensureCursorVisible(this); - } - } - }), - - // Fetch the parser token for a given character. Useful for hacks - // that want to inspect the mode state (say, for completion). - getTokenAt: function(pos, precise) { - return takeToken(this, pos, precise); - }, - - getLineTokens: function(line, precise) { - return takeToken(this, Pos(line), precise, true); - }, - - getTokenTypeAt: function(pos) { - pos = clipPos(this.doc, pos); - var styles = getLineStyles(this, getLine(this.doc, pos.line)); - var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; - var type; - if (ch == 0) type = styles[2]; - else for (;;) { - var mid = (before + after) >> 1; - if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; - else if (styles[mid * 2 + 1] < ch) before = mid + 1; - else { type = styles[mid * 2 + 2]; break; } - } - var cut = type ? type.indexOf("cm-overlay ") : -1; - return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); - }, - - getModeAt: function(pos) { - var mode = this.doc.mode; - if (!mode.innerMode) return mode; - return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; - }, - - getHelper: function(pos, type) { - return this.getHelpers(pos, type)[0]; - }, - - getHelpers: function(pos, type) { - var found = []; - if (!helpers.hasOwnProperty(type)) return found; - var help = helpers[type], mode = this.getModeAt(pos); - if (typeof mode[type] == "string") { - if (help[mode[type]]) found.push(help[mode[type]]); - } else if (mode[type]) { - for (var i = 0; i < mode[type].length; i++) { - var val = help[mode[type][i]]; - if (val) found.push(val); - } - } else if (mode.helperType && help[mode.helperType]) { - found.push(help[mode.helperType]); - } else if (help[mode.name]) { - found.push(help[mode.name]); - } - for (var i = 0; i < help._global.length; i++) { - var cur = help._global[i]; - if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) - found.push(cur.val); - } - return found; - }, - - getStateAfter: function(line, precise) { - var doc = this.doc; - line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); - return getStateBefore(this, line + 1, precise); - }, - - cursorCoords: function(start, mode) { - var pos, range = this.doc.sel.primary(); - if (start == null) pos = range.head; - else if (typeof start == "object") pos = clipPos(this.doc, start); - else pos = start ? range.from() : range.to(); - return cursorCoords(this, pos, mode || "page"); - }, - - charCoords: function(pos, mode) { - return charCoords(this, clipPos(this.doc, pos), mode || "page"); - }, - - coordsChar: function(coords, mode) { - coords = fromCoordSystem(this, coords, mode || "page"); - return coordsChar(this, coords.left, coords.top); - }, - - lineAtHeight: function(height, mode) { - height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; - return lineAtHeight(this.doc, height + this.display.viewOffset); - }, - heightAtLine: function(line, mode) { - var end = false, lineObj; - if (typeof line == "number") { - var last = this.doc.first + this.doc.size - 1; - if (line < this.doc.first) line = this.doc.first; - else if (line > last) { line = last; end = true; } - lineObj = getLine(this.doc, line); - } else { - lineObj = line; - } - return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + - (end ? this.doc.height - heightAtLine(lineObj) : 0); - }, - - defaultTextHeight: function() { return textHeight(this.display); }, - defaultCharWidth: function() { return charWidth(this.display); }, - - setGutterMarker: methodOp(function(line, gutterID, value) { - return changeLine(this.doc, line, "gutter", function(line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}); - markers[gutterID] = value; - if (!value && isEmpty(markers)) line.gutterMarkers = null; - return true; - }); - }), - - clearGutter: methodOp(function(gutterID) { - var cm = this, doc = cm.doc, i = doc.first; - doc.iter(function(line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - line.gutterMarkers[gutterID] = null; - regLineChange(cm, i, "gutter"); - if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; - } - ++i; - }); - }), - - lineInfo: function(line) { - if (typeof line == "number") { - if (!isLine(this.doc, line)) return null; - var n = line; - line = getLine(this.doc, line); - if (!line) return null; - } else { - var n = lineNo(line); - if (n == null) return null; - } - return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets}; - }, - - getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, - - addWidget: function(pos, node, scroll, vert, horiz) { - var display = this.display; - pos = cursorCoords(this, clipPos(this.doc, pos)); - var top = pos.bottom, left = pos.left; - node.style.position = "absolute"; - node.setAttribute("cm-ignore-events", "true"); - this.display.input.setUneditable(node); - display.sizer.appendChild(node); - if (vert == "over") { - top = pos.top; - } else if (vert == "above" || vert == "near") { - var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), - hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); - // Default to positioning above (if specified and possible); otherwise default to positioning below - if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) - top = pos.top - node.offsetHeight; - else if (pos.bottom + node.offsetHeight <= vspace) - top = pos.bottom; - if (left + node.offsetWidth > hspace) - left = hspace - node.offsetWidth; - } - node.style.top = top + "px"; - node.style.left = node.style.right = ""; - if (horiz == "right") { - left = display.sizer.clientWidth - node.offsetWidth; - node.style.right = "0px"; - } else { - if (horiz == "left") left = 0; - else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; - node.style.left = left + "px"; - } - if (scroll) - scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); - }, - - triggerOnKeyDown: methodOp(onKeyDown), - triggerOnKeyPress: methodOp(onKeyPress), - triggerOnKeyUp: onKeyUp, - - execCommand: function(cmd) { - if (commands.hasOwnProperty(cmd)) - return commands[cmd].call(null, this); - }, - - triggerElectric: methodOp(function(text) { triggerElectric(this, text); }), - - findPosH: function(from, amount, unit, visually) { - var dir = 1; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - cur = findPosH(this.doc, cur, dir, unit, visually); - if (cur.hitSide) break; - } - return cur; - }, - - moveH: methodOp(function(dir, unit) { - var cm = this; - cm.extendSelectionsBy(function(range) { - if (cm.display.shift || cm.doc.extend || range.empty()) - return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); - else - return dir < 0 ? range.from() : range.to(); - }, sel_move); - }), - - deleteH: methodOp(function(dir, unit) { - var sel = this.doc.sel, doc = this.doc; - if (sel.somethingSelected()) - doc.replaceSelection("", null, "+delete"); - else - deleteNearSelection(this, function(range) { - var other = findPosH(doc, range.head, dir, unit, false); - return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; - }); - }), - - findPosV: function(from, amount, unit, goalColumn) { - var dir = 1, x = goalColumn; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - var coords = cursorCoords(this, cur, "div"); - if (x == null) x = coords.left; - else coords.left = x; - cur = findPosV(this, coords, dir, unit); - if (cur.hitSide) break; - } - return cur; - }, - - moveV: methodOp(function(dir, unit) { - var cm = this, doc = this.doc, goals = []; - var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); - doc.extendSelectionsBy(function(range) { - if (collapse) - return dir < 0 ? range.from() : range.to(); - var headPos = cursorCoords(cm, range.head, "div"); - if (range.goalColumn != null) headPos.left = range.goalColumn; - goals.push(headPos.left); - var pos = findPosV(cm, headPos, dir, unit); - if (unit == "page" && range == doc.sel.primary()) - addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); - return pos; - }, sel_move); - if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) - doc.sel.ranges[i].goalColumn = goals[i]; - }), - - // Find the word at the given position (as returned by coordsChar). - findWordAt: function(pos) { - var doc = this.doc, line = getLine(doc, pos.line).text; - var start = pos.ch, end = pos.ch; - if (line) { - var helper = this.getHelper(pos, "wordChars"); - if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; - var startChar = line.charAt(start); - var check = isWordChar(startChar, helper) - ? function(ch) { return isWordChar(ch, helper); } - : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} - : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; - while (start > 0 && check(line.charAt(start - 1))) --start; - while (end < line.length && check(line.charAt(end))) ++end; - } - return new Range(Pos(pos.line, start), Pos(pos.line, end)); - }, - - toggleOverwrite: function(value) { - if (value != null && value == this.state.overwrite) return; - if (this.state.overwrite = !this.state.overwrite) - addClass(this.display.cursorDiv, "CodeMirror-overwrite"); - else - rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); - - signal(this, "overwriteToggle", this, this.state.overwrite); - }, - hasFocus: function() { return this.display.input.getField() == activeElt(); }, - isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit); }, - - scrollTo: methodOp(function(x, y) { - if (x != null || y != null) resolveScrollToPos(this); - if (x != null) this.curOp.scrollLeft = x; - if (y != null) this.curOp.scrollTop = y; - }), - getScrollInfo: function() { - var scroller = this.display.scroller; - return {left: scroller.scrollLeft, top: scroller.scrollTop, - height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, - width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, - clientHeight: displayHeight(this), clientWidth: displayWidth(this)}; - }, - - scrollIntoView: methodOp(function(range, margin) { - if (range == null) { - range = {from: this.doc.sel.primary().head, to: null}; - if (margin == null) margin = this.options.cursorScrollMargin; - } else if (typeof range == "number") { - range = {from: Pos(range, 0), to: null}; - } else if (range.from == null) { - range = {from: range, to: null}; - } - if (!range.to) range.to = range.from; - range.margin = margin || 0; - - if (range.from.line != null) { - resolveScrollToPos(this); - this.curOp.scrollToPos = range; - } else { - var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), - Math.min(range.from.top, range.to.top) - range.margin, - Math.max(range.from.right, range.to.right), - Math.max(range.from.bottom, range.to.bottom) + range.margin); - this.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - }), - - setSize: methodOp(function(width, height) { - var cm = this; - function interpret(val) { - return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; - } - if (width != null) cm.display.wrapper.style.width = interpret(width); - if (height != null) cm.display.wrapper.style.height = interpret(height); - if (cm.options.lineWrapping) clearLineMeasurementCache(this); - var lineNo = cm.display.viewFrom; - cm.doc.iter(lineNo, cm.display.viewTo, function(line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) - if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } - ++lineNo; - }); - cm.curOp.forceUpdate = true; - signal(cm, "refresh", this); - }), - - operation: function(f){return runInOp(this, f);}, - - refresh: methodOp(function() { - var oldHeight = this.display.cachedTextHeight; - regChange(this); - this.curOp.forceUpdate = true; - clearCaches(this); - this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); - updateGutterSpace(this); - if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) - estimateLineHeights(this); - signal(this, "refresh", this); - }), - - swapDoc: methodOp(function(doc) { - var old = this.doc; - old.cm = null; - attachDoc(this, doc); - clearCaches(this); - this.display.input.reset(); - this.scrollTo(doc.scrollLeft, doc.scrollTop); - this.curOp.forceScroll = true; - signalLater(this, "swapDoc", this, old); - return old; - }), - - getInputField: function(){return this.display.input.getField();}, - getWrapperElement: function(){return this.display.wrapper;}, - getScrollerElement: function(){return this.display.scroller;}, - getGutterElement: function(){return this.display.gutters;} - }; - eventMixin(CodeMirror); - - // OPTION DEFAULTS - - // The default configuration options. - var defaults = CodeMirror.defaults = {}; - // Functions to run when options are changed. - var optionHandlers = CodeMirror.optionHandlers = {}; - - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt; - if (handle) optionHandlers[name] = - notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; - } - - // Passed to option handlers when there is no old value. - var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function(cm, val) { - cm.setValue(val); - }, true); - option("mode", null, function(cm, val) { - cm.doc.modeOption = val; - loadMode(cm); - }, true); - - option("indentUnit", 2, loadMode, true); - option("indentWithTabs", false); - option("smartIndent", true); - option("tabSize", 4, function(cm) { - resetModeState(cm); - clearCaches(cm); - regChange(cm); - }, true); - option("lineSeparator", null, function(cm, val) { - cm.doc.lineSep = val; - if (!val) return; - var newBreaks = [], lineNo = cm.doc.first; - cm.doc.iter(function(line) { - for (var pos = 0;;) { - var found = line.text.indexOf(val, pos); - if (found == -1) break; - pos = found + val.length; - newBreaks.push(Pos(lineNo, found)); - } - lineNo++; - }); - for (var i = newBreaks.length - 1; i >= 0; i--) - replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) - }); - option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) { - cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); - if (old != CodeMirror.Init) cm.refresh(); - }); - option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); - option("electricChars", true); - option("inputStyle", mobile ? "contenteditable" : "textarea", function() { - throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME - }, true); - option("rtlMoveVisually", !windows); - option("wholeLineUpdateBefore", true); - - option("theme", "default", function(cm) { - themeChanged(cm); - guttersChanged(cm); - }, true); - option("keyMap", "default", function(cm, val, old) { - var next = getKeyMap(val); - var prev = old != CodeMirror.Init && getKeyMap(old); - if (prev && prev.detach) prev.detach(cm, next); - if (next.attach) next.attach(cm, prev || null); - }); - option("extraKeys", null); - - option("lineWrapping", false, wrappingChanged, true); - option("gutters", [], function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("fixedGutter", true, function(cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; - cm.refresh(); - }, true); - option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true); - option("scrollbarStyle", "native", function(cm) { - initScrollbars(cm); - updateScrollbars(cm); - cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); - cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); - }, true); - option("lineNumbers", false, function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("firstLineNumber", 1, guttersChanged, true); - option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); - option("showCursorWhenSelecting", false, updateSelection, true); - - option("resetSelectionOnContextMenu", true); - option("lineWiseCopyCut", true); - - option("readOnly", false, function(cm, val) { - if (val == "nocursor") { - onBlur(cm); - cm.display.input.blur(); - cm.display.disabled = true; - } else { - cm.display.disabled = false; - } - cm.display.input.readOnlyChanged(val) - }); - option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true); - option("dragDrop", true, dragDropChanged); - option("allowDropFileTypes", null); - - option("cursorBlinkRate", 530); - option("cursorScrollMargin", 0); - option("cursorHeight", 1, updateSelection, true); - option("singleCursorHeightPerLine", true, updateSelection, true); - option("workTime", 100); - option("workDelay", 100); - option("flattenSpans", true, resetModeState, true); - option("addModeClass", false, resetModeState, true); - option("pollInterval", 100); - option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); - option("historyEventDelay", 1250); - option("viewportMargin", 10, function(cm){cm.refresh();}, true); - option("maxHighlightLength", 10000, resetModeState, true); - option("moveInputWithCursor", true, function(cm, val) { - if (!val) cm.display.input.resetPosition(); - }); - - option("tabindex", null, function(cm, val) { - cm.display.input.getField().tabIndex = val || ""; - }); - option("autofocus", null); - - // MODE DEFINITION AND QUERYING - - // Known modes, by name and by MIME - var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; - - // Extra arguments are stored as the mode's dependencies, which is - // used by (legacy) mechanisms like loadmode.js to automatically - // load a mode. (Preferred mechanism is the require/define calls.) - CodeMirror.defineMode = function(name, mode) { - if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; - if (arguments.length > 2) - mode.dependencies = Array.prototype.slice.call(arguments, 2); - modes[name] = mode; - }; - - CodeMirror.defineMIME = function(mime, spec) { - mimeModes[mime] = spec; - }; - - // Given a MIME type, a {name, ...options} config object, or a name - // string, return a mode config object. - CodeMirror.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name]; - if (typeof found == "string") found = {name: found}; - spec = createObj(found, spec); - spec.name = found.name; - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return CodeMirror.resolveMode("application/xml"); - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; - }; - - // Given a mode spec (anything that resolveMode accepts), find and - // initialize an actual mode object. - CodeMirror.getMode = function(options, spec) { - var spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) return CodeMirror.getMode(options, "text/plain"); - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) continue; - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - if (spec.helperType) modeObj.helperType = spec.helperType; - if (spec.modeProps) for (var prop in spec.modeProps) - modeObj[prop] = spec.modeProps[prop]; - - return modeObj; - }; - - // Minimal default mode. - CodeMirror.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; - }); - CodeMirror.defineMIME("text/plain", "null"); - - // This can be used to attach properties to mode objects from - // outside the actual mode definition. - var modeExtensions = CodeMirror.modeExtensions = {}; - CodeMirror.extendMode = function(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); - }; - - // EXTENSIONS - - CodeMirror.defineExtension = function(name, func) { - CodeMirror.prototype[name] = func; - }; - CodeMirror.defineDocExtension = function(name, func) { - Doc.prototype[name] = func; - }; - CodeMirror.defineOption = option; - - var initHooks = []; - CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; - - var helpers = CodeMirror.helpers = {}; - CodeMirror.registerHelper = function(type, name, value) { - if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; - helpers[type][name] = value; - }; - CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { - CodeMirror.registerHelper(type, name, value); - helpers[type]._global.push({pred: predicate, val: value}); - }; - - // MODE STATE HANDLING - - // Utility functions for working with state. Exported because nested - // modes need to do this for their inner modes. - - var copyState = CodeMirror.copyState = function(mode, state) { - if (state === true) return state; - if (mode.copyState) return mode.copyState(state); - var nstate = {}; - for (var n in state) { - var val = state[n]; - if (val instanceof Array) val = val.concat([]); - nstate[n] = val; - } - return nstate; - }; - - var startState = CodeMirror.startState = function(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; - }; - - // Given a mode and a state (for that mode), find the inner mode and - // state at the position that the state refers to. - CodeMirror.innerMode = function(mode, state) { - while (mode.innerMode) { - var info = mode.innerMode(state); - if (!info || info.mode == mode) break; - state = info.state; - mode = info.mode; - } - return info || {mode: mode, state: state}; - }; - - // STANDARD COMMANDS - - // Commands are parameter-less actions that can be performed on an - // editor, mostly used for keybindings. - var commands = CodeMirror.commands = { - selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, - singleSelection: function(cm) { - cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); - }, - killLine: function(cm) { - deleteNearSelection(cm, function(range) { - if (range.empty()) { - var len = getLine(cm.doc, range.head.line).text.length; - if (range.head.ch == len && range.head.line < cm.lastLine()) - return {from: range.head, to: Pos(range.head.line + 1, 0)}; - else - return {from: range.head, to: Pos(range.head.line, len)}; - } else { - return {from: range.from(), to: range.to()}; - } - }); - }, - deleteLine: function(cm) { - deleteNearSelection(cm, function(range) { - return {from: Pos(range.from().line, 0), - to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; - }); - }, - delLineLeft: function(cm) { - deleteNearSelection(cm, function(range) { - return {from: Pos(range.from().line, 0), to: range.from()}; - }); - }, - delWrappedLineLeft: function(cm) { - deleteNearSelection(cm, function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - var leftPos = cm.coordsChar({left: 0, top: top}, "div"); - return {from: leftPos, to: range.from()}; - }); - }, - delWrappedLineRight: function(cm) { - deleteNearSelection(cm, function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); - return {from: range.from(), to: rightPos }; - }); - }, - undo: function(cm) {cm.undo();}, - redo: function(cm) {cm.redo();}, - undoSelection: function(cm) {cm.undoSelection();}, - redoSelection: function(cm) {cm.redoSelection();}, - goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, - goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, - goLineStart: function(cm) { - cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, - {origin: "+move", bias: 1}); - }, - goLineStartSmart: function(cm) { - cm.extendSelectionsBy(function(range) { - return lineStartSmart(cm, range.head); - }, {origin: "+move", bias: 1}); - }, - goLineEnd: function(cm) { - cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, - {origin: "+move", bias: -1}); - }, - goLineRight: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); - }, sel_move); - }, - goLineLeft: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({left: 0, top: top}, "div"); - }, sel_move); - }, - goLineLeftSmart: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - var pos = cm.coordsChar({left: 0, top: top}, "div"); - if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); - return pos; - }, sel_move); - }, - goLineUp: function(cm) {cm.moveV(-1, "line");}, - goLineDown: function(cm) {cm.moveV(1, "line");}, - goPageUp: function(cm) {cm.moveV(-1, "page");}, - goPageDown: function(cm) {cm.moveV(1, "page");}, - goCharLeft: function(cm) {cm.moveH(-1, "char");}, - goCharRight: function(cm) {cm.moveH(1, "char");}, - goColumnLeft: function(cm) {cm.moveH(-1, "column");}, - goColumnRight: function(cm) {cm.moveH(1, "column");}, - goWordLeft: function(cm) {cm.moveH(-1, "word");}, - goGroupRight: function(cm) {cm.moveH(1, "group");}, - goGroupLeft: function(cm) {cm.moveH(-1, "group");}, - goWordRight: function(cm) {cm.moveH(1, "word");}, - delCharBefore: function(cm) {cm.deleteH(-1, "char");}, - delCharAfter: function(cm) {cm.deleteH(1, "char");}, - delWordBefore: function(cm) {cm.deleteH(-1, "word");}, - delWordAfter: function(cm) {cm.deleteH(1, "word");}, - delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, - delGroupAfter: function(cm) {cm.deleteH(1, "group");}, - indentAuto: function(cm) {cm.indentSelection("smart");}, - indentMore: function(cm) {cm.indentSelection("add");}, - indentLess: function(cm) {cm.indentSelection("subtract");}, - insertTab: function(cm) {cm.replaceSelection("\t");}, - insertSoftTab: function(cm) { - var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].from(); - var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); - spaces.push(new Array(tabSize - col % tabSize + 1).join(" ")); - } - cm.replaceSelections(spaces); - }, - defaultTab: function(cm) { - if (cm.somethingSelected()) cm.indentSelection("add"); - else cm.execCommand("insertTab"); - }, - transposeChars: function(cm) { - runInOp(cm, function() { - var ranges = cm.listSelections(), newSel = []; - for (var i = 0; i < ranges.length; i++) { - var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; - if (line) { - if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); - if (cur.ch > 0) { - cur = new Pos(cur.line, cur.ch + 1); - cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), - Pos(cur.line, cur.ch - 2), cur, "+transpose"); - } else if (cur.line > cm.doc.first) { - var prev = getLine(cm.doc, cur.line - 1).text; - if (prev) - cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + - prev.charAt(prev.length - 1), - Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); - } - } - newSel.push(new Range(cur, cur)); - } - cm.setSelections(newSel); - }); - }, - newlineAndIndent: function(cm) { - runInOp(cm, function() { - var len = cm.listSelections().length; - for (var i = 0; i < len; i++) { - var range = cm.listSelections()[i]; - cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input"); - cm.indentLine(range.from().line + 1, null, true); - } - ensureCursorVisible(cm); - }); - }, - toggleOverwrite: function(cm) {cm.toggleOverwrite();} - }; - - - // STANDARD KEYMAPS - - var keyMap = CodeMirror.keyMap = {}; - - keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", - "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", - "Esc": "singleSelection" - }; - // Note that the save and find-related commands aren't defined by - // default. User code or addons can define them. Unknown commands - // are simply ignored. - keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" - }; - // Very basic readline/emacs-style bindings, which are standard on Mac. - keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" - }; - keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", - "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", - fallthrough: ["basic", "emacsy"] - }; - keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; - - // KEYMAP DISPATCH - - function normalizeKeyName(name) { - var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; - var alt, ctrl, shift, cmd; - for (var i = 0; i < parts.length - 1; i++) { - var mod = parts[i]; - if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; - else if (/^a(lt)?$/i.test(mod)) alt = true; - else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; - else if (/^s(hift)$/i.test(mod)) shift = true; - else throw new Error("Unrecognized modifier name: " + mod); - } - if (alt) name = "Alt-" + name; - if (ctrl) name = "Ctrl-" + name; - if (cmd) name = "Cmd-" + name; - if (shift) name = "Shift-" + name; - return name; - } - - // This is a kludge to keep keymaps mostly working as raw objects - // (backwards compatibility) while at the same time support features - // like normalization and multi-stroke key bindings. It compiles a - // new normalized keymap, and then updates the old object to reflect - // this. - CodeMirror.normalizeKeyMap = function(keymap) { - var copy = {}; - for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { - var value = keymap[keyname]; - if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; - if (value == "...") { delete keymap[keyname]; continue; } - - var keys = map(keyname.split(" "), normalizeKeyName); - for (var i = 0; i < keys.length; i++) { - var val, name; - if (i == keys.length - 1) { - name = keys.join(" "); - val = value; - } else { - name = keys.slice(0, i + 1).join(" "); - val = "..."; - } - var prev = copy[name]; - if (!prev) copy[name] = val; - else if (prev != val) throw new Error("Inconsistent bindings for " + name); - } - delete keymap[keyname]; - } - for (var prop in copy) keymap[prop] = copy[prop]; - return keymap; - }; - - var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) { - map = getKeyMap(map); - var found = map.call ? map.call(key, context) : map[key]; - if (found === false) return "nothing"; - if (found === "...") return "multi"; - if (found != null && handle(found)) return "handled"; - - if (map.fallthrough) { - if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") - return lookupKey(key, map.fallthrough, handle, context); - for (var i = 0; i < map.fallthrough.length; i++) { - var result = lookupKey(key, map.fallthrough[i], handle, context); - if (result) return result; - } - } - }; - - // Modifier key presses don't count as 'real' key presses for the - // purpose of keymap fallthrough. - var isModifierKey = CodeMirror.isModifierKey = function(value) { - var name = typeof value == "string" ? value : keyNames[value.keyCode]; - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; - }; - - // Look up the name of a key as indicated by an event object. - var keyName = CodeMirror.keyName = function(event, noShift) { - if (presto && event.keyCode == 34 && event["char"]) return false; - var base = keyNames[event.keyCode], name = base; - if (name == null || event.altGraphKey) return false; - if (event.altKey && base != "Alt") name = "Alt-" + name; - if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; - if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; - if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; - return name; - }; - - function getKeyMap(val) { - return typeof val == "string" ? keyMap[val] : val; - } - - // FROMTEXTAREA - - CodeMirror.fromTextArea = function(textarea, options) { - options = options ? copyObj(options) : {}; - options.value = textarea.value; - if (!options.tabindex && textarea.tabIndex) - options.tabindex = textarea.tabIndex; - if (!options.placeholder && textarea.placeholder) - options.placeholder = textarea.placeholder; - // Set autofocus to true if this textarea is focused, or if it has - // autofocus and no other element is focused. - if (options.autofocus == null) { - var hasFocus = activeElt(); - options.autofocus = hasFocus == textarea || - textarea.getAttribute("autofocus") != null && hasFocus == document.body; - } - - function save() {textarea.value = cm.getValue();} - if (textarea.form) { - on(textarea.form, "submit", save); - // Deplorable hack to make the submit method do the right thing. - if (!options.leaveSubmitMethodAlone) { - var form = textarea.form, realSubmit = form.submit; - try { - var wrappedSubmit = form.submit = function() { - save(); - form.submit = realSubmit; - form.submit(); - form.submit = wrappedSubmit; - }; - } catch(e) {} - } - } - - options.finishInit = function(cm) { - cm.save = save; - cm.getTextArea = function() { return textarea; }; - cm.toTextArea = function() { - cm.toTextArea = isNaN; // Prevent this from being ran twice - save(); - textarea.parentNode.removeChild(cm.getWrapperElement()); - textarea.style.display = ""; - if (textarea.form) { - off(textarea.form, "submit", save); - if (typeof textarea.form.submit == "function") - textarea.form.submit = realSubmit; - } - }; - }; - - textarea.style.display = "none"; - var cm = CodeMirror(function(node) { - textarea.parentNode.insertBefore(node, textarea.nextSibling); - }, options); - return cm; - }; - - // STRING STREAM - - // Fed to the mode parsers, provides helper functions to make - // parsers more succinct. - - var StringStream = CodeMirror.StringStream = function(string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; - }; - - StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == this.lineStart;}, - peek: function() {return this.string.charAt(this.pos) || undefined;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - indentation: function() { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } - }; - - // TEXTMARKERS - - // Created with markText and setBookmark methods. A TextMarker is a - // handle that can be used to clear or find a marked position in the - // document. Line objects hold arrays (markedSpans) containing - // {from, to, marker} object pointing to such marker objects, and - // indicating that such a marker is present on that line. Multiple - // lines may point to the same marker when it spans across lines. - // The spans will have null for their from/to properties when the - // marker continues beyond the start/end of the line. Markers have - // links back to the lines they currently touch. - - var nextMarkerId = 0; - - var TextMarker = CodeMirror.TextMarker = function(doc, type) { - this.lines = []; - this.type = type; - this.doc = doc; - this.id = ++nextMarkerId; - }; - eventMixin(TextMarker); - - // Clear the marker. - TextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - var cm = this.doc.cm, withOp = cm && !cm.curOp; - if (withOp) startOperation(cm); - if (hasHandler(this, "clear")) { - var found = this.find(); - if (found) signalLater(this, "clear", found.from, found.to); - } - var min = null, max = null; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); - else if (cm) { - if (span.to != null) max = lineNo(line); - if (span.from != null) min = lineNo(line); - } - line.markedSpans = removeMarkedSpan(line.markedSpans, span); - if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) - updateLineHeight(line, textHeight(cm.display)); - } - if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { - var visual = visualLine(this.lines[i]), len = lineLength(visual); - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual; - cm.display.maxLineLength = len; - cm.display.maxLineChanged = true; - } - } - - if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); - this.lines.length = 0; - this.explicitlyCleared = true; - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false; - if (cm) reCheckSelection(cm.doc); - } - if (cm) signalLater(cm, "markerCleared", cm, this); - if (withOp) endOperation(cm); - if (this.parent) this.parent.clear(); - }; - - // Find the position of the marker in the document. Returns a {from, - // to} object by default. Side can be passed to get a specific side - // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the - // Pos objects returned contain a line object, rather than a line - // number (used to prevent looking up the same line twice). - TextMarker.prototype.find = function(side, lineObj) { - if (side == null && this.type == "bookmark") side = 1; - var from, to; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.from != null) { - from = Pos(lineObj ? line : lineNo(line), span.from); - if (side == -1) return from; - } - if (span.to != null) { - to = Pos(lineObj ? line : lineNo(line), span.to); - if (side == 1) return to; - } - } - return from && {from: from, to: to}; - }; - - // Signals that the marker's widget changed, and surrounding layout - // should be recomputed. - TextMarker.prototype.changed = function() { - var pos = this.find(-1, true), widget = this, cm = this.doc.cm; - if (!pos || !cm) return; - runInOp(cm, function() { - var line = pos.line, lineN = lineNo(pos.line); - var view = findViewForLine(cm, lineN); - if (view) { - clearLineMeasurementCacheFor(view); - cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; - } - cm.curOp.updateMaxLine = true; - if (!lineIsHidden(widget.doc, line) && widget.height != null) { - var oldHeight = widget.height; - widget.height = null; - var dHeight = widgetHeight(widget) - oldHeight; - if (dHeight) - updateLineHeight(line, line.height + dHeight); - } - }); - }; - - TextMarker.prototype.attachLine = function(line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) - (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); - } - this.lines.push(line); - }; - TextMarker.prototype.detachLine = function(line) { - this.lines.splice(indexOf(this.lines, line), 1); - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); - } - }; - - // Collapsed markers have unique ids, in order to be able to order - // them, which is needed for uniquely determining an outer marker - // when they overlap (they may nest, but not partially overlap). - var nextMarkerId = 0; - - // Create a marker, wire it up to the right lines, and - function markText(doc, from, to, options, type) { - // Shared markers (across linked documents) are handled separately - // (markTextShared will call out to this again, once per - // document). - if (options && options.shared) return markTextShared(doc, from, to, options, type); - // Ensure we are in an operation. - if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); - - var marker = new TextMarker(doc, type), diff = cmp(from, to); - if (options) copyObj(options, marker, false); - // Don't connect empty markers unless clearWhenEmpty is false - if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) - return marker; - if (marker.replacedWith) { - // Showing up as a widget implies collapsed (widget replaces text) - marker.collapsed = true; - marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); - if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); - if (options.insertLeft) marker.widgetNode.insertLeft = true; - } - if (marker.collapsed) { - if (conflictingCollapsedRange(doc, from.line, from, to, marker) || - from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) - throw new Error("Inserting collapsed marker partially overlapping an existing one"); - sawCollapsedSpans = true; - } - - if (marker.addToHistory) - addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); - - var curLine = from.line, cm = doc.cm, updateMaxLine; - doc.iter(curLine, to.line + 1, function(line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) - updateMaxLine = true; - if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); - addMarkedSpan(line, new MarkedSpan(marker, - curLine == from.line ? from.ch : null, - curLine == to.line ? to.ch : null)); - ++curLine; - }); - // lineIsHidden depends on the presence of the spans, so needs a second pass - if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { - if (lineIsHidden(doc, line)) updateLineHeight(line, 0); - }); - - if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); - - if (marker.readOnly) { - sawReadOnlySpans = true; - if (doc.history.done.length || doc.history.undone.length) - doc.clearHistory(); - } - if (marker.collapsed) { - marker.id = ++nextMarkerId; - marker.atomic = true; - } - if (cm) { - // Sync editor state - if (updateMaxLine) cm.curOp.updateMaxLine = true; - if (marker.collapsed) - regChange(cm, from.line, to.line + 1); - else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) - for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); - if (marker.atomic) reCheckSelection(cm.doc); - signalLater(cm, "markerAdded", cm, marker); - } - return marker; - } - - // SHARED TEXTMARKERS - - // A shared marker spans multiple linked documents. It is - // implemented as a meta-marker-object controlling multiple normal - // markers. - var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { - this.markers = markers; - this.primary = primary; - for (var i = 0; i < markers.length; ++i) - markers[i].parent = this; - }; - eventMixin(SharedTextMarker); - - SharedTextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - this.explicitlyCleared = true; - for (var i = 0; i < this.markers.length; ++i) - this.markers[i].clear(); - signalLater(this, "clear"); - }; - SharedTextMarker.prototype.find = function(side, lineObj) { - return this.primary.find(side, lineObj); - }; - - function markTextShared(doc, from, to, options, type) { - options = copyObj(options); - options.shared = false; - var markers = [markText(doc, from, to, options, type)], primary = markers[0]; - var widget = options.widgetNode; - linkedDocs(doc, function(doc) { - if (widget) options.widgetNode = widget.cloneNode(true); - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); - for (var i = 0; i < doc.linked.length; ++i) - if (doc.linked[i].isParent) return; - primary = lst(markers); - }); - return new SharedTextMarker(markers, primary); - } - - function findSharedMarkers(doc) { - return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), - function(m) { return m.parent; }); - } - - function copySharedMarkers(doc, markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], pos = marker.find(); - var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); - if (cmp(mFrom, mTo)) { - var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); - marker.markers.push(subMark); - subMark.parent = marker; - } - } - } - - function detachSharedMarkers(markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], linked = [marker.primary.doc];; - linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); - for (var j = 0; j < marker.markers.length; j++) { - var subMarker = marker.markers[j]; - if (indexOf(linked, subMarker.doc) == -1) { - subMarker.parent = null; - marker.markers.splice(j--, 1); - } - } - } - } - - // TEXTMARKER SPANS - - function MarkedSpan(marker, from, to) { - this.marker = marker; - this.from = from; this.to = to; - } - - // Search an array of spans for a span matching the given marker. - function getMarkedSpanFor(spans, marker) { - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.marker == marker) return span; - } - } - // Remove a span from an array, returning undefined if no spans are - // left (we don't store arrays for lines without spans). - function removeMarkedSpan(spans, span) { - for (var r, i = 0; i < spans.length; ++i) - if (spans[i] != span) (r || (r = [])).push(spans[i]); - return r; - } - // Add a span to a line. - function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; - span.marker.attachLine(line); - } - - // Used for the algorithm that adjusts markers for a change in the - // document. These functions cut an array of spans at a given - // character position, returning an array of remaining chunks (or - // undefined if nothing remains). - function markedSpansBefore(old, startCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); - if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); - (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); - } - } - return nw; - } - function markedSpansAfter(old, endCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); - if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); - (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, - span.to == null ? null : span.to - endCh)); - } - } - return nw; - } - - // Given a change object, compute the new set of marker spans that - // cover the line in which the change took place. Removes spans - // entirely within the change, reconnects spans belonging to the - // same marker that appear on both sides of the change, and cuts off - // spans partially within the change. Returns an array of span - // arrays with one element for each line in (after) the change. - function stretchSpansOverChange(doc, change) { - if (change.full) return null; - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; - if (!oldFirst && !oldLast) return null; - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert); - var last = markedSpansAfter(oldLast, endCh, isInsert); - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i]; - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker); - if (!found) span.to = startCh; - else if (sameLine) span.to = found.to == null ? null : found.to + offset; - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i = 0; i < last.length; ++i) { - var span = last[i]; - if (span.to != null) span.to += offset; - if (span.from == null) { - var found = getMarkedSpanFor(first, span.marker); - if (!found) { - span.from = offset; - if (sameLine) (first || (first = [])).push(span); - } - } else { - span.from += offset; - if (sameLine) (first || (first = [])).push(span); - } - } - } - // Make sure we didn't create any zero-length spans - if (first) first = clearEmptySpans(first); - if (last && last != first) last = clearEmptySpans(last); - - var newMarkers = [first]; - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers; - if (gap > 0 && first) - for (var i = 0; i < first.length; ++i) - if (first[i].to == null) - (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); - for (var i = 0; i < gap; ++i) - newMarkers.push(gapMarkers); - newMarkers.push(last); - } - return newMarkers; - } - - // Remove spans that are empty and don't have a clearWhenEmpty - // option of false. - function clearEmptySpans(spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) - spans.splice(i--, 1); - } - if (!spans.length) return null; - return spans; - } - - // Used for un/re-doing changes from the history. Combines the - // result of computing the existing spans with the set of spans that - // existed in the history (so that deleting around a span and then - // undoing brings back the span). - function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change); - var stretched = stretchSpansOverChange(doc, change); - if (!old) return stretched; - if (!stretched) return old; - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i]; - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j]; - for (var k = 0; k < oldCur.length; ++k) - if (oldCur[k].marker == span.marker) continue spans; - oldCur.push(span); - } - } else if (stretchCur) { - old[i] = stretchCur; - } - } - return old; - } - - // Used to 'clip' out readOnly ranges when making a change. - function removeReadOnlyRanges(doc, from, to) { - var markers = null; - doc.iter(from.line, to.line + 1, function(line) { - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker; - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) - (markers || (markers = [])).push(mark); - } - }); - if (!markers) return null; - var parts = [{from: from, to: to}]; - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(0); - for (var j = 0; j < parts.length; ++j) { - var p = parts[j]; - if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; - var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); - if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) - newParts.push({from: p.from, to: m.from}); - if (dto > 0 || !mk.inclusiveRight && !dto) - newParts.push({from: m.to, to: p.to}); - parts.splice.apply(parts, newParts); - j += newParts.length - 1; - } - } - return parts; - } - - // Connect or disconnect spans from a line. - function detachMarkedSpans(line) { - var spans = line.markedSpans; - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.detachLine(line); - line.markedSpans = null; - } - function attachMarkedSpans(line, spans) { - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.attachLine(line); - line.markedSpans = spans; - } - - // Helpers used when computing which overlapping collapsed span - // counts as the larger one. - function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } - function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } - - // Returns a number indicating which of two overlapping collapsed - // spans is larger (and thus includes the other). Falls back to - // comparing ids when the spans cover exactly the same range. - function compareCollapsedMarkers(a, b) { - var lenDiff = a.lines.length - b.lines.length; - if (lenDiff != 0) return lenDiff; - var aPos = a.find(), bPos = b.find(); - var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); - if (fromCmp) return -fromCmp; - var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); - if (toCmp) return toCmp; - return b.id - a.id; - } - - // Find out whether a line ends or starts in a collapsed span. If - // so, return the marker for that span. - function collapsedSpanAtSide(line, start) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) - found = sp.marker; - } - return found; - } - function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } - function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } - - // Test whether there exists a collapsed span that partially - // overlaps (covers the start or end, but not both) of a new span. - // Such overlap is not allowed. - function conflictingCollapsedRange(doc, lineNo, from, to, marker) { - var line = getLine(doc, lineNo); - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) { - var sp = sps[i]; - if (!sp.marker.collapsed) continue; - var found = sp.marker.find(0); - var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); - var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); - if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; - if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) || - fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight))) - return true; - } - } - - // A visual line is a line as drawn on the screen. Folding, for - // example, can cause multiple logical lines to appear on the same - // visual line. This finds the start of the visual line that the - // given line is part of (usually that is the line itself). - function visualLine(line) { - var merged; - while (merged = collapsedSpanAtStart(line)) - line = merged.find(-1, true).line; - return line; - } - - // Returns an array of logical lines that continue the visual line - // started by the argument, or undefined if there are no such lines. - function visualLineContinued(line) { - var merged, lines; - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - (lines || (lines = [])).push(line); - } - return lines; - } - - // Get the line number of the start of the visual line that the - // given line number is part of. - function visualLineNo(doc, lineN) { - var line = getLine(doc, lineN), vis = visualLine(line); - if (line == vis) return lineN; - return lineNo(vis); - } - // Get the line number of the start of the next visual line after - // the given line. - function visualLineEndNo(doc, lineN) { - if (lineN > doc.lastLine()) return lineN; - var line = getLine(doc, lineN), merged; - if (!lineIsHidden(doc, line)) return lineN; - while (merged = collapsedSpanAtEnd(line)) - line = merged.find(1, true).line; - return lineNo(line) + 1; - } - - // Compute whether a line is hidden. Lines count as hidden when they - // are part of a visual line that starts with another line, or when - // they are entirely covered by collapsed, non-widget span. - function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) continue; - if (sp.from == null) return true; - if (sp.marker.widgetNode) continue; - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) - return true; - } - } - function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find(1, true); - return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); - } - if (span.marker.inclusiveRight && span.to == line.text.length) - return true; - for (var sp, i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i]; - if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && - (sp.to == null || sp.to != span.from) && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) return true; - } - } - - // LINE WIDGETS - - // Line widgets are block elements displayed above or below a line. - - var LineWidget = CodeMirror.LineWidget = function(doc, node, options) { - if (options) for (var opt in options) if (options.hasOwnProperty(opt)) - this[opt] = options[opt]; - this.doc = doc; - this.node = node; - }; - eventMixin(LineWidget); - - function adjustScrollWhenAboveVisible(cm, line, diff) { - if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) - addToScrollPos(cm, null, diff); - } - - LineWidget.prototype.clear = function() { - var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); - if (no == null || !ws) return; - for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); - if (!ws.length) line.widgets = null; - var height = widgetHeight(this); - updateLineHeight(line, Math.max(0, line.height - height)); - if (cm) runInOp(cm, function() { - adjustScrollWhenAboveVisible(cm, line, -height); - regLineChange(cm, no, "widget"); - }); - }; - LineWidget.prototype.changed = function() { - var oldH = this.height, cm = this.doc.cm, line = this.line; - this.height = null; - var diff = widgetHeight(this) - oldH; - if (!diff) return; - updateLineHeight(line, line.height + diff); - if (cm) runInOp(cm, function() { - cm.curOp.forceUpdate = true; - adjustScrollWhenAboveVisible(cm, line, diff); - }); - }; - - function widgetHeight(widget) { - if (widget.height != null) return widget.height; - var cm = widget.doc.cm; - if (!cm) return 0; - if (!contains(document.body, widget.node)) { - var parentStyle = "position: relative;"; - if (widget.coverGutter) - parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; - if (widget.noHScroll) - parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; - removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); - } - return widget.height = widget.node.parentNode.offsetHeight; - } - - function addLineWidget(doc, handle, node, options) { - var widget = new LineWidget(doc, node, options); - var cm = doc.cm; - if (cm && widget.noHScroll) cm.display.alignWidgets = true; - changeLine(doc, handle, "widget", function(line) { - var widgets = line.widgets || (line.widgets = []); - if (widget.insertAt == null) widgets.push(widget); - else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); - widget.line = line; - if (cm && !lineIsHidden(doc, line)) { - var aboveVisible = heightAtLine(line) < doc.scrollTop; - updateLineHeight(line, line.height + widgetHeight(widget)); - if (aboveVisible) addToScrollPos(cm, null, widget.height); - cm.curOp.forceUpdate = true; - } - return true; - }); - return widget; - } - - // LINE DATA STRUCTURE - - // Line objects. These hold state related to a line, including - // highlighting info (the styles array). - var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { - this.text = text; - attachMarkedSpans(this, markedSpans); - this.height = estimateHeight ? estimateHeight(this) : 1; - }; - eventMixin(Line); - Line.prototype.lineNo = function() { return lineNo(this); }; - - // Change the content (text, markers) of a line. Automatically - // invalidates cached information and tries to re-estimate the - // line's height. - function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text; - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - if (line.order != null) line.order = null; - detachMarkedSpans(line); - attachMarkedSpans(line, markedSpans); - var estHeight = estimateHeight ? estimateHeight(line) : 1; - if (estHeight != line.height) updateLineHeight(line, estHeight); - } - - // Detach a line from the document tree and its markers. - function cleanUpLine(line) { - line.parent = null; - detachMarkedSpans(line); - } - - function extractLineClasses(type, output) { - if (type) for (;;) { - var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); - if (!lineClass) break; - type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); - var prop = lineClass[1] ? "bgClass" : "textClass"; - if (output[prop] == null) - output[prop] = lineClass[2]; - else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) - output[prop] += " " + lineClass[2]; - } - return type; - } - - function callBlankLine(mode, state) { - if (mode.blankLine) return mode.blankLine(state); - if (!mode.innerMode) return; - var inner = CodeMirror.innerMode(mode, state); - if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); - } - - function readToken(mode, stream, state, inner) { - for (var i = 0; i < 10; i++) { - if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; - var style = mode.token(stream, state); - if (stream.pos > stream.start) return style; - } - throw new Error("Mode " + mode.name + " failed to advance stream."); - } - - // Utility for getTokenAt and getLineTokens - function takeToken(cm, pos, precise, asArray) { - function getObj(copy) { - return {start: stream.start, end: stream.pos, - string: stream.current(), - type: style || null, - state: copy ? copyState(doc.mode, state) : state}; - } - - var doc = cm.doc, mode = doc.mode, style; - pos = clipPos(doc, pos); - var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); - var stream = new StringStream(line.text, cm.options.tabSize), tokens; - if (asArray) tokens = []; - while ((asArray || stream.pos < pos.ch) && !stream.eol()) { - stream.start = stream.pos; - style = readToken(mode, stream, state); - if (asArray) tokens.push(getObj(true)); - } - return asArray ? tokens : getObj(); - } - - // Run the given mode's parser over a line, calling f for each token. - function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { - var flattenSpans = mode.flattenSpans; - if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; - var curStart = 0, curStyle = null; - var stream = new StringStream(text, cm.options.tabSize), style; - var inner = cm.options.addModeClass && [null]; - if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false; - if (forceToEnd) processLine(cm, text, state, stream.pos); - stream.pos = text.length; - style = null; - } else { - style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); - } - if (inner) { - var mName = inner[0].name; - if (mName) style = "m-" + (style ? mName + " " + style : mName); - } - if (!flattenSpans || curStyle != style) { - while (curStart < stream.start) { - curStart = Math.min(stream.start, curStart + 50000); - f(curStart, curStyle); - } - curStyle = style; - } - stream.start = stream.pos; - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 characters - var pos = Math.min(stream.pos, curStart + 50000); - f(pos, curStyle); - curStart = pos; - } - } - - // Compute a style array (an array starting with a mode generation - // -- for invalidation -- followed by pairs of end positions and - // style strings), which is used to highlight the tokens on the - // line. - function highlightLine(cm, line, state, forceToEnd) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen], lineClasses = {}; - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, state, function(end, style) { - st.push(end, style); - }, lineClasses, forceToEnd); - - // Run overlays, adjust style array. - for (var o = 0; o < cm.state.overlays.length; ++o) { - var overlay = cm.state.overlays[o], i = 1, at = 0; - runMode(cm, line.text, overlay.mode, true, function(end, style) { - var start = i; - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i]; - if (i_end > end) - st.splice(i, 1, end, st[i+1], i_end); - i += 2; - at = Math.min(end, i_end); - } - if (!style) return; - if (overlay.opaque) { - st.splice(start, i - start, end, "cm-overlay " + style); - i = start + 2; - } else { - for (; start < i; start += 2) { - var cur = st[start+1]; - st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; - } - } - }, lineClasses); - } - - return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; - } - - function getLineStyles(cm, line, updateFrontier) { - if (!line.styles || line.styles[0] != cm.state.modeGen) { - var state = getStateBefore(cm, lineNo(line)); - var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state); - line.stateAfter = state; - line.styles = result.styles; - if (result.classes) line.styleClasses = result.classes; - else if (line.styleClasses) line.styleClasses = null; - if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; - } - return line.styles; - } - - // Lightweight form of highlight -- proceed over this line and - // update state, but don't save a style array. Used for lines that - // aren't currently visible. - function processLine(cm, text, state, startAt) { - var mode = cm.doc.mode; - var stream = new StringStream(text, cm.options.tabSize); - stream.start = stream.pos = startAt || 0; - if (text == "") callBlankLine(mode, state); - while (!stream.eol()) { - readToken(mode, stream, state); - stream.start = stream.pos; - } - } - - // Convert a style as returned by a mode (either null, or a string - // containing one or more styles) to a CSS style. This is cached, - // and also looks for line-wide styles. - var styleToClassCache = {}, styleToClassCacheWithMode = {}; - function interpretTokenStyle(style, options) { - if (!style || /^\s*$/.test(style)) return null; - var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; - return cache[style] || - (cache[style] = style.replace(/\S+/g, "cm-$&")); - } - - // Render the DOM representation of the text of a line. Also builds - // up a 'line map', which points at the DOM nodes that represent - // specific stretches of text, and is used by the measuring code. - // The returned object contains the DOM node, this map, and - // information about line-wide styles that were set by the mode. - function buildLineContent(cm, lineView) { - // The padding-right forces the element to have a 'border', which - // is needed on Webkit to be able to get line-level bounding - // rectangles for it (in measureChar). - var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); - var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content, - col: 0, pos: 0, cm: cm, - splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}; - lineView.measure = {}; - - // Iterate over the logical lines that make up this visual line. - for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { - var line = i ? lineView.rest[i - 1] : lineView.line, order; - builder.pos = 0; - builder.addToken = buildToken; - // Optionally wire in some hacks into the token-rendering - // algorithm, to deal with browser quirks. - if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) - builder.addToken = buildTokenBadBidi(builder.addToken, order); - builder.map = []; - var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); - insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); - if (line.styleClasses) { - if (line.styleClasses.bgClass) - builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); - if (line.styleClasses.textClass) - builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); - } - - // Ensure at least a single node is present, for measuring. - if (builder.map.length == 0) - builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); - - // Store the map and a cache object for the current logical line - if (i == 0) { - lineView.measure.map = builder.map; - lineView.measure.cache = {}; - } else { - (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); - (lineView.measure.caches || (lineView.measure.caches = [])).push({}); - } - } - - // See issue #2901 - if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className)) - builder.content.className = "cm-tab-wrap-hack"; - - signal(cm, "renderLine", cm, lineView.line, builder.pre); - if (builder.pre.className) - builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); - - return builder; - } - - function defaultSpecialCharPlaceholder(ch) { - var token = elt("span", "\u2022", "cm-invalidchar"); - token.title = "\\u" + ch.charCodeAt(0).toString(16); - token.setAttribute("aria-label", token.title); - return token; - } - - // Build up the DOM representation for a single token, and add it to - // the line map. Takes care to render special characters separately. - function buildToken(builder, text, style, startStyle, endStyle, title, css) { - if (!text) return; - var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text; - var special = builder.cm.state.specialChars, mustWrap = false; - if (!special.test(text)) { - builder.col += text.length; - var content = document.createTextNode(displayText); - builder.map.push(builder.pos, builder.pos + text.length, content); - if (ie && ie_version < 9) mustWrap = true; - builder.pos += text.length; - } else { - var content = document.createDocumentFragment(), pos = 0; - while (true) { - special.lastIndex = pos; - var m = special.exec(text); - var skipped = m ? m.index - pos : text.length - pos; - if (skipped) { - var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); - if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.map.push(builder.pos, builder.pos + skipped, txt); - builder.col += skipped; - builder.pos += skipped; - } - if (!m) break; - pos += skipped + 1; - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; - var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); - txt.setAttribute("role", "presentation"); - txt.setAttribute("cm-text", "\t"); - builder.col += tabWidth; - } else if (m[0] == "\r" || m[0] == "\n") { - var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); - txt.setAttribute("cm-text", m[0]); - builder.col += 1; - } else { - var txt = builder.cm.options.specialCharPlaceholder(m[0]); - txt.setAttribute("cm-text", m[0]); - if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.col += 1; - } - builder.map.push(builder.pos, builder.pos + 1, txt); - builder.pos++; - } - } - if (style || startStyle || endStyle || mustWrap || css) { - var fullStyle = style || ""; - if (startStyle) fullStyle += startStyle; - if (endStyle) fullStyle += endStyle; - var token = elt("span", [content], fullStyle, css); - if (title) token.title = title; - return builder.content.appendChild(token); - } - builder.content.appendChild(content); - } - - function splitSpaces(old) { - var out = " "; - for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; - out += " "; - return out; - } - - // Work around nonsense dimensions being reported for stretches of - // right-to-left text. - function buildTokenBadBidi(inner, order) { - return function(builder, text, style, startStyle, endStyle, title, css) { - style = style ? style + " cm-force-border" : "cm-force-border"; - var start = builder.pos, end = start + text.length; - for (;;) { - // Find the part that overlaps with the start of this text - for (var i = 0; i < order.length; i++) { - var part = order[i]; - if (part.to > start && part.from <= start) break; - } - if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); - inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); - startStyle = null; - text = text.slice(part.to - start); - start = part.to; - } - }; - } - - function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.widgetNode; - if (widget) builder.map.push(builder.pos, builder.pos + size, widget); - if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { - if (!widget) - widget = builder.content.appendChild(document.createElement("span")); - widget.setAttribute("cm-marker", marker.id); - } - if (widget) { - builder.cm.display.input.setUneditable(widget); - builder.content.appendChild(widget); - } - builder.pos += size; - } - - // Outputs a number of spans to make up a line, taking highlighting - // and marked text into account. - function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0; - if (!spans) { - for (var i = 1; i < styles.length; i+=2) - builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); - return; - } - - var len = allText.length, pos = 0, i = 1, text = "", style, css; - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; - for (;;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = title = css = ""; - collapsed = null; nextChange = Infinity; - var foundBookmarks = [], endStyles - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker; - if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { - foundBookmarks.push(m); - } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { - if (sp.to != null && sp.to != pos && nextChange > sp.to) { - nextChange = sp.to; - spanEndStyle = ""; - } - if (m.className) spanStyle += " " + m.className; - if (m.css) css = (css ? css + ";" : "") + m.css; - if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; - if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to) - if (m.title && !title) title = m.title; - if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) - collapsed = sp; - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from; - } - } - if (endStyles) for (var j = 0; j < endStyles.length; j += 2) - if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j] - - if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j) - buildCollapsedSpan(builder, 0, foundBookmarks[j]); - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, - collapsed.marker, collapsed.from == null); - if (collapsed.to == null) return; - if (collapsed.to == pos) collapsed = false; - } - } - if (pos >= len) break; - - var upto = Math.min(len, nextChange); - while (true) { - if (text) { - var end = pos + text.length; - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text; - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); - } - if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} - pos = end; - spanStartStyle = ""; - } - text = allText.slice(at, at = styles[i++]); - style = interpretTokenStyle(styles[i++], builder.cm.options); - } - } - } - - // DOCUMENT DATA STRUCTURE - - // By default, updates that start and end at the beginning of a line - // are treated specially, in order to make the association of line - // widgets and marker elements with the text behave more intuitive. - function isWholeLineUpdate(doc, change) { - return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && - (!doc.cm || doc.cm.options.wholeLineUpdateBefore); - } - - // Perform a change on the document data structure. - function updateDoc(doc, change, markedSpans, estimateHeight) { - function spansFor(n) {return markedSpans ? markedSpans[n] : null;} - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight); - signalLater(line, "change", line, change); - } - function linesFor(start, end) { - for (var i = start, result = []; i < end; ++i) - result.push(new Line(text[i], spansFor(i), estimateHeight)); - return result; - } - - var from = change.from, to = change.to, text = change.text; - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; - - // Adjust the line structure - if (change.full) { - doc.insert(0, linesFor(0, text.length)); - doc.remove(text.length, doc.size - text.length); - } else if (isWholeLineUpdate(doc, change)) { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - var added = linesFor(0, text.length - 1); - update(lastLine, lastLine.text, lastSpans); - if (nlines) doc.remove(from.line, nlines); - if (added.length) doc.insert(from.line, added); - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); - } else { - var added = linesFor(1, text.length - 1); - added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - doc.insert(from.line + 1, added); - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); - doc.remove(from.line + 1, nlines); - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); - var added = linesFor(1, text.length - 1); - if (nlines > 1) doc.remove(from.line + 1, nlines - 1); - doc.insert(from.line + 1, added); - } - - signalLater(doc, "change", doc, change); - } - - // The document is represented as a BTree consisting of leaves, with - // chunk of lines in them, and branches, with up to ten leaves or - // other branch nodes below them. The top node is always a branch - // node, and is the document object itself (meaning it has - // additional methods and properties). - // - // All nodes have parent links. The tree is used both to go from - // line numbers to line objects, and to go from objects to numbers. - // It also indexes by height, and is used to convert between height - // and line object, and to find the total height of the document. - // - // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html - - function LeafChunk(lines) { - this.lines = lines; - this.parent = null; - for (var i = 0, height = 0; i < lines.length; ++i) { - lines[i].parent = this; - height += lines[i].height; - } - this.height = height; - } - - LeafChunk.prototype = { - chunkSize: function() { return this.lines.length; }, - // Remove the n lines at offset 'at'. - removeInner: function(at, n) { - for (var i = at, e = at + n; i < e; ++i) { - var line = this.lines[i]; - this.height -= line.height; - cleanUpLine(line); - signalLater(line, "delete"); - } - this.lines.splice(at, n); - }, - // Helper used to collapse a small branch into a single leaf. - collapse: function(lines) { - lines.push.apply(lines, this.lines); - }, - // Insert the given array of lines at offset 'at', count them as - // having the given height. - insertInner: function(at, lines, height) { - this.height += height; - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); - for (var i = 0; i < lines.length; ++i) lines[i].parent = this; - }, - // Used to iterate over a part of the tree. - iterN: function(at, n, op) { - for (var e = at + n; at < e; ++at) - if (op(this.lines[at])) return true; - } - }; - - function BranchChunk(children) { - this.children = children; - var size = 0, height = 0; - for (var i = 0; i < children.length; ++i) { - var ch = children[i]; - size += ch.chunkSize(); height += ch.height; - ch.parent = this; - } - this.size = size; - this.height = height; - this.parent = null; - } - - BranchChunk.prototype = { - chunkSize: function() { return this.size; }, - removeInner: function(at, n) { - this.size -= n; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height; - child.removeInner(at, rm); - this.height -= oldHeight - child.height; - if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } - if ((n -= rm) == 0) break; - at = 0; - } else at -= sz; - } - // If the result is smaller than 25 lines, ensure that it is a - // single leaf node. - if (this.size - n < 25 && - (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { - var lines = []; - this.collapse(lines); - this.children = [new LeafChunk(lines)]; - this.children[0].parent = this; - } - }, - collapse: function(lines) { - for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); - }, - insertInner: function(at, lines, height) { - this.size += lines.length; - this.height += height; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at <= sz) { - child.insertInner(at, lines, height); - if (child.lines && child.lines.length > 50) { - while (child.lines.length > 50) { - var spilled = child.lines.splice(child.lines.length - 25, 25); - var newleaf = new LeafChunk(spilled); - child.height -= newleaf.height; - this.children.splice(i + 1, 0, newleaf); - newleaf.parent = this; - } - this.maybeSpill(); - } - break; - } - at -= sz; - } - }, - // When a node has grown, check whether it should be split. - maybeSpill: function() { - if (this.children.length <= 10) return; - var me = this; - do { - var spilled = me.children.splice(me.children.length - 5, 5); - var sibling = new BranchChunk(spilled); - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children); - copy.parent = me; - me.children = [copy, sibling]; - me = copy; - } else { - me.size -= sibling.size; - me.height -= sibling.height; - var myIndex = indexOf(me.parent.children, me); - me.parent.children.splice(myIndex + 1, 0, sibling); - } - sibling.parent = me.parent; - } while (me.children.length > 10); - me.parent.maybeSpill(); - }, - iterN: function(at, n, op) { - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var used = Math.min(n, sz - at); - if (child.iterN(at, used, op)) return true; - if ((n -= used) == 0) break; - at = 0; - } else at -= sz; - } - } - }; - - var nextDocId = 0; - var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) { - if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep); - if (firstLine == null) firstLine = 0; - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); - this.first = firstLine; - this.scrollTop = this.scrollLeft = 0; - this.cantEdit = false; - this.cleanGeneration = 1; - this.frontier = firstLine; - var start = Pos(firstLine, 0); - this.sel = simpleSelection(start); - this.history = new History(null); - this.id = ++nextDocId; - this.modeOption = mode; - this.lineSep = lineSep; - this.extend = false; - - if (typeof text == "string") text = this.splitLines(text); - updateDoc(this, {from: start, to: start, text: text}); - setSelection(this, simpleSelection(start), sel_dontScroll); - }; - - Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - // Iterate over the document. Supports two forms -- with only one - // argument, it calls that for each line in the document. With - // three, it iterates over the range given by the first two (with - // the second being non-inclusive). - iter: function(from, to, op) { - if (op) this.iterN(from - this.first, to - from, op); - else this.iterN(this.first, this.first + this.size, from); - }, - - // Non-public interface for adding and removing lines. - insert: function(at, lines) { - var height = 0; - for (var i = 0; i < lines.length; ++i) height += lines[i].height; - this.insertInner(at - this.first, lines, height); - }, - remove: function(at, n) { this.removeInner(at - this.first, n); }, - - // From here, the methods are part of the public interface. Most - // are also available from CodeMirror (editor) instances. - - getValue: function(lineSep) { - var lines = getLines(this, this.first, this.first + this.size); - if (lineSep === false) return lines; - return lines.join(lineSep || this.lineSeparator()); - }, - setValue: docMethodOp(function(code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1; - makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), - text: this.splitLines(code), origin: "setValue", full: true}, true); - setSelection(this, simpleSelection(top)); - }), - replaceRange: function(code, from, to, origin) { - from = clipPos(this, from); - to = to ? clipPos(this, to) : from; - replaceRange(this, code, from, to, origin); - }, - getRange: function(from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); - if (lineSep === false) return lines; - return lines.join(lineSep || this.lineSeparator()); - }, - - getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, - - getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, - getLineNumber: function(line) {return lineNo(line);}, - - getLineHandleVisualStart: function(line) { - if (typeof line == "number") line = getLine(this, line); - return visualLine(line); - }, - - lineCount: function() {return this.size;}, - firstLine: function() {return this.first;}, - lastLine: function() {return this.first + this.size - 1;}, - - clipPos: function(pos) {return clipPos(this, pos);}, - - getCursor: function(start) { - var range = this.sel.primary(), pos; - if (start == null || start == "head") pos = range.head; - else if (start == "anchor") pos = range.anchor; - else if (start == "end" || start == "to" || start === false) pos = range.to(); - else pos = range.from(); - return pos; - }, - listSelections: function() { return this.sel.ranges; }, - somethingSelected: function() {return this.sel.somethingSelected();}, - - setCursor: docMethodOp(function(line, ch, options) { - setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); - }), - setSelection: docMethodOp(function(anchor, head, options) { - setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); - }), - extendSelection: docMethodOp(function(head, other, options) { - extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); - }), - extendSelections: docMethodOp(function(heads, options) { - extendSelections(this, clipPosArray(this, heads), options); - }), - extendSelectionsBy: docMethodOp(function(f, options) { - var heads = map(this.sel.ranges, f); - extendSelections(this, clipPosArray(this, heads), options); - }), - setSelections: docMethodOp(function(ranges, primary, options) { - if (!ranges.length) return; - for (var i = 0, out = []; i < ranges.length; i++) - out[i] = new Range(clipPos(this, ranges[i].anchor), - clipPos(this, ranges[i].head)); - if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); - setSelection(this, normalizeSelection(out, primary), options); - }), - addSelection: docMethodOp(function(anchor, head, options) { - var ranges = this.sel.ranges.slice(0); - ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); - setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); - }), - - getSelection: function(lineSep) { - var ranges = this.sel.ranges, lines; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - lines = lines ? lines.concat(sel) : sel; - } - if (lineSep === false) return lines; - else return lines.join(lineSep || this.lineSeparator()); - }, - getSelections: function(lineSep) { - var parts = [], ranges = this.sel.ranges; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator()); - parts[i] = sel; - } - return parts; - }, - replaceSelection: function(code, collapse, origin) { - var dup = []; - for (var i = 0; i < this.sel.ranges.length; i++) - dup[i] = code; - this.replaceSelections(dup, collapse, origin || "+input"); - }, - replaceSelections: docMethodOp(function(code, collapse, origin) { - var changes = [], sel = this.sel; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin}; - } - var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); - for (var i = changes.length - 1; i >= 0; i--) - makeChange(this, changes[i]); - if (newSel) setSelectionReplaceHistory(this, newSel); - else if (this.cm) ensureCursorVisible(this.cm); - }), - undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), - redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), - undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), - redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), - - setExtending: function(val) {this.extend = val;}, - getExtending: function() {return this.extend;}, - - historySize: function() { - var hist = this.history, done = 0, undone = 0; - for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; - for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; - return {undo: done, redo: undone}; - }, - clearHistory: function() {this.history = new History(this.history.maxGeneration);}, - - markClean: function() { - this.cleanGeneration = this.changeGeneration(true); - }, - changeGeneration: function(forceSplit) { - if (forceSplit) - this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; - return this.history.generation; - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration); - }, - - getHistory: function() { - return {done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone)}; - }, - setHistory: function(histData) { - var hist = this.history = new History(this.history.maxGeneration); - hist.done = copyHistoryArray(histData.done.slice(0), null, true); - hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); - }, - - addLineClass: docMethodOp(function(handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass"; - if (!line[prop]) line[prop] = cls; - else if (classTest(cls).test(line[prop])) return false; - else line[prop] += " " + cls; - return true; - }); - }), - removeLineClass: docMethodOp(function(handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass"; - var cur = line[prop]; - if (!cur) return false; - else if (cls == null) line[prop] = null; - else { - var found = cur.match(classTest(cls)); - if (!found) return false; - var end = found.index + found[0].length; - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; - } - return true; - }); - }), - - addLineWidget: docMethodOp(function(handle, node, options) { - return addLineWidget(this, handle, node, options); - }), - removeLineWidget: function(widget) { widget.clear(); }, - - markText: function(from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range"); - }, - setBookmark: function(pos, options) { - var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft, - clearWhenEmpty: false, shared: options && options.shared, - handleMouseEvents: options && options.handleMouseEvents}; - pos = clipPos(this, pos); - return markText(this, pos, pos, realOpts, "bookmark"); - }, - findMarksAt: function(pos) { - pos = clipPos(this, pos); - var markers = [], spans = getLine(this, pos.line).markedSpans; - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) - markers.push(span.marker.parent || span.marker); - } - return markers; - }, - findMarks: function(from, to, filter) { - from = clipPos(this, from); to = clipPos(this, to); - var found = [], lineNo = from.line; - this.iter(from.line, to.line + 1, function(line) { - var spans = line.markedSpans; - if (spans) for (var i = 0; i < spans.length; i++) { - var span = spans[i]; - if (!(span.to != null && lineNo == from.line && from.ch >= span.to || - span.from == null && lineNo != from.line || - span.from != null && lineNo == to.line && span.from >= to.ch) && - (!filter || filter(span.marker))) - found.push(span.marker.parent || span.marker); - } - ++lineNo; - }); - return found; - }, - getAllMarks: function() { - var markers = []; - this.iter(function(line) { - var sps = line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) - if (sps[i].from != null) markers.push(sps[i].marker); - }); - return markers; - }, - - posFromIndex: function(off) { - var ch, lineNo = this.first, sepSize = this.lineSeparator().length; - this.iter(function(line) { - var sz = line.text.length + sepSize; - if (sz > off) { ch = off; return true; } - off -= sz; - ++lineNo; - }); - return clipPos(this, Pos(lineNo, ch)); - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords); - var index = coords.ch; - if (coords.line < this.first || coords.ch < 0) return 0; - var sepSize = this.lineSeparator().length; - this.iter(this.first, coords.line, function (line) { - index += line.text.length + sepSize; - }); - return index; - }, - - copy: function(copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), - this.modeOption, this.first, this.lineSep); - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; - doc.sel = this.sel; - doc.extend = false; - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth; - doc.setHistory(this.getHistory()); - } - return doc; - }, - - linkedDoc: function(options) { - if (!options) options = {}; - var from = this.first, to = this.first + this.size; - if (options.from != null && options.from > from) from = options.from; - if (options.to != null && options.to < to) to = options.to; - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep); - if (options.sharedHist) copy.history = this.history; - (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); - copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; - copySharedMarkers(copy, findSharedMarkers(this)); - return copy; - }, - unlinkDoc: function(other) { - if (other instanceof CodeMirror) other = other.doc; - if (this.linked) for (var i = 0; i < this.linked.length; ++i) { - var link = this.linked[i]; - if (link.doc != other) continue; - this.linked.splice(i, 1); - other.unlinkDoc(this); - detachSharedMarkers(findSharedMarkers(this)); - break; - } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id]; - linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); - other.history = new History(null); - other.history.done = copyHistoryArray(this.history.done, splitIds); - other.history.undone = copyHistoryArray(this.history.undone, splitIds); - } - }, - iterLinkedDocs: function(f) {linkedDocs(this, f);}, - - getMode: function() {return this.mode;}, - getEditor: function() {return this.cm;}, - - splitLines: function(str) { - if (this.lineSep) return str.split(this.lineSep); - return splitLinesAuto(str); - }, - lineSeparator: function() { return this.lineSep || "\n"; } - }); - - // Public alias. - Doc.prototype.eachLine = Doc.prototype.iter; - - // Set up methods on CodeMirror's prototype to redirect to the editor's document. - var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); - for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) - CodeMirror.prototype[prop] = (function(method) { - return function() {return method.apply(this.doc, arguments);}; - })(Doc.prototype[prop]); - - eventMixin(Doc); - - // Call f for all linked documents. - function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i]; - if (rel.doc == skip) continue; - var shared = sharedHist && rel.sharedHist; - if (sharedHistOnly && !shared) continue; - f(rel.doc, shared); - propagate(rel.doc, doc, shared); - } - } - propagate(doc, null, true); - } - - // Attach a document to an editor. - function attachDoc(cm, doc) { - if (doc.cm) throw new Error("This document is already in use."); - cm.doc = doc; - doc.cm = cm; - estimateLineHeights(cm); - loadMode(cm); - if (!cm.options.lineWrapping) findMaxLine(cm); - cm.options.mode = doc.modeOption; - regChange(cm); - } - - // LINE UTILITIES - - // Find the line object corresponding to the given line number. - function getLine(doc, n) { - n -= doc.first; - if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); - for (var chunk = doc; !chunk.lines;) { - for (var i = 0;; ++i) { - var child = chunk.children[i], sz = child.chunkSize(); - if (n < sz) { chunk = child; break; } - n -= sz; - } - } - return chunk.lines[n]; - } - - // Get the part of a document between two positions, as an array of - // strings. - function getBetween(doc, start, end) { - var out = [], n = start.line; - doc.iter(start.line, end.line + 1, function(line) { - var text = line.text; - if (n == end.line) text = text.slice(0, end.ch); - if (n == start.line) text = text.slice(start.ch); - out.push(text); - ++n; - }); - return out; - } - // Get the lines between from and to, as array of strings. - function getLines(doc, from, to) { - var out = []; - doc.iter(from, to, function(line) { out.push(line.text); }); - return out; - } - - // Update the height of a line, propagating the height change - // upwards to parent nodes. - function updateLineHeight(line, height) { - var diff = height - line.height; - if (diff) for (var n = line; n; n = n.parent) n.height += diff; - } - - // Given a line object, find its line number by walking up through - // its parent links. - function lineNo(line) { - if (line.parent == null) return null; - var cur = line.parent, no = indexOf(cur.lines, line); - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0;; ++i) { - if (chunk.children[i] == cur) break; - no += chunk.children[i].chunkSize(); - } - } - return no + cur.first; - } - - // Find the line at the given vertical position, using the height - // information in the document tree. - function lineAtHeight(chunk, h) { - var n = chunk.first; - outer: do { - for (var i = 0; i < chunk.children.length; ++i) { - var child = chunk.children[i], ch = child.height; - if (h < ch) { chunk = child; continue outer; } - h -= ch; - n += child.chunkSize(); - } - return n; - } while (!chunk.lines); - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i], lh = line.height; - if (h < lh) break; - h -= lh; - } - return n + i; - } - - - // Find the height above the given line. - function heightAtLine(lineObj) { - lineObj = visualLine(lineObj); - - var h = 0, chunk = lineObj.parent; - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i]; - if (line == lineObj) break; - else h += line.height; - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i = 0; i < p.children.length; ++i) { - var cur = p.children[i]; - if (cur == chunk) break; - else h += cur.height; - } - } - return h; - } - - // Get the bidi ordering for the given line (and cache it). Returns - // false for lines that are fully left-to-right, and an array of - // BidiSpan objects otherwise. - function getOrder(line) { - var order = line.order; - if (order == null) order = line.order = bidiOrdering(line.text); - return order; - } - - // HISTORY - - function History(startGen) { - // Arrays of change events and selections. Doing something adds an - // event to done and clears undo. Undoing moves events from done - // to undone, redoing moves them in the other direction. - this.done = []; this.undone = []; - this.undoDepth = Infinity; - // Used to track when changes can be merged into a single undo - // event - this.lastModTime = this.lastSelTime = 0; - this.lastOp = this.lastSelOp = null; - this.lastOrigin = this.lastSelOrigin = null; - // Used by the isClean() method - this.generation = this.maxGeneration = startGen || 1; - } - - // Create a history change event from an updateDoc-style change - // object. - function historyChangeFromChange(doc, change) { - var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); - linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); - return histChange; - } - - // Pop all selection events off the end of a history array. Stop at - // a change event. - function clearSelectionEvents(array) { - while (array.length) { - var last = lst(array); - if (last.ranges) array.pop(); - else break; - } - } - - // Find the top change event in the history. Pop off selection - // events that are in the way. - function lastChangeEvent(hist, force) { - if (force) { - clearSelectionEvents(hist.done); - return lst(hist.done); - } else if (hist.done.length && !lst(hist.done).ranges) { - return lst(hist.done); - } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { - hist.done.pop(); - return lst(hist.done); - } - } - - // Register a change in the history. Merges changes that are within - // a single operation, ore are close together with an origin that - // allows merging (starting with "+") into a single event. - function addChangeToHistory(doc, change, selAfter, opId) { - var hist = doc.history; - hist.undone.length = 0; - var time = +new Date, cur; - - if ((hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || - change.origin.charAt(0) == "*")) && - (cur = lastChangeEvent(hist, hist.lastOp == opId))) { - // Merge this change into the last event - var last = lst(cur.changes); - if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change); - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)); - } - } else { - // Can not be merged, start a new event. - var before = lst(hist.done); - if (!before || !before.ranges) - pushSelectionToHistory(doc.sel, hist.done); - cur = {changes: [historyChangeFromChange(doc, change)], - generation: hist.generation}; - hist.done.push(cur); - while (hist.done.length > hist.undoDepth) { - hist.done.shift(); - if (!hist.done[0].ranges) hist.done.shift(); - } - } - hist.done.push(selAfter); - hist.generation = ++hist.maxGeneration; - hist.lastModTime = hist.lastSelTime = time; - hist.lastOp = hist.lastSelOp = opId; - hist.lastOrigin = hist.lastSelOrigin = change.origin; - - if (!last) signal(doc, "historyAdded"); - } - - function selectionEventCanBeMerged(doc, origin, prev, sel) { - var ch = origin.charAt(0); - return ch == "*" || - ch == "+" && - prev.ranges.length == sel.ranges.length && - prev.somethingSelected() == sel.somethingSelected() && - new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); - } - - // Called whenever the selection changes, sets the new selection as - // the pending selection in the history, and pushes the old pending - // selection into the 'done' array when it was significantly - // different (in number of selected ranges, emptiness, or time). - function addSelectionToHistory(doc, sel, opId, options) { - var hist = doc.history, origin = options && options.origin; - - // A new event is started when the previous origin does not match - // the current, or the origins don't allow matching. Origins - // starting with * are always merged, those starting with + are - // merged when similar and close together in time. - if (opId == hist.lastSelOp || - (origin && hist.lastSelOrigin == origin && - (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || - selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) - hist.done[hist.done.length - 1] = sel; - else - pushSelectionToHistory(sel, hist.done); - - hist.lastSelTime = +new Date; - hist.lastSelOrigin = origin; - hist.lastSelOp = opId; - if (options && options.clearRedo !== false) - clearSelectionEvents(hist.undone); - } - - function pushSelectionToHistory(sel, dest) { - var top = lst(dest); - if (!(top && top.ranges && top.equals(sel))) - dest.push(sel); - } - - // Used to store marked span information in the history. - function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0; - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { - if (line.markedSpans) - (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; - ++n; - }); - } - - // When un/re-doing restores text containing marked spans, those - // that have been explicitly cleared should not be restored. - function removeClearedSpans(spans) { - if (!spans) return null; - for (var i = 0, out; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } - else if (out) out.push(spans[i]); - } - return !out ? spans : out.length ? out : null; - } - - // Retrieve and filter the old marked spans stored in a change event. - function getOldSpans(doc, change) { - var found = change["spans_" + doc.id]; - if (!found) return null; - for (var i = 0, nw = []; i < change.text.length; ++i) - nw.push(removeClearedSpans(found[i])); - return nw; - } - - // Used both to provide a JSON-safe object in .getHistory, and, when - // detaching a document, to split the history in two - function copyHistoryArray(events, newGroup, instantiateSel) { - for (var i = 0, copy = []; i < events.length; ++i) { - var event = events[i]; - if (event.ranges) { - copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); - continue; - } - var changes = event.changes, newChanges = []; - copy.push({changes: newChanges}); - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m; - newChanges.push({from: change.from, to: change.to, text: change.text}); - if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop]; - delete change[prop]; - } - } - } - } - return copy; - } - - // Rebasing/resetting history to deal with externally-sourced changes - - function rebaseHistSelSingle(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff; - } else if (from < pos.line) { - pos.line = from; - pos.ch = 0; - } - } - - // Tries to rebase an array of history events given a change in the - // document. If the change touches the same lines as the event, the - // event, and everything 'behind' it, is discarded. If the change is - // before the event, the event's positions are updated. Uses a - // copy-on-write scheme for the positions, to avoid having to - // reallocate them all on every rebase, but also avoid problems with - // shared position objects being unsafely updated. - function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true; - if (sub.ranges) { - if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } - for (var j = 0; j < sub.ranges.length; j++) { - rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); - rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); - } - continue; - } - for (var j = 0; j < sub.changes.length; ++j) { - var cur = sub.changes[j]; - if (to < cur.from.line) { - cur.from = Pos(cur.from.line + diff, cur.from.ch); - cur.to = Pos(cur.to.line + diff, cur.to.ch); - } else if (from <= cur.to.line) { - ok = false; - break; - } - } - if (!ok) { - array.splice(0, i + 1); - i = 0; - } - } - } - - function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; - rebaseHistArray(hist.done, from, to, diff); - rebaseHistArray(hist.undone, from, to, diff); - } - - // EVENT UTILITIES - - // Due to the fact that we still support jurassic IE versions, some - // compatibility wrappers are needed. - - var e_preventDefault = CodeMirror.e_preventDefault = function(e) { - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; - }; - var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { - if (e.stopPropagation) e.stopPropagation(); - else e.cancelBubble = true; - }; - function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; - } - var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; - - function e_target(e) {return e.target || e.srcElement;} - function e_button(e) { - var b = e.which; - if (b == null) { - if (e.button & 1) b = 1; - else if (e.button & 2) b = 3; - else if (e.button & 4) b = 2; - } - if (mac && e.ctrlKey && b == 1) b = 3; - return b; - } - - // EVENT HANDLING - - // Lightweight event framework. on/off also work on DOM nodes, - // registering native DOM handlers. - - var on = CodeMirror.on = function(emitter, type, f) { - if (emitter.addEventListener) - emitter.addEventListener(type, f, false); - else if (emitter.attachEvent) - emitter.attachEvent("on" + type, f); - else { - var map = emitter._handlers || (emitter._handlers = {}); - var arr = map[type] || (map[type] = []); - arr.push(f); - } - }; - - var noHandlers = [] - function getHandlers(emitter, type, copy) { - var arr = emitter._handlers && emitter._handlers[type] - if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers - else return arr || noHandlers - } - - var off = CodeMirror.off = function(emitter, type, f) { - if (emitter.removeEventListener) - emitter.removeEventListener(type, f, false); - else if (emitter.detachEvent) - emitter.detachEvent("on" + type, f); - else { - var handlers = getHandlers(emitter, type, false) - for (var i = 0; i < handlers.length; ++i) - if (handlers[i] == f) { handlers.splice(i, 1); break; } - } - }; - - var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { - var handlers = getHandlers(emitter, type, true) - if (!handlers.length) return; - var args = Array.prototype.slice.call(arguments, 2); - for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args); - }; - - var orphanDelayedCallbacks = null; - - // Often, we want to signal events at a point where we are in the - // middle of some work, but don't want the handler to start calling - // other methods on the editor, which might be in an inconsistent - // state or simply not expect any other events to happen. - // signalLater looks whether there are any handlers, and schedules - // them to be executed when the last operation ends, or, if no - // operation is active, when a timeout fires. - function signalLater(emitter, type /*, values...*/) { - var arr = getHandlers(emitter, type, false) - if (!arr.length) return; - var args = Array.prototype.slice.call(arguments, 2), list; - if (operationGroup) { - list = operationGroup.delayedCallbacks; - } else if (orphanDelayedCallbacks) { - list = orphanDelayedCallbacks; - } else { - list = orphanDelayedCallbacks = []; - setTimeout(fireOrphanDelayed, 0); - } - function bnd(f) {return function(){f.apply(null, args);};}; - for (var i = 0; i < arr.length; ++i) - list.push(bnd(arr[i])); - } - - function fireOrphanDelayed() { - var delayed = orphanDelayedCallbacks; - orphanDelayedCallbacks = null; - for (var i = 0; i < delayed.length; ++i) delayed[i](); - } - - // The DOM events that CodeMirror handles can be overridden by - // registering a (non-DOM) handler on the editor for the event name, - // and preventDefault-ing the event in that handler. - function signalDOMEvent(cm, e, override) { - if (typeof e == "string") - e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; - signal(cm, override || e.type, cm, e); - return e_defaultPrevented(e) || e.codemirrorIgnore; - } - - function signalCursorActivity(cm) { - var arr = cm._handlers && cm._handlers.cursorActivity; - if (!arr) return; - var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); - for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) - set.push(arr[i]); - } - - function hasHandler(emitter, type) { - return getHandlers(emitter, type).length > 0 - } - - // Add on and off methods to a constructor's prototype, to make - // registering events on such objects more convenient. - function eventMixin(ctor) { - ctor.prototype.on = function(type, f) {on(this, type, f);}; - ctor.prototype.off = function(type, f) {off(this, type, f);}; - } - - // MISC UTILITIES - - // Number of pixels added to scroller and sizer to hide scrollbar - var scrollerGap = 30; - - // Returned or thrown by various protocols to signal 'I'm not - // handling this'. - var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; - - // Reused option objects for setSelection & friends - var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; - - function Delayed() {this.id = null;} - Delayed.prototype.set = function(ms, f) { - clearTimeout(this.id); - this.id = setTimeout(f, ms); - }; - - // Counts the column offset in a string, taking tabs into account. - // Used mostly to find indentation. - var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) end = string.length; - } - for (var i = startIndex || 0, n = startValue || 0;;) { - var nextTab = string.indexOf("\t", i); - if (nextTab < 0 || nextTab >= end) - return n + (end - i); - n += nextTab - i; - n += tabSize - (n % tabSize); - i = nextTab + 1; - } - }; - - // The inverse of countColumn -- find the offset that corresponds to - // a particular column. - var findColumn = CodeMirror.findColumn = function(string, goal, tabSize) { - for (var pos = 0, col = 0;;) { - var nextTab = string.indexOf("\t", pos); - if (nextTab == -1) nextTab = string.length; - var skipped = nextTab - pos; - if (nextTab == string.length || col + skipped >= goal) - return pos + Math.min(skipped, goal - col); - col += nextTab - pos; - col += tabSize - (col % tabSize); - pos = nextTab + 1; - if (col >= goal) return pos; - } - } - - var spaceStrs = [""]; - function spaceStr(n) { - while (spaceStrs.length <= n) - spaceStrs.push(lst(spaceStrs) + " "); - return spaceStrs[n]; - } - - function lst(arr) { return arr[arr.length-1]; } - - var selectInput = function(node) { node.select(); }; - if (ios) // Mobile Safari apparently has a bug where select() is broken. - selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; - else if (ie) // Suppress mysterious IE10 errors - selectInput = function(node) { try { node.select(); } catch(_e) {} }; - - function indexOf(array, elt) { - for (var i = 0; i < array.length; ++i) - if (array[i] == elt) return i; - return -1; - } - function map(array, f) { - var out = []; - for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); - return out; - } - - function nothing() {} - - function createObj(base, props) { - var inst; - if (Object.create) { - inst = Object.create(base); - } else { - nothing.prototype = base; - inst = new nothing(); - } - if (props) copyObj(props, inst); - return inst; - }; - - function copyObj(obj, target, overwrite) { - if (!target) target = {}; - for (var prop in obj) - if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) - target[prop] = obj[prop]; - return target; - } - - function bind(f) { - var args = Array.prototype.slice.call(arguments, 1); - return function(){return f.apply(null, args);}; - } - - var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; - var isWordCharBasic = CodeMirror.isWordChar = function(ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); - }; - function isWordChar(ch, helper) { - if (!helper) return isWordCharBasic(ch); - if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; - return helper.test(ch); - } - - function isEmpty(obj) { - for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; - return true; - } - - // Extending unicode characters. A series of a non-extending char + - // any number of extending chars is treated as a single unit as far - // as editing and measuring is concerned. This is not fully correct, - // since some scripts/fonts/browsers also treat other configurations - // of code points as a group. - var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; - function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } - - // DOM UTILITIES - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") e.appendChild(document.createTextNode(content)); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - var range; - if (document.createRange) range = function(node, start, end, endNode) { - var r = document.createRange(); - r.setEnd(endNode || node, end); - r.setStart(node, start); - return r; - }; - else range = function(node, start, end) { - var r = document.body.createTextRange(); - try { r.moveToElementText(node.parentNode); } - catch(e) { return r; } - r.collapse(true); - r.moveEnd("character", end); - r.moveStart("character", start); - return r; - }; - - function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) - e.removeChild(e.firstChild); - return e; - } - - function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e); - } - - var contains = CodeMirror.contains = function(parent, child) { - if (child.nodeType == 3) // Android browser always returns false when child is a textnode - child = child.parentNode; - if (parent.contains) - return parent.contains(child); - do { - if (child.nodeType == 11) child = child.host; - if (child == parent) return true; - } while (child = child.parentNode); - }; - - function activeElt() { - var activeElement = document.activeElement; - while (activeElement && activeElement.root && activeElement.root.activeElement) - activeElement = activeElement.root.activeElement; - return activeElement; - } - // Older versions of IE throws unspecified error when touching - // document.activeElement in some cases (during loading, in iframe) - if (ie && ie_version < 11) activeElt = function() { - try { return document.activeElement; } - catch(e) { return document.body; } - }; - - function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } - var rmClass = CodeMirror.rmClass = function(node, cls) { - var current = node.className; - var match = classTest(cls).exec(current); - if (match) { - var after = current.slice(match.index + match[0].length); - node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); - } - }; - var addClass = CodeMirror.addClass = function(node, cls) { - var current = node.className; - if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; - }; - function joinClasses(a, b) { - var as = a.split(" "); - for (var i = 0; i < as.length; i++) - if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; - return b; - } - - // WINDOW-WIDE EVENTS - - // These must be handled carefully, because naively registering a - // handler for each editor will cause the editors to never be - // garbage collected. - - function forEachCodeMirror(f) { - if (!document.body.getElementsByClassName) return; - var byClass = document.body.getElementsByClassName("CodeMirror"); - for (var i = 0; i < byClass.length; i++) { - var cm = byClass[i].CodeMirror; - if (cm) f(cm); - } - } - - var globalsRegistered = false; - function ensureGlobalHandlers() { - if (globalsRegistered) return; - registerGlobalHandlers(); - globalsRegistered = true; - } - function registerGlobalHandlers() { - // When the window resizes, we need to refresh active editors. - var resizeTimer; - on(window, "resize", function() { - if (resizeTimer == null) resizeTimer = setTimeout(function() { - resizeTimer = null; - forEachCodeMirror(onResize); - }, 100); - }); - // When the window loses focus, we want to show the editor as blurred - on(window, "blur", function() { - forEachCodeMirror(onBlur); - }); - } - - // FEATURE DETECTION - - // Detect drag-and-drop - var dragAndDrop = function() { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie && ie_version < 9) return false; - var div = elt('div'); - return "draggable" in div || "dragDrop" in div; - }(); - - var zwspSupported; - function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b"); - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); - if (measure.firstChild.offsetHeight != 0) - zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); - } - var node = zwspSupported ? elt("span", "\u200b") : - elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); - node.setAttribute("cm-text", ""); - return node; - } - - // Feature-detect IE's crummy client rect reporting for bidi text - var badBidiRects; - function hasBadBidiRects(measure) { - if (badBidiRects != null) return badBidiRects; - var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); - var r0 = range(txt, 0, 1).getBoundingClientRect(); - if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) - var r1 = range(txt, 1, 2).getBoundingClientRect(); - return badBidiRects = (r1.right - r0.right < 3); - } - - // See if "".split is the broken IE version, if so, provide an - // alternative way to split lines. - var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { - var pos = 0, result = [], l = string.length; - while (pos <= l) { - var nl = string.indexOf("\n", pos); - if (nl == -1) nl = string.length; - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); - var rt = line.indexOf("\r"); - if (rt != -1) { - result.push(line.slice(0, rt)); - pos += rt + 1; - } else { - result.push(line); - pos = nl + 1; - } - } - return result; - } : function(string){return string.split(/\r\n?|\n/);}; - - var hasSelection = window.getSelection ? function(te) { - try { return te.selectionStart != te.selectionEnd; } - catch(e) { return false; } - } : function(te) { - try {var range = te.ownerDocument.selection.createRange();} - catch(e) {} - if (!range || range.parentElement() != te) return false; - return range.compareEndPoints("StartToEnd", range) != 0; - }; - - var hasCopyEvent = (function() { - var e = elt("div"); - if ("oncopy" in e) return true; - e.setAttribute("oncopy", "return;"); - return typeof e.oncopy == "function"; - })(); - - var badZoomedRects = null; - function hasBadZoomedRects(measure) { - if (badZoomedRects != null) return badZoomedRects; - var node = removeChildrenAndAdd(measure, elt("span", "x")); - var normal = node.getBoundingClientRect(); - var fromRange = range(node, 0, 1).getBoundingClientRect(); - return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; - } - - // KEY NAMES - - var keyNames = CodeMirror.keyNames = { - 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", - 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", - 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", - 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" - }; - (function() { - // Number keys - for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); - // Alphabetic keys - for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); - // Function keys - for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; - })(); - - // BIDI HELPERS - - function iterateBidiSections(order, from, to, f) { - if (!order) return f(from, to, "ltr"); - var found = false; - for (var i = 0; i < order.length; ++i) { - var part = order[i]; - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); - found = true; - } - } - if (!found) f(from, to, "ltr"); - } - - function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } - function bidiRight(part) { return part.level % 2 ? part.from : part.to; } - - function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } - function lineRight(line) { - var order = getOrder(line); - if (!order) return line.text.length; - return bidiRight(lst(order)); - } - - function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLine(line); - if (visual != line) lineN = lineNo(visual); - var order = getOrder(visual); - var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); - return Pos(lineN, ch); - } - function lineEnd(cm, lineN) { - var merged, line = getLine(cm.doc, lineN); - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - lineN = null; - } - var order = getOrder(line); - var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); - return Pos(lineN == null ? lineNo(line) : lineN, ch); - } - function lineStartSmart(cm, pos) { - var start = lineStart(cm, pos.line); - var line = getLine(cm.doc, start.line); - var order = getOrder(line); - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(0, line.text.search(/\S/)); - var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; - return Pos(start.line, inWS ? 0 : firstNonWS); - } - return start; - } - - function compareBidiLevel(order, a, b) { - var linedir = order[0].level; - if (a == linedir) return true; - if (b == linedir) return false; - return a < b; - } - var bidiOther; - function getBidiPartAt(order, pos) { - bidiOther = null; - for (var i = 0, found; i < order.length; ++i) { - var cur = order[i]; - if (cur.from < pos && cur.to > pos) return i; - if ((cur.from == pos || cur.to == pos)) { - if (found == null) { - found = i; - } else if (compareBidiLevel(order, cur.level, order[found].level)) { - if (cur.from != cur.to) bidiOther = found; - return i; - } else { - if (cur.from != cur.to) bidiOther = i; - return found; - } - } - } - return found; - } - - function moveInLine(line, pos, dir, byUnit) { - if (!byUnit) return pos + dir; - do pos += dir; - while (pos > 0 && isExtendingChar(line.text.charAt(pos))); - return pos; - } - - // This is needed in order to move 'visually' through bi-directional - // text -- i.e., pressing left should make the cursor go left, even - // when in RTL text. The tricky part is the 'jumps', where RTL and - // LTR text touch each other. This often requires the cursor offset - // to move more than one unit, in order to visually move one unit. - function moveVisually(line, start, dir, byUnit) { - var bidi = getOrder(line); - if (!bidi) return moveLogically(line, start, dir, byUnit); - var pos = getBidiPartAt(bidi, start), part = bidi[pos]; - var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); - - for (;;) { - if (target > part.from && target < part.to) return target; - if (target == part.from || target == part.to) { - if (getBidiPartAt(bidi, target) == pos) return target; - part = bidi[pos += dir]; - return (dir > 0) == part.level % 2 ? part.to : part.from; - } else { - part = bidi[pos += dir]; - if (!part) return null; - if ((dir > 0) == part.level % 2) - target = moveInLine(line, part.to, -1, byUnit); - else - target = moveInLine(line, part.from, 1, byUnit); - } - } - } - - function moveLogically(line, start, dir, byUnit) { - var target = start + dir; - if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; - return target < 0 || target > line.text.length ? null : target; - } - - // Bidirectional ordering algorithm - // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm - // that this (partially) implements. - - // One-char codes used for character types: - // L (L): Left-to-Right - // R (R): Right-to-Left - // r (AL): Right-to-Left Arabic - // 1 (EN): European Number - // + (ES): European Number Separator - // % (ET): European Number Terminator - // n (AN): Arabic Number - // , (CS): Common Number Separator - // m (NSM): Non-Spacing Mark - // b (BN): Boundary Neutral - // s (B): Paragraph Separator - // t (S): Segment Separator - // w (WS): Whitespace - // N (ON): Other Neutrals - - // Returns null if characters are ordered as they appear - // (left-to-right), or an array of sections ({from, to, level} - // objects) in the order in which they occur visually. - var bidiOrdering = (function() { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; - // Character types for codepoints 0x600 to 0x6ff - var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; - function charType(code) { - if (code <= 0xf7) return lowTypes.charAt(code); - else if (0x590 <= code && code <= 0x5f4) return "R"; - else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); - else if (0x6ee <= code && code <= 0x8ac) return "r"; - else if (0x2000 <= code && code <= 0x200b) return "w"; - else if (code == 0x200c) return "b"; - else return "L"; - } - - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; - // Browsers seem to always treat the boundaries of block elements as being L. - var outerType = "L"; - - function BidiSpan(level, from, to) { - this.level = level; - this.from = from; this.to = to; - } - - return function(str) { - if (!bidiRE.test(str)) return false; - var len = str.length, types = []; - for (var i = 0, type; i < len; ++i) - types.push(type = charType(str.charCodeAt(i))); - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i = 0, prev = outerType; i < len; ++i) { - var type = types[i]; - if (type == "m") types[i] = prev; - else prev = type; - } - - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (type == "1" && cur == "r") types[i] = "n"; - else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } - } - - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i = 1, prev = types[0]; i < len - 1; ++i) { - var type = types[i]; - if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; - else if (type == "," && prev == types[i+1] && - (prev == "1" || prev == "n")) types[i] = prev; - prev = type; - } - - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i = 0; i < len; ++i) { - var type = types[i]; - if (type == ",") types[i] = "N"; - else if (type == "%") { - for (var end = i + 1; end < len && types[end] == "%"; ++end) {} - var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (cur == "L" && type == "1") types[i] = "L"; - else if (isStrong.test(type)) cur = type; - } - - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i = 0; i < len; ++i) { - if (isNeutral.test(types[i])) { - for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} - var before = (i ? types[i-1] : outerType) == "L"; - var after = (end < len ? types[end] : outerType) == "L"; - var replace = before || after ? "L" : "R"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m; - for (var i = 0; i < len;) { - if (countsAsLeft.test(types[i])) { - var start = i; - for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} - order.push(new BidiSpan(0, start, i)); - } else { - var pos = i, at = order.length; - for (++i; i < len && types[i] != "L"; ++i) {} - for (var j = pos; j < i;) { - if (countsAsNum.test(types[j])) { - if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); - var nstart = j; - for (++j; j < i && countsAsNum.test(types[j]); ++j) {} - order.splice(at, 0, new BidiSpan(2, nstart, j)); - pos = j; - } else ++j; - } - if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); - } - } - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift(new BidiSpan(0, 0, m[0].length)); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push(new BidiSpan(0, len - m[0].length, len)); - } - if (order[0].level == 2) - order.unshift(new BidiSpan(1, order[0].to, order[0].to)); - if (order[0].level != lst(order).level) - order.push(new BidiSpan(order[0].level, len, len)); - - return order; - }; - })(); - - // THE END - - CodeMirror.version = "5.14.2"; - - return CodeMirror; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + module.exports = mod(); + else if (typeof define == "function" && define.amd) // AMD + return define([], mod); + else // Plain browser env + (this || window).CodeMirror = mod(); +})(function() { + "use strict"; + + // BROWSER SNIFFING + + // Kludges for bugs and behavior differences that can't be feature + // detected are enabled based on userAgent etc sniffing. + var userAgent = navigator.userAgent; + var platform = navigator.platform; + + var gecko = /gecko\/\d/i.test(userAgent); + var ie_upto10 = /MSIE \d/.test(userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); + var ie = ie_upto10 || ie_11up; + var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); + var webkit = /WebKit\//.test(userAgent); + var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); + var chrome = /Chrome\//.test(userAgent); + var presto = /Opera\//.test(userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); + var phantom = /PhantomJS/.test(userAgent); + + var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); + // This is woefully incomplete. Suggestions for alternative methods welcome. + var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); + var mac = ios || /Mac/.test(platform); + var chromeOS = /\bCrOS\b/.test(userAgent); + var windows = /win/i.test(platform); + + var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); + if (presto_version) presto_version = Number(presto_version[1]); + if (presto_version && presto_version >= 15) { presto = false; webkit = true; } + // Some browsers use the wrong event properties to signal cmd/ctrl on OS X + var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); + var captureRightClick = gecko || (ie && ie_version >= 9); + + // Optimize some code when these features are not used. + var sawReadOnlySpans = false, sawCollapsedSpans = false; + + // EDITOR CONSTRUCTOR + + // A CodeMirror instance represents an editor. This is the object + // that user code is usually dealing with. + + function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); + + this.options = options = options ? copyObj(options) : {}; + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false); + setGuttersForLineNumbers(options); + + var doc = options.value; + if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator); + this.doc = doc; + + var input = new CodeMirror.inputStyles[options.inputStyle](this); + var display = this.display = new Display(place, doc, input); + display.wrapper.CodeMirror = this; + updateGutters(this); + themeChanged(this); + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap"; + if (options.autofocus && !mobile) display.input.focus(); + initScrollbars(this); + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll + selectingText: false, + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + }; + + var cm = this; + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20); + + registerEventHandlers(this); + ensureGlobalHandlers(); + + startOperation(this); + this.curOp.forceUpdate = true; + attachDoc(this, doc); + + if ((options.autofocus && !mobile) || cm.hasFocus()) + setTimeout(bind(onFocus, this), 20); + else + onBlur(this); + + for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) + optionHandlers[opt](this, options[opt], Init); + maybeUpdateLineNumberWidth(this); + if (options.finishInit) options.finishInit(this); + for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); + endOperation(this); + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + display.lineDiv.style.textRendering = "auto"; + } + + // DISPLAY CONSTRUCTOR + + // The display handles the DOM integration, both for input reading + // and content drawing. It holds references to DOM nodes and + // display-related state. + + function Display(place, doc, input) { + var d = this; + this.input = input; + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + d.scrollbarFiller.setAttribute("cm-not-content", "true"); + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + d.gutterFiller.setAttribute("cm-not-content", "true"); + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = elt("div", null, "CodeMirror-code"); + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + d.cursorDiv = elt("div", null, "CodeMirror-cursors"); + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure"); + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none"); + // Moved around its parent to cover visible view. + d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + d.sizerWidth = null; + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; + + if (place) { + if (place.appendChild) place.appendChild(d.wrapper); + else place(d.wrapper); + } + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first; + d.reportedViewFrom = d.reportedViewTo = doc.first; + // Information about the rendered lines. + d.view = []; + d.renderedView = null; + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null; + // Empty space (in pixels) above the view + d.viewOffset = 0; + d.lastWrapHeight = d.lastWrapWidth = 0; + d.updateLineNumbers = null; + + d.nativeBarWidth = d.barHeight = d.barWidth = 0; + d.scrollbarsClipped = false; + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false; + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; + + // True when shift is held down. + d.shift = false; + + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null; + + d.activeTouch = null; + + input.init(d); + } + + // STATE UPDATES + + // Used to get the editor into a consistent state again when options change. + + function loadMode(cm) { + cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); + resetModeState(cm); + } + + function resetModeState(cm) { + cm.doc.iter(function(line) { + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + }); + cm.doc.frontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) regChange(cm); + } + + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap"); + cm.display.sizer.style.minWidth = ""; + cm.display.sizerWidth = null; + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap"); + findMaxLine(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function(){updateScrollbars(cm);}, 100); + } + + // Returns a function that estimates the height of a line, to use as + // first approximation until the line becomes visible (and is thus + // properly measurable). + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function(line) { + if (lineIsHidden(cm.doc, line)) return 0; + + var widgetsHeight = 0; + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; + } + + if (wrapping) + return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; + else + return widgetsHeight + th; + }; + } + + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function(line) { + var estHeight = est(line); + if (estHeight != line.height) updateLineHeight(line, estHeight); + }); + } + + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } + + function guttersChanged(cm) { + updateGutters(cm); + regChange(cm); + setTimeout(function(){alignHorizontally(cm);}, 20); + } + + // Rebuild the gutter elements, ensure the margin to the left of the + // code matches their width. + function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters; + removeChildren(gutters); + for (var i = 0; i < specs.length; ++i) { + var gutterClass = specs[i]; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt; + gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = i ? "" : "none"; + updateGutterSpace(cm); + } + + function updateGutterSpace(cm) { + var width = cm.display.gutters.offsetWidth; + cm.display.sizer.style.marginLeft = width + "px"; + } + + // Compute the character length of a line, taking into account + // collapsed ranges (see markText) that might hide parts, and join + // other lines onto it. + function lineLength(line) { + if (line.height == 0) return 0; + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true); + cur = found.from.line; + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found = merged.find(0, true); + len -= cur.text.length - found.from.ch; + cur = found.to.line; + len += cur.text.length - found.to.ch; + } + return len; + } + + // Find the longest line in the document. + function findMaxLine(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(d.maxLine); + d.maxLineChanged = true; + doc.iter(function(line) { + var len = lineLength(line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } + + // Make sure the gutters options contains the element + // "CodeMirror-linenumbers" when the lineNumbers option is true. + function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers"); + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0); + options.gutters.splice(found, 1); + } + } + + // SCROLLBARS + + // Prepare DOM reads needed to update the scrollbars. Done in one + // shot to minimize update/measure roundtrips. + function measureForScrollbars(cm) { + var d = cm.display, gutterW = d.gutters.offsetWidth; + var docH = Math.round(cm.doc.height + paddingVert(cm.display)); + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + }; + } + + function NativeScrollbars(place, scroll, cm) { + this.cm = cm; + var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); + var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + place(vert); place(horiz); + + on(vert, "scroll", function() { + if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); + }); + on(horiz, "scroll", function() { + if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); + }); + + this.checkedZeroWidth = false; + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; + } + + NativeScrollbars.prototype = copyObj({ + update: function(measure) { + var needsH = measure.scrollWidth > measure.clientWidth + 1; + var needsV = measure.scrollHeight > measure.clientHeight + 1; + var sWidth = measure.nativeBarWidth; + + if (needsV) { + this.vert.style.display = "block"; + this.vert.style.bottom = needsH ? sWidth + "px" : "0"; + var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; + } else { + this.vert.style.display = ""; + this.vert.firstChild.style.height = "0"; + } + + if (needsH) { + this.horiz.style.display = "block"; + this.horiz.style.right = needsV ? sWidth + "px" : "0"; + this.horiz.style.left = measure.barLeft + "px"; + var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); + this.horiz.firstChild.style.width = + (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; + } else { + this.horiz.style.display = ""; + this.horiz.firstChild.style.width = "0"; + } + + if (!this.checkedZeroWidth && measure.clientHeight > 0) { + if (sWidth == 0) this.zeroWidthHack(); + this.checkedZeroWidth = true; + } + + return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}; + }, + setScrollLeft: function(pos) { + if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; + if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz); + }, + setScrollTop: function(pos) { + if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; + if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert); + }, + zeroWidthHack: function() { + var w = mac && !mac_geMountainLion ? "12px" : "18px"; + this.horiz.style.height = this.vert.style.width = w; + this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; + this.disableHoriz = new Delayed; + this.disableVert = new Delayed; + }, + enableZeroWidthBar: function(bar, delay) { + bar.style.pointerEvents = "auto"; + function maybeDisable() { + // To find out whether the scrollbar is still visible, we + // check whether the element under the pixel in the bottom + // left corner of the scrollbar box is the scrollbar box + // itself (when the bar is still visible) or its filler child + // (when the bar is hidden). If it is still visible, we keep + // it enabled, if it's hidden, we disable pointer events. + var box = bar.getBoundingClientRect(); + var elt = document.elementFromPoint(box.left + 1, box.bottom - 1); + if (elt != bar) bar.style.pointerEvents = "none"; + else delay.set(1000, maybeDisable); + } + delay.set(1000, maybeDisable); + }, + clear: function() { + var parent = this.horiz.parentNode; + parent.removeChild(this.horiz); + parent.removeChild(this.vert); + } + }, NativeScrollbars.prototype); + + function NullScrollbars() {} + + NullScrollbars.prototype = copyObj({ + update: function() { return {bottom: 0, right: 0}; }, + setScrollLeft: function() {}, + setScrollTop: function() {}, + clear: function() {} + }, NullScrollbars.prototype); + + CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; + + function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear(); + if (cm.display.scrollbars.addClass) + rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } + + cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", function() { + if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0); + }); + node.setAttribute("cm-not-content", "true"); + }, function(pos, axis) { + if (axis == "horizontal") setScrollLeft(cm, pos); + else setScrollTop(cm, pos); + }, cm); + if (cm.display.scrollbars.addClass) + addClass(cm.display.wrapper, cm.display.scrollbars.addClass); + } + + function updateScrollbars(cm, measure) { + if (!measure) measure = measureForScrollbars(cm); + var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; + updateScrollbarsInner(cm, measure); + for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + updateHeightsInViewport(cm); + updateScrollbarsInner(cm, measureForScrollbars(cm)); + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; + } + } + + // Re-synchronize the fake scrollbars with the actual size of the + // content. + function updateScrollbarsInner(cm, measure) { + var d = cm.display; + var sizes = d.scrollbars.update(measure); + + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; + d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent" + + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = sizes.bottom + "px"; + d.scrollbarFiller.style.width = sizes.right + "px"; + } else d.scrollbarFiller.style.display = ""; + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = sizes.bottom + "px"; + d.gutterFiller.style.width = measure.gutterWidth + "px"; + } else d.gutterFiller.style.display = ""; + } + + // Compute the lines that are visible in a given viewport (defaults + // the the current scroll position). viewport may contain top, + // height, and ensure (see op.scrollToPos) properties. + function visibleLines(display, doc, viewport) { + var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; + top = Math.floor(top - paddingTop(display)); + var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; + if (ensureFrom < from) { + from = ensureFrom; + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); + to = ensureTo; + } + } + return {from: from, to: Math.max(to, from + 1)}; + } + + // LINE NUMBERS + + // Re-align line numbers and gutter marks to compensate for + // horizontal scrolling. + function alignHorizontally(cm) { + var display = cm.display, view = display.view; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, left = comp + "px"; + for (var i = 0; i < view.length; i++) if (!view[i].hidden) { + if (cm.options.fixedGutter && view[i].gutter) + view[i].gutter.style.left = left; + var align = view[i].alignable; + if (align) for (var j = 0; j < align.length; j++) + align[j].style.left = left; + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px"; + } + + // Used to ensure that the line number gutter is still the right + // size for the current document size. Returns true when an update + // is needed. + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false; + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; + display.lineNumWidth = display.lineNumInnerWidth + padding; + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; + display.lineGutter.style.width = display.lineNumWidth + "px"; + updateGutterSpace(cm); + return true; + } + return false; + } + + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)); + } + + // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, + // but using getBoundingClientRect to get a sub-pixel-accurate + // result. + function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; + } + + // DISPLAY DRAWING + + function DisplayUpdate(cm, viewport, force) { + var display = cm.display; + + this.viewport = viewport; + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport); + this.editorIsHidden = !display.wrapper.offsetWidth; + this.wrapperHeight = display.wrapper.clientHeight; + this.wrapperWidth = display.wrapper.clientWidth; + this.oldDisplayWidth = displayWidth(cm); + this.force = force; + this.dims = getDimensions(cm); + this.events = []; + } + + DisplayUpdate.prototype.signal = function(emitter, type) { + if (hasHandler(emitter, type)) + this.events.push(arguments); + }; + DisplayUpdate.prototype.finish = function() { + for (var i = 0; i < this.events.length; i++) + signal.apply(null, this.events[i]); + }; + + function maybeClipScrollbars(cm) { + var display = cm.display; + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; + display.heightForcer.style.height = scrollGap(cm) + "px"; + display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; + display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; + display.scrollbarsClipped = true; + } + } + + // Does the actual updating of the line display. Bails out + // (returning false) when there is nothing to be done and forced is + // false. + function updateDisplayIfNeeded(cm, update) { + var display = cm.display, doc = cm.doc; + + if (update.editorIsHidden) { + resetView(cm); + return false; + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + return false; + + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm); + update.dims = getDimensions(cm); + } + + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size; + var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, update.visible.to + cm.options.viewportMargin); + if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); + if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from); + to = visualLineEndNo(cm.doc, to); + } + + var different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; + adjustView(cm, from, to); + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px"; + + var toUpdate = countDirtyView(cm); + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + return false; + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var focused = activeElt(); + if (toUpdate > 4) display.lineDiv.style.display = "none"; + patchDisplay(cm, display.updateLineNumbers, update.dims); + if (toUpdate > 4) display.lineDiv.style.display = ""; + display.renderedView = display.view; + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); + + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv); + removeChildren(display.selectionDiv); + display.gutters.style.height = display.sizer.style.minHeight = 0; + + if (different) { + display.lastWrapHeight = update.wrapperHeight; + display.lastWrapWidth = update.wrapperWidth; + startWorker(cm, 400); + } + + display.updateLineNumbers = null; + + return true; + } + + function postUpdateDisplay(cm, update) { + var viewport = update.viewport; + + for (var first = true;; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport); + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + break; + } + if (!updateDisplayIfNeeded(cm, update)) break; + updateHeightsInViewport(cm); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + updateScrollbars(cm, barMeasure); + setDocumentHeight(cm, barMeasure); + } + + update.signal(cm, "update", cm); + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; + } + } + + function updateDisplaySimple(cm, viewport) { + var update = new DisplayUpdate(cm, viewport); + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm); + postUpdateDisplay(cm, update); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + updateScrollbars(cm, barMeasure); + setDocumentHeight(cm, barMeasure); + update.finish(); + } + } + + function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = measure.docHeight + "px"; + cm.display.heightForcer.style.top = measure.docHeight + "px"; + cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px"; + } + + // Read the actual heights of the rendered lines, and update their + // stored heights to match. + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], height; + if (cur.hidden) continue; + if (ie && ie_version < 8) { + var bot = cur.node.offsetTop + cur.node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = cur.node.getBoundingClientRect(); + height = box.bottom - box.top; + } + var diff = cur.line.height - height; + if (height < 2) height = textHeight(display); + if (diff > .001 || diff < -.001) { + updateLineHeight(cur.line, height); + updateWidgetHeight(cur.line); + if (cur.rest) for (var j = 0; j < cur.rest.length; j++) + updateWidgetHeight(cur.rest[j]); + } + } + } + + // Read and store the height of line widgets associated with the + // given line. + function updateWidgetHeight(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) + line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight; + } + + // Do a bulk-read of the DOM positions and sizes needed to draw the + // view, so that we don't interleave reading and writing to the DOM. + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + var gutterLeft = d.gutters.clientLeft; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; + width[cm.options.gutters[i]] = n.clientWidth; + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth}; + } + + // Sync the actual display DOM structure with display.view, removing + // nodes for lines that are no longer in view, and creating the ones + // that are not there yet, and updating the ones that are out of + // date. + function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers; + var container = display.lineDiv, cur = container.firstChild; + + function rm(node) { + var next = node.nextSibling; + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + node.style.display = "none"; + else + node.parentNode.removeChild(node); + return next; + } + + var view = display.view, lineN = display.viewFrom; + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (lineView.hidden) { + } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims); + container.insertBefore(node, cur); + } else { // Already drawn + while (cur != lineView.node) cur = rm(cur); + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber; + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; + updateLineForChanges(cm, lineView, lineN, dims); + } + if (updateNumber) { + removeChildren(lineView.lineNumber); + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); + } + cur = lineView.node.nextSibling; + } + lineN += lineView.size; + } + while (cur) cur = rm(cur); + } + + // When an aspect of a line changes, a string is added to + // lineView.changes. This updates the relevant part of the line's + // DOM structure. + function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j]; + if (type == "text") updateLineText(cm, lineView); + else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); + else if (type == "class") updateLineClasses(lineView); + else if (type == "widget") updateLineWidgets(cm, lineView, dims); + } + lineView.changes = null; + } + + // Lines with gutter elements, widgets or a background class need to + // be wrapped, and have the extra elements added to the wrapper div + function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative"); + if (lineView.text.parentNode) + lineView.text.parentNode.replaceChild(lineView.node, lineView.text); + lineView.node.appendChild(lineView.text); + if (ie && ie_version < 8) lineView.node.style.zIndex = 2; + } + return lineView.node; + } + + function updateLineBackground(lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; + if (cls) cls += " CodeMirror-linebackground"; + if (lineView.background) { + if (cls) lineView.background.className = cls; + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } + } else if (cls) { + var wrap = ensureLineWrapped(lineView); + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); + } + } + + // Wrapper around buildLineContent which will reuse the structure + // in display.externalMeasured when possible. + function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured; + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null; + lineView.measure = ext.measure; + return ext.built; + } + return buildLineContent(cm, lineView); + } + + // Redraw the line's text. Interacts with the background and text + // classes because the mode may output tokens that influence these + // classes. + function updateLineText(cm, lineView) { + var cls = lineView.text.className; + var built = getLineContent(cm, lineView); + if (lineView.text == lineView.node) lineView.node = built.pre; + lineView.text.parentNode.replaceChild(built.pre, lineView.text); + lineView.text = built.pre; + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass; + lineView.textClass = built.textClass; + updateLineClasses(lineView); + } else if (cls) { + lineView.text.className = cls; + } + } + + function updateLineClasses(lineView) { + updateLineBackground(lineView); + if (lineView.line.wrapClass) + ensureLineWrapped(lineView).className = lineView.line.wrapClass; + else if (lineView.node != lineView.text) + lineView.node.className = ""; + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; + lineView.text.className = textClass || ""; + } + + function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter); + lineView.gutter = null; + } + if (lineView.gutterBackground) { + lineView.node.removeChild(lineView.gutterBackground); + lineView.gutterBackground = null; + } + if (lineView.line.gutterClass) { + var wrap = ensureLineWrapped(lineView); + lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, + "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + + "px; width: " + dims.gutterTotalWidth + "px"); + wrap.insertBefore(lineView.gutterBackground, lineView.text); + } + var markers = lineView.line.gutterMarkers; + if (cm.options.lineNumbers || markers) { + var wrap = ensureLineWrapped(lineView); + var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"); + cm.display.input.setUneditable(gutterWrap); + wrap.insertBefore(gutterWrap, lineView.text); + if (lineView.line.gutterClass) + gutterWrap.className += " " + lineView.line.gutterClass; + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " + + cm.display.lineNumInnerWidth + "px")); + if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + + dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); + } + } + } + + function updateLineWidgets(cm, lineView, dims) { + if (lineView.alignable) lineView.alignable = null; + for (var node = lineView.node.firstChild, next; node; node = next) { + var next = node.nextSibling; + if (node.className == "CodeMirror-linewidget") + lineView.node.removeChild(node); + } + insertLineWidgets(cm, lineView, dims); + } + + // Build a line's DOM representation from scratch + function buildLineElement(cm, lineView, lineN, dims) { + var built = getLineContent(cm, lineView); + lineView.text = lineView.node = built.pre; + if (built.bgClass) lineView.bgClass = built.bgClass; + if (built.textClass) lineView.textClass = built.textClass; + + updateLineClasses(lineView); + updateLineGutter(cm, lineView, lineN, dims); + insertLineWidgets(cm, lineView, dims); + return lineView.node; + } + + // A lineView may contain multiple logical lines (when merged by + // collapsed spans). The widgets for all of them need to be drawn. + function insertLineWidgets(cm, lineView, dims) { + insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); + } + + function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { + if (!line.widgets) return; + var wrap = ensureLineWrapped(lineView); + for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); + if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true"); + positionLineWidget(widget, node, lineView, dims); + cm.display.input.setUneditable(node); + if (allowAbove && widget.above) + wrap.insertBefore(node, lineView.gutter || lineView.text); + else + wrap.appendChild(node); + signalLater(widget, "redraw"); + } + } + + function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + (lineView.alignable || (lineView.alignable = [])).push(node); + var width = dims.wrapperWidth; + node.style.left = dims.fixedPos + "px"; + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth; + node.style.paddingLeft = dims.gutterTotalWidth + "px"; + } + node.style.width = width + "px"; + } + if (widget.coverGutter) { + node.style.zIndex = 5; + node.style.position = "relative"; + if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; + } + } + + // POSITION OBJECT + + // A Pos instance represents a position within the text. + var Pos = CodeMirror.Pos = function(line, ch) { + if (!(this instanceof Pos)) return new Pos(line, ch); + this.line = line; this.ch = ch; + }; + + // Compare two positions, return 0 if they are the same, a negative + // number when a is less, and a positive number otherwise. + var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; + + function copyPos(x) {return Pos(x.line, x.ch);} + function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } + function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } + + // INPUT HANDLING + + function ensureFocus(cm) { + if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } + } + + // This will be set to an array of strings when copying, so that, + // when pasting, we know what kind of selections the copied text + // was made out of. + var lastCopied = null; + + function applyTextInput(cm, inserted, deleted, sel, origin) { + var doc = cm.doc; + cm.display.shift = false; + if (!sel) sel = doc.sel; + + var paste = cm.state.pasteIncoming || origin == "paste"; + var textLines = doc.splitLines(inserted), multiPaste = null; + // When pasing N lines into N selections, insert one line per selection + if (paste && sel.ranges.length > 1) { + if (lastCopied && lastCopied.join("\n") == inserted) { + if (sel.ranges.length % lastCopied.length == 0) { + multiPaste = []; + for (var i = 0; i < lastCopied.length; i++) + multiPaste.push(doc.splitLines(lastCopied[i])); + } + } else if (textLines.length == sel.ranges.length) { + multiPaste = map(textLines, function(l) { return [l]; }); + } + } + + // Normal behavior is to insert the new text into every selection + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + var from = range.from(), to = range.to(); + if (range.empty()) { + if (deleted && deleted > 0) // Handle deletion + from = Pos(from.line, from.ch - deleted); + else if (cm.state.overwrite && !paste) // Handle overwrite + to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); + } + var updateInput = cm.curOp.updateInput; + var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, + origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")}; + makeChange(cm.doc, changeEvent); + signalLater(cm, "inputRead", cm, changeEvent); + } + if (inserted && !paste) + triggerElectric(cm, inserted); + + ensureCursorVisible(cm); + cm.curOp.updateInput = updateInput; + cm.curOp.typing = true; + cm.state.pasteIncoming = cm.state.cutIncoming = false; + } + + function handlePaste(e, cm) { + var pasted = e.clipboardData && e.clipboardData.getData("text/plain"); + if (pasted) { + e.preventDefault(); + if (!cm.isReadOnly() && !cm.options.disableInput) + runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); }); + return true; + } + } + + function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) return; + var sel = cm.doc.sel; + + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; + var mode = cm.getModeAt(range.head); + var indented = false; + if (mode.electricChars) { + for (var j = 0; j < mode.electricChars.length; j++) + if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart"); + break; + } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + indented = indentLine(cm, range.head.line, "smart"); + } + if (indented) signalLater(cm, "electricInput", cm, range.head.line); + } + } + + function copyableRanges(cm) { + var text = [], ranges = []; + for (var i = 0; i < cm.doc.sel.ranges.length; i++) { + var line = cm.doc.sel.ranges[i].head.line; + var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; + ranges.push(lineRange); + text.push(cm.getRange(lineRange.anchor, lineRange.head)); + } + return {text: text, ranges: ranges}; + } + + function disableBrowserMagic(field) { + field.setAttribute("autocorrect", "off"); + field.setAttribute("autocapitalize", "off"); + field.setAttribute("spellcheck", "false"); + } + + // TEXTAREA INPUT STYLE + + function TextareaInput(cm) { + this.cm = cm; + // See input.poll and input.reset + this.prevInput = ""; + + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false; + // Self-resetting timeout for the poller + this.polling = new Delayed(); + // Tracks when input.reset has punted to just putting a short + // string into the textarea instead of the full selection. + this.inaccurateSelection = false; + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false; + this.composing = null; + }; + + function hiddenTextarea() { + var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); + var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) te.style.width = "1000px"; + else te.setAttribute("wrap", "off"); + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) te.style.border = "1px solid black"; + disableBrowserMagic(te); + return div; + } + + TextareaInput.prototype = copyObj({ + init: function(display) { + var input = this, cm = this.cm; + + // Wraps and hides input textarea + var div = this.wrapper = hiddenTextarea(); + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + var te = this.textarea = div.firstChild; + display.wrapper.insertBefore(div, display.wrapper.firstChild); + + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) te.style.width = "0px"; + + on(te, "input", function() { + if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; + input.poll(); + }); + + on(te, "paste", function(e) { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return + + cm.state.pasteIncoming = true; + input.fastPoll(); + }); + + function prepareCopyCut(e) { + if (signalDOMEvent(cm, e)) return + if (cm.somethingSelected()) { + lastCopied = cm.getSelections(); + if (input.inaccurateSelection) { + input.prevInput = ""; + input.inaccurateSelection = false; + te.value = lastCopied.join("\n"); + selectInput(te); + } + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = ranges.text; + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll); + } else { + input.prevInput = ""; + te.value = ranges.text.join("\n"); + selectInput(te); + } + } + if (e.type == "cut") cm.state.cutIncoming = true; + } + on(te, "cut", prepareCopyCut); + on(te, "copy", prepareCopyCut); + + on(display.scroller, "paste", function(e) { + if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return; + cm.state.pasteIncoming = true; + input.focus(); + }); + + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", function(e) { + if (!eventInWidget(display, e)) e_preventDefault(e); + }); + + on(te, "compositionstart", function() { + var start = cm.getCursor("from"); + if (input.composing) input.composing.range.clear() + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) + }; + }); + on(te, "compositionend", function() { + if (input.composing) { + input.poll(); + input.composing.range.clear(); + input.composing = null; + } + }); + }, + + prepareSelection: function() { + // Redraw the selection and/or cursor + var cm = this.cm, display = cm.display, doc = cm.doc; + var result = prepareSelection(cm); + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)); + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)); + } + + return result; + }, + + showSelection: function(drawn) { + var cm = this.cm, display = cm.display; + removeChildrenAndAdd(display.cursorDiv, drawn.cursors); + removeChildrenAndAdd(display.selectionDiv, drawn.selection); + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px"; + this.wrapper.style.left = drawn.teLeft + "px"; + } + }, + + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + reset: function(typing) { + if (this.contextMenuPending) return; + var minimal, selected, cm = this.cm, doc = cm.doc; + if (cm.somethingSelected()) { + this.prevInput = ""; + var range = doc.sel.primary(); + minimal = hasCopyEvent && + (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); + var content = minimal ? "-" : selected || cm.getSelection(); + this.textarea.value = content; + if (cm.state.focused) selectInput(this.textarea); + if (ie && ie_version >= 9) this.hasSelection = content; + } else if (!typing) { + this.prevInput = this.textarea.value = ""; + if (ie && ie_version >= 9) this.hasSelection = null; + } + this.inaccurateSelection = minimal; + }, + + getField: function() { return this.textarea; }, + + supportsTouch: function() { return false; }, + + focus: function() { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus(); } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } + }, + + blur: function() { this.textarea.blur(); }, + + resetPosition: function() { + this.wrapper.style.top = this.wrapper.style.left = 0; + }, + + receivedFocus: function() { this.slowPoll(); }, + + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + slowPoll: function() { + var input = this; + if (input.pollingFast) return; + input.polling.set(this.cm.options.pollInterval, function() { + input.poll(); + if (input.cm.state.focused) input.slowPoll(); + }); + }, + + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + fastPoll: function() { + var missed = false, input = this; + input.pollingFast = true; + function p() { + var changed = input.poll(); + if (!changed && !missed) {missed = true; input.polling.set(60, p);} + else {input.pollingFast = false; input.slowPoll();} + } + input.polling.set(20, p); + }, + + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + poll: function() { + var cm = this.cm, input = this.textarea, prevInput = this.prevInput; + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput && !this.composing) || + cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) + return false; + + var text = input.value; + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) return false; + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset(); + return false; + } + + if (cm.doc.sel == cm.display.selForContextMenu) { + var first = text.charCodeAt(0); + if (first == 0x200b && !prevInput) prevInput = "\u200b"; + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } + } + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; + + var self = this; + runInOp(cm, function() { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, self.composing ? "*compose" : null); + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; + else self.prevInput = text; + + if (self.composing) { + self.composing.range.clear(); + self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), + {className: "CodeMirror-composing"}); + } + }); + return true; + }, + + ensurePolled: function() { + if (this.pollingFast && this.poll()) this.pollingFast = false; + }, + + onKeyPress: function() { + if (ie && ie_version >= 9) this.hasSelection = null; + this.fastPoll(); + }, + + onContextMenu: function(e) { + var input = this, cm = input.cm, display = cm.display, te = input.textarea; + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || presto) return; // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu; + if (reset && cm.doc.sel.contains(pos) == -1) + operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); + + var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText; + input.wrapper.style.cssText = "position: absolute" + var wrapperBox = input.wrapper.getBoundingClientRect() + te.style.cssText = "position: absolute; width: 30px; height: 30px; top: " + (e.clientY - wrapperBox.top - 5) + + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px; z-index: 1000; background: " + + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + + "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) + display.input.focus(); + if (webkit) window.scrollTo(null, oldScrollY); + display.input.reset(); + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) te.value = input.prevInput = " "; + input.contextMenuPending = true; + display.selForContextMenu = cm.doc.sel; + clearTimeout(display.detectingSelectAll); + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + var selected = cm.somethingSelected(); + var extval = "\u200b" + (selected ? te.value : ""); + te.value = "\u21da"; // Used to catch context-menu undo + te.value = extval; + input.prevInput = selected ? "" : "\u200b"; + te.selectionStart = 1; te.selectionEnd = extval.length; + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel; + } + } + function rehide() { + input.contextMenuPending = false; + input.wrapper.style.cssText = oldWrapperCSS + te.style.cssText = oldCSS; + if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); + + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); + var i = 0, poll = function() { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") + operation(cm, commands.selectAll)(cm); + else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); + else display.input.reset(); + }; + display.detectingSelectAll = setTimeout(poll, 200); + } + } + + if (ie && ie_version >= 9) prepareSelectAllHack(); + if (captureRightClick) { + e_stop(e); + var mouseup = function() { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } + }, + + readOnlyChanged: function(val) { + if (!val) this.reset(); + }, + + setUneditable: nothing, + + needsContentAttribute: false + }, TextareaInput.prototype); + + // CONTENTEDITABLE INPUT STYLE + + function ContentEditableInput(cm) { + this.cm = cm; + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; + this.polling = new Delayed(); + this.gracePeriod = false; + } + + ContentEditableInput.prototype = copyObj({ + init: function(display) { + var input = this, cm = input.cm; + var div = input.div = display.lineDiv; + disableBrowserMagic(div); + + on(div, "paste", function(e) { + if (!signalDOMEvent(cm, e)) handlePaste(e, cm); + }) + + on(div, "compositionstart", function(e) { + var data = e.data; + input.composing = {sel: cm.doc.sel, data: data, startData: data}; + if (!data) return; + var prim = cm.doc.sel.primary(); + var line = cm.getLine(prim.head.line); + var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); + if (found > -1 && found <= prim.head.ch) + input.composing.sel = simpleSelection(Pos(prim.head.line, found), + Pos(prim.head.line, found + data.length)); + }); + on(div, "compositionupdate", function(e) { + input.composing.data = e.data; + }); + on(div, "compositionend", function(e) { + var ours = input.composing; + if (!ours) return; + if (e.data != ours.startData && !/\u200b/.test(e.data)) + ours.data = e.data; + // Need a small delay to prevent other code (input event, + // selection polling) from doing damage when fired right after + // compositionend. + setTimeout(function() { + if (!ours.handled) + input.applyComposition(ours); + if (input.composing == ours) + input.composing = null; + }, 50); + }); + + on(div, "touchstart", function() { + input.forceCompositionEnd(); + }); + + on(div, "input", function() { + if (input.composing) return; + if (cm.isReadOnly() || !input.pollContent()) + runInOp(input.cm, function() {regChange(cm);}); + }); + + function onCopyCut(e) { + if (signalDOMEvent(cm, e)) return + if (cm.somethingSelected()) { + lastCopied = cm.getSelections(); + if (e.type == "cut") cm.replaceSelection("", null, "cut"); + } else if (!cm.options.lineWiseCopyCut) { + return; + } else { + var ranges = copyableRanges(cm); + lastCopied = ranges.text; + if (e.type == "cut") { + cm.operation(function() { + cm.setSelections(ranges.ranges, 0, sel_dontScroll); + cm.replaceSelection("", null, "cut"); + }); + } + } + // iOS exposes the clipboard API, but seems to discard content inserted into it + if (e.clipboardData && !ios) { + e.preventDefault(); + e.clipboardData.clearData(); + e.clipboardData.setData("text/plain", lastCopied.join("\n")); + } else { + // Old-fashioned briefly-focus-a-textarea hack + var kludge = hiddenTextarea(), te = kludge.firstChild; + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); + te.value = lastCopied.join("\n"); + var hadFocus = document.activeElement; + selectInput(te); + setTimeout(function() { + cm.display.lineSpace.removeChild(kludge); + hadFocus.focus(); + }, 50); + } + } + on(div, "copy", onCopyCut); + on(div, "cut", onCopyCut); + }, + + prepareSelection: function() { + var result = prepareSelection(this.cm, false); + result.focus = this.cm.state.focused; + return result; + }, + + showSelection: function(info) { + if (!info || !this.cm.display.view.length) return; + if (info.focus) this.showPrimarySelection(); + this.showMultipleSelections(info); + }, + + showPrimarySelection: function() { + var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); + var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); + var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && + cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) + return; + + var start = posToDOM(this.cm, prim.from()); + var end = posToDOM(this.cm, prim.to()); + if (!start && !end) return; + + var view = this.cm.display.view; + var old = sel.rangeCount && sel.getRangeAt(0); + if (!start) { + start = {node: view[0].measure.map[2], offset: 0}; + } else if (!end) { // FIXME dangerously hacky + var measure = view[view.length - 1].measure; + var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; + end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}; + } + + try { var rng = range(start.node, start.offset, end.offset, end.node); } + catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + if (!gecko && this.cm.state.focused) { + sel.collapse(start.node, start.offset); + if (!rng.collapsed) sel.addRange(rng); + } else { + sel.removeAllRanges(); + sel.addRange(rng); + } + if (old && sel.anchorNode == null) sel.addRange(old); + else if (gecko) this.startGracePeriod(); + } + this.rememberSelection(); + }, + + startGracePeriod: function() { + var input = this; + clearTimeout(this.gracePeriod); + this.gracePeriod = setTimeout(function() { + input.gracePeriod = false; + if (input.selectionChanged()) + input.cm.operation(function() { input.cm.curOp.selectionChanged = true; }); + }, 20); + }, + + showMultipleSelections: function(info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); + }, + + rememberSelection: function() { + var sel = window.getSelection(); + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; + }, + + selectionInEditor: function() { + var sel = window.getSelection(); + if (!sel.rangeCount) return false; + var node = sel.getRangeAt(0).commonAncestorContainer; + return contains(this.div, node); + }, + + focus: function() { + if (this.cm.options.readOnly != "nocursor") this.div.focus(); + }, + blur: function() { this.div.blur(); }, + getField: function() { return this.div; }, + + supportsTouch: function() { return true; }, + + receivedFocus: function() { + var input = this; + if (this.selectionInEditor()) + this.pollSelection(); + else + runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; }); + + function poll() { + if (input.cm.state.focused) { + input.pollSelection(); + input.polling.set(input.cm.options.pollInterval, poll); + } + } + this.polling.set(this.cm.options.pollInterval, poll); + }, + + selectionChanged: function() { + var sel = window.getSelection(); + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; + }, + + pollSelection: function() { + if (!this.composing && !this.gracePeriod && this.selectionChanged()) { + var sel = window.getSelection(), cm = this.cm; + this.rememberSelection(); + var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); + var head = domToPos(cm, sel.focusNode, sel.focusOffset); + if (anchor && head) runInOp(cm, function() { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); + if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; + }); + } + }, + + pollContent: function() { + var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); + var from = sel.from(), to = sel.to(); + if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; + + var fromIndex; + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + var fromLine = lineNo(display.view[0].line); + var fromNode = display.view[0].node; + } else { + var fromLine = lineNo(display.view[fromIndex].line); + var fromNode = display.view[fromIndex - 1].node.nextSibling; + } + var toIndex = findViewIndex(cm, to.line); + if (toIndex == display.view.length - 1) { + var toLine = display.viewTo - 1; + var toNode = display.lineDiv.lastChild; + } else { + var toLine = lineNo(display.view[toIndex + 1].line) - 1; + var toNode = display.view[toIndex + 1].node.previousSibling; + } + + var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); + var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } + else break; + } + + var cutFront = 0, cutEnd = 0; + var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + ++cutFront; + var newBot = lst(newText), oldBot = lst(oldText); + var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)); + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + ++cutEnd; + + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); + newText[0] = newText[0].slice(cutFront); + + var chFrom = Pos(fromLine, cutFront); + var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input"); + return true; + } + }, + + ensurePolled: function() { + this.forceCompositionEnd(); + }, + reset: function() { + this.forceCompositionEnd(); + }, + forceCompositionEnd: function() { + if (!this.composing || this.composing.handled) return; + this.applyComposition(this.composing); + this.composing.handled = true; + this.div.blur(); + this.div.focus(); + }, + applyComposition: function(composing) { + if (this.cm.isReadOnly()) + operation(this.cm, regChange)(this.cm) + else if (composing.data && composing.data != composing.startData) + operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); + }, + + setUneditable: function(node) { + node.contentEditable = "false" + }, + + onKeyPress: function(e) { + e.preventDefault(); + if (!this.cm.isReadOnly()) + operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); + }, + + readOnlyChanged: function(val) { + this.div.contentEditable = String(val != "nocursor") + }, + + onContextMenu: nothing, + resetPosition: nothing, + + needsContentAttribute: true + }, ContentEditableInput.prototype); + + function posToDOM(cm, pos) { + var view = findViewForLine(cm, pos.line); + if (!view || view.hidden) return null; + var line = getLine(cm.doc, pos.line); + var info = mapFromLineView(view, line, pos.line); + + var order = getOrder(line), side = "left"; + if (order) { + var partPos = getBidiPartAt(order, pos.ch); + side = partPos % 2 ? "right" : "left"; + } + var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); + result.offset = result.collapse == "right" ? result.end : result.start; + return result; + } + + function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } + + function domToPos(cm, node, offset) { + var lineNode; + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset]; + if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); + node = null; offset = 0; + } else { + for (lineNode = node;; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) return null; + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; + } + } + for (var i = 0; i < cm.display.view.length; i++) { + var lineView = cm.display.view[i]; + if (lineView.node == lineNode) + return locateNodeInLineView(lineView, node, offset); + } + } + + function locateNodeInLineView(lineView, node, offset) { + var wrapper = lineView.text.firstChild, bad = false; + if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); + if (node == wrapper) { + bad = true; + node = wrapper.childNodes[offset]; + offset = 0; + if (!node) { + var line = lineView.rest ? lst(lineView.rest) : lineView.line; + return badPos(Pos(lineNo(line), line.text.length), bad); + } + } + + var textNode = node.nodeType == 3 ? node : null, topNode = node; + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild; + if (offset) offset = textNode.nodeValue.length; + } + while (topNode.parentNode != wrapper) topNode = topNode.parentNode; + var measure = lineView.measure, maps = measure.maps; + + function find(textNode, topNode, offset) { + for (var i = -1; i < (maps ? maps.length : 0); i++) { + var map = i < 0 ? measure.map : maps[i]; + for (var j = 0; j < map.length; j += 3) { + var curNode = map[j + 2]; + if (curNode == textNode || curNode == topNode) { + var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); + var ch = map[j] + offset; + if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; + return Pos(line, ch); + } + } + } + } + var found = find(textNode, topNode, offset); + if (found) return badPos(found, bad); + + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0); + if (found) + return badPos(Pos(found.line, found.ch - dist), bad); + else + dist += after.textContent.length; + } + for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1); + if (found) + return badPos(Pos(found.line, found.ch + dist), bad); + else + dist += after.textContent.length; + } + } + + function domTextBetween(cm, from, to, fromLine, toLine) { + var text = "", closing = false, lineSep = cm.doc.lineSeparator(); + function recognizeMarker(id) { return function(marker) { return marker.id == id; }; } + function walk(node) { + if (node.nodeType == 1) { + var cmText = node.getAttribute("cm-text"); + if (cmText != null) { + if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); + text += cmText; + return; + } + var markerID = node.getAttribute("cm-marker"), range; + if (markerID) { + var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); + if (found.length && (range = found[0].find())) + text += getBetween(cm.doc, range.from, range.to).join(lineSep); + return; + } + if (node.getAttribute("contenteditable") == "false") return; + for (var i = 0; i < node.childNodes.length; i++) + walk(node.childNodes[i]); + if (/^(pre|div|p)$/i.test(node.nodeName)) + closing = true; + } else if (node.nodeType == 3) { + var val = node.nodeValue; + if (!val) return; + if (closing) { + text += lineSep; + closing = false; + } + text += val; + } + } + for (;;) { + walk(from); + if (from == to) break; + from = from.nextSibling; + } + return text; + } + + CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}; + + // SELECTION / CURSOR + + // Selection objects are immutable. A new one is created every time + // the selection changes. A selection is one or more non-overlapping + // (and non-touching) ranges, sorted, and an integer that indicates + // which one is the primary selection (the one that's scrolled into + // view, that getCursor returns, etc). + function Selection(ranges, primIndex) { + this.ranges = ranges; + this.primIndex = primIndex; + } + + Selection.prototype = { + primary: function() { return this.ranges[this.primIndex]; }, + equals: function(other) { + if (other == this) return true; + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; + for (var i = 0; i < this.ranges.length; i++) { + var here = this.ranges[i], there = other.ranges[i]; + if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; + } + return true; + }, + deepCopy: function() { + for (var out = [], i = 0; i < this.ranges.length; i++) + out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); + return new Selection(out, this.primIndex); + }, + somethingSelected: function() { + for (var i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].empty()) return true; + return false; + }, + contains: function(pos, end) { + if (!end) end = pos; + for (var i = 0; i < this.ranges.length; i++) { + var range = this.ranges[i]; + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + return i; + } + return -1; + } + }; + + function Range(anchor, head) { + this.anchor = anchor; this.head = head; + } + + Range.prototype = { + from: function() { return minPos(this.anchor, this.head); }, + to: function() { return maxPos(this.anchor, this.head); }, + empty: function() { + return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; + } + }; + + // Take an unsorted, potentially overlapping set of ranges, and + // build a selection out of it. 'Consumes' ranges array (modifying + // it). + function normalizeSelection(ranges, primIndex) { + var prim = ranges[primIndex]; + ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); + primIndex = indexOf(ranges, prim); + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1]; + if (cmp(prev.to(), cur.from()) >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; + if (i <= primIndex) --primIndex; + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); + } + } + return new Selection(ranges, primIndex); + } + + function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0); + } + + // Most of the external API clips given positions to make sure they + // actually exist within the document. + function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} + function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0); + var last = doc.first + doc.size - 1; + if (pos.line > last) return Pos(last, getLine(doc, last).text.length); + return clipToLen(pos, getLine(doc, pos.line).text.length); + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) return Pos(pos.line, linelen); + else if (ch < 0) return Pos(pos.line, 0); + else return pos; + } + function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} + function clipPosArray(doc, array) { + for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); + return out; + } + + // SELECTION UPDATES + + // The 'scroll' parameter given to many of these indicated whether + // the new cursor position should be scrolled into view after + // modifying the selection. + + // If shift is held or the extend flag is set, extends a range to + // include a given position (and optionally a second position). + // Otherwise, simply returns the range between the given positions. + // Used for cursor motion and such. + function extendRange(doc, range, head, other) { + if (doc.cm && doc.cm.display.shift || doc.extend) { + var anchor = range.anchor; + if (other) { + var posBefore = cmp(head, anchor) < 0; + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head; + head = other; + } else if (posBefore != (cmp(head, other) < 0)) { + head = other; + } + } + return new Range(anchor, head); + } else { + return new Range(other || head, head); + } + } + + // Extend the primary selection range, discard the rest. + function extendSelection(doc, head, other, options) { + setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); + } + + // Extend all selections (pos is an array of selections with length + // equal the number of selections) + function extendSelections(doc, heads, options) { + for (var out = [], i = 0; i < doc.sel.ranges.length; i++) + out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); + var newSel = normalizeSelection(out, doc.sel.primIndex); + setSelection(doc, newSel, options); + } + + // Updates a single range in the selection. + function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0); + ranges[i] = range; + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); + } + + // Reset the selection to a single range. + function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options); + } + + // Give beforeSelectionChange handlers a change to influence a + // selection update. + function filterSelectionChange(doc, sel, options) { + var obj = { + ranges: sel.ranges, + update: function(ranges) { + this.ranges = []; + for (var i = 0; i < ranges.length; i++) + this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)); + }, + origin: options && options.origin + }; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); + if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); + else return sel; + } + + function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done); + if (last && last.ranges) { + done[done.length - 1] = sel; + setSelectionNoUndo(doc, sel, options); + } else { + setSelection(doc, sel, options); + } + } + + // Set a new selection. + function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options); + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); + } + + function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + sel = filterSelectionChange(doc, sel, options); + + var bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); + + if (!(options && options.scroll === false) && doc.cm) + ensureCursorVisible(doc.cm); + } + + function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) return; + + doc.sel = sel; + + if (doc.cm) { + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; + signalCursorActivity(doc.cm); + } + signalLater(doc, "cursorActivity", doc); + } + + // Verify that the selection does not partially select any atomic + // marked ranges. + function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); + } + + // Return a selection that does not partially select any atomic + // ranges. + function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; + var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); + var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) out = sel.ranges.slice(0, i); + out[i] = new Range(newAnchor, newHead); + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel; + } + + function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { + var line = getLine(doc, pos.line); + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) break; + else {--i; continue;} + } + } + if (!m.atomic) continue; + + if (oldPos) { + var near = m.find(dir < 0 ? 1 : -1), diff; + if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) + near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); + if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) + return skipAtomicInner(doc, near, pos, dir, mayClear); + } + + var far = m.find(dir < 0 ? -1 : 1); + if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) + far = movePos(doc, far, dir, far.line == pos.line ? line : null); + return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null; + } + } + return pos; + } + + // Ensure a given position is not inside an atomic range. + function skipAtomic(doc, pos, oldPos, bias, mayClear) { + var dir = bias || 1; + var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || + skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)); + if (!found) { + doc.cantEdit = true; + return Pos(doc.first, 0); + } + return found; + } + + function movePos(doc, pos, dir, line) { + if (dir < 0 && pos.ch == 0) { + if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1)); + else return null; + } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { + if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0); + else return null; + } else { + return new Pos(pos.line, pos.ch + dir); + } + } + + // SELECTION DRAWING + + function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()); + } + + function prepareSelection(cm, primary) { + var doc = cm.doc, result = {}; + var curFragment = result.cursors = document.createDocumentFragment(); + var selFragment = result.selection = document.createDocumentFragment(); + + for (var i = 0; i < doc.sel.ranges.length; i++) { + if (primary === false && i == doc.sel.primIndex) continue; + var range = doc.sel.ranges[i]; + if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue; + var collapsed = range.empty(); + if (collapsed || cm.options.showCursorWhenSelecting) + drawSelectionCursor(cm, range.head, curFragment); + if (!collapsed) + drawSelectionRange(cm, range, selFragment); + } + return result; + } + + // Draws a cursor for the given range + function drawSelectionCursor(cm, head, output) { + var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); + + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); + cursor.style.left = pos.left + "px"; + cursor.style.top = pos.top + "px"; + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); + otherCursor.style.display = ""; + otherCursor.style.left = pos.other.left + "px"; + otherCursor.style.top = pos.other.top + "px"; + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; + } + } + + // Draws the given range as a highlighted selection + function drawSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc; + var fragment = document.createDocumentFragment(); + var padding = paddingH(cm.display), leftSide = padding.left; + var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; + + function add(left, top, width, bottom) { + if (top < 0) top = 0; + top = Math.round(top); + bottom = Math.round(bottom); + fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + + "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + + "px; height: " + (bottom - top) + "px")); + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias); + } + + iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) left = leftSide; + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = leftSide; + if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); + } + if (toArg == null && to == lineLen) right = rightSide; + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + start = leftPos; + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + end = rightPos; + if (left < leftSide + 1) left = leftSide; + add(left, rightPos.top, right - left, rightPos.bottom); + }); + return {start: start, end: end}; + } + + var sFrom = range.from(), sTo = range.to(); + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch); + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); + var singleVLine = visualLine(fromLine) == visualLine(toLine); + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + add(leftSide, leftEnd.bottom, null, rightStart.top); + } + + output.appendChild(fragment); + } + + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) return; + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursorDiv.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(function() { + display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); + else if (cm.options.cursorBlinkRate < 0) + display.cursorDiv.style.visibility = "hidden"; + } + + // HIGHLIGHT WORKER + + function startWorker(cm, time) { + if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)); + } + + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.frontier < doc.first) doc.frontier = doc.first; + if (doc.frontier >= cm.display.viewTo) return; + var end = +new Date + cm.options.workTime; + var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); + var changedLines = []; + + doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { + if (doc.frontier >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength; + var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true); + line.styles = highlighted.styles; + var oldCls = line.styleClasses, newCls = highlighted.classes; + if (newCls) line.styleClasses = newCls; + else if (oldCls) line.styleClasses = null; + var ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); + for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; + if (ischange) changedLines.push(doc.frontier); + line.stateAfter = tooLong ? state : copyState(doc.mode, state); + } else { + if (line.text.length <= cm.options.maxHighlightLength) + processLine(cm, line.text, state); + line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; + } + ++doc.frontier; + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true; + } + }); + if (changedLines.length) runInOp(cm, function() { + for (var i = 0; i < changedLines.length; i++) + regLineChange(cm, changedLines[i], "text"); + }); + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc; + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); + for (var search = n; search > lim; --search) { + if (search <= doc.first) return doc.first; + var line = getLine(doc, search - 1); + if (line.stateAfter && (!precise || search <= doc.frontier)) return search; + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline; + } + + function getStateBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) return true; + var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; + if (!state) state = startState(doc.mode); + else state = copyState(doc.mode, state); + doc.iter(pos, n, function(line) { + processLine(cm, line.text, state); + var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; + line.stateAfter = save ? copyState(doc.mode, state) : null; + ++pos; + }); + if (precise) doc.frontier = pos; + return state; + } + + // POSITION MEASUREMENT + + function paddingTop(display) {return display.lineSpace.offsetTop;} + function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} + function paddingH(display) { + if (display.cachedPaddingH) return display.cachedPaddingH; + var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; + var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; + if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; + return data; + } + + function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } + function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; + } + function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; + } + + // Ensure the lineView.wrapping.heights array is populated. This is + // an array of bottom offsets for the lines that make up a drawn + // line. When lineWrapping is on, there might be more than one + // height. + function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping; + var curWidth = wrapping && displayWidth(cm); + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = []; + if (wrapping) { + lineView.measure.width = curWidth; + var rects = lineView.text.firstChild.getClientRects(); + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1]; + if (Math.abs(cur.bottom - next.bottom) > 2) + heights.push((cur.bottom + next.top) / 2 - rect.top); + } + } + heights.push(rect.bottom - rect.top); + } + } + + // Find a line map (mapping character offsets to text nodes) and a + // measurement cache for the given line number. (A line view might + // contain multiple lines when collapsed ranges are present.) + function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + return {map: lineView.measure.map, cache: lineView.measure.cache}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineView.rest[i] == line) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineNo(lineView.rest[i]) > lineN) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; + } + + // Render a line into the hidden node display.externalMeasured. Used + // when measurement is needed for a line that's not in the viewport. + function updateExternalMeasurement(cm, line) { + line = visualLine(line); + var lineN = lineNo(line); + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); + view.lineN = lineN; + var built = view.built = buildLineContent(cm, view); + view.text = built.pre; + removeChildrenAndAdd(cm.display.lineMeasure, built.pre); + return view; + } + + // Get a {top, bottom, left, right} box (in line-local coordinates) + // for a given character. + function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); + } + + // Find a line view that corresponds to the given line number. + function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + return cm.display.view[findViewIndex(cm, lineN)]; + var ext = cm.display.externalMeasured; + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + return ext; + } + + // Measurement can be split in two steps, the set-up work that + // applies to the whole line, and the measurement of the actual + // character. Functions like coordsChar, that need to do a lot of + // measurements in a row, can thus ensure that the set-up work is + // only done once. + function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line); + var view = findViewForLine(cm, lineN); + if (view && !view.text) { + view = null; + } else if (view && view.changes) { + updateLineForChanges(cm, view, lineN, getDimensions(cm)); + cm.curOp.forceUpdate = true; + } + if (!view) + view = updateExternalMeasurement(cm, line); + + var info = mapFromLineView(view, line, lineN); + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + }; + } + + // Given a prepared measurement object, measures the position of an + // actual character (or fetches it from the cache). + function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) ch = -1; + var key = ch + (bias || ""), found; + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key]; + } else { + if (!prepared.rect) + prepared.rect = prepared.view.text.getBoundingClientRect(); + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect); + prepared.hasHeights = true; + } + found = measureCharInner(cm, prepared, ch, bias); + if (!found.bogus) prepared.cache[key] = found; + } + return {left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom}; + } + + var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; + + function nodeAndOffsetInLineMap(map, ch, bias) { + var node, start, end, collapse; + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + var mStart = map[i], mEnd = map[i + 1]; + if (ch < mStart) { + start = 0; end = 1; + collapse = "left"; + } else if (ch < mEnd) { + start = ch - mStart; + end = start + 1; + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart; + start = end - 1; + if (ch >= mEnd) collapse = "right"; + } + if (start != null) { + node = map[i + 2]; + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + collapse = bias; + if (bias == "left" && start == 0) + while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2]; + collapse = "left"; + } + if (bias == "right" && start == mEnd - mStart) + while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2]; + collapse = "right"; + } + break; + } + } + return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}; + } + + function measureCharInner(cm, prepared, ch, bias) { + var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); + var node = place.node, start = place.start, end = place.end, collapse = place.collapse; + + var rect; + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { + rect = node.parentNode.getBoundingClientRect(); + } else if (ie && cm.options.lineWrapping) { + var rects = range(node, start, end).getClientRects(); + if (rects.length) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = nullRect; + } else { + rect = range(node, start, end).getBoundingClientRect() || nullRect; + } + if (rect.left || rect.right || start == 0) break; + end = start; + start = start - 1; + collapse = "right"; + } + if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) collapse = bias = "right"; + var rects; + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = node.getBoundingClientRect(); + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0]; + if (rSpan) + rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; + else + rect = nullRect; + } + + var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; + var mid = (rtop + rbot) / 2; + var heights = prepared.view.measure.heights; + for (var i = 0; i < heights.length - 1; i++) + if (mid < heights[i]) break; + var top = i ? heights[i - 1] : 0, bot = heights[i]; + var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot}; + if (!rect.left && !rect.right) result.bogus = true; + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } + + return result; + } + + // Work around problem with bounding client rects on ranges being + // returned incorrectly when zoomed on IE10 and below. + function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + return rect; + var scaleX = screen.logicalXDPI / screen.deviceXDPI; + var scaleY = screen.logicalYDPI / screen.deviceYDPI; + return {left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY}; + } + + function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {}; + lineView.measure.heights = null; + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + lineView.measure.caches[i] = {}; + } + } + + function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null; + removeChildren(cm.display.lineMeasure); + for (var i = 0; i < cm.display.view.length; i++) + clearLineMeasurementCacheFor(cm.display.view[i]); + } + + function clearCaches(cm) { + clearLineMeasurementCache(cm); + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; + cm.display.lineNumChars = null; + } + + function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } + function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } + + // Converts a {top, bottom, left, right} box from line-local + // coordinates into another coordinate system. Context may be one of + // "line", "div" (display.lineDiv), "local"/null (editor), "window", + // or "page". + function intoCoordSystem(cm, lineObj, rect, context) { + if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } + if (context == "line") return rect; + if (!context) context = "local"; + var yOff = heightAtLine(lineObj); + if (context == "local") yOff += paddingTop(cm.display); + else yOff -= cm.display.viewOffset; + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect(); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect; + } + + // Coverts a box from "div" coords to another coordinate system. + // Context may be "window", "page", "div", or "local"/null. + function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords; + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect(); + left += localBox.left; + top += localBox.top; + } + + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; + } + + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line); + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); + } + + // Returns a box for a given cursor position, which may have an + // 'other' property containing the position of the secondary cursor + // on a bidi boundary. + function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); + if (right) m.left = m.right; else m.right = m.left; + return intoCoordSystem(cm, lineObj, m, context); + } + function getBidi(ch, partPos) { + var part = order[partPos], right = part.level % 2; + if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { + part = order[--partPos]; + ch = bidiRight(part) - (part.level % 2 ? 0 : 1); + right = true; + } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { + part = order[++partPos]; + ch = bidiLeft(part) - part.level % 2; + right = false; + } + if (right && ch == part.to && ch > part.from) return get(ch - 1); + return get(ch, right); + } + var order = getOrder(lineObj), ch = pos.ch; + if (!order) return get(ch); + var partPos = getBidiPartAt(order, ch); + var val = getBidi(ch, partPos); + if (bidiOther != null) val.other = getBidi(ch, bidiOther); + return val; + } + + // Used to cheaply estimate the coordinates for a position. Used for + // intermediate scroll updates. + function estimateCoords(cm, pos) { + var left = 0, pos = clipPos(cm.doc, pos); + if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; + var lineObj = getLine(cm.doc, pos.line); + var top = heightAtLine(lineObj) + paddingTop(cm.display); + return {left: left, right: left, top: top, bottom: top + lineObj.height}; + } + + // Positions returned by coordsChar contain some extra information. + // xRel is the relative x position of the input coordinates compared + // to the found position (so xRel > 0 means the coordinates are to + // the right of the character position, for example). When outside + // is true, that means the coordinates lie outside the line's + // vertical range. + function PosWithInfo(line, ch, outside, xRel) { + var pos = Pos(line, ch); + pos.xRel = xRel; + if (outside) pos.outside = true; + return pos; + } + + // Compute the character position closest to the given coordinates. + // Input must be lineSpace-local ("div" coordinate system). + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) return PosWithInfo(doc.first, 0, true, -1); + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineN > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); + if (x < 0) x = 0; + + var lineObj = getLine(doc, lineN); + for (;;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y); + var merged = collapsedSpanAtEnd(lineObj); + var mergedPos = merged && merged.find(0, true); + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineN = lineNo(lineObj = mergedPos.to.line); + else + return found; + } + } + + function coordsCharInner(cm, lineObj, lineNo, x, y) { + var innerOff = y - heightAtLine(lineObj); + var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; + var preparedMeasure = prepareMeasureForLine(cm, lineObj); + + function getX(ch) { + var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); + wrongLine = true; + if (innerOff > sp.bottom) return sp.left - adjust; + else if (innerOff < sp.top) return sp.left + adjust; + else wrongLine = false; + return sp.left; + } + + var bidi = getOrder(lineObj), dist = lineObj.text.length; + var from = lineLeft(lineObj), to = lineRight(lineObj); + var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; + + if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); + // Do a binary search between these bounds. + for (;;) { + if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { + var ch = x < fromX || x - fromX <= toX - x ? from : to; + var xDiff = x - (ch == from ? fromX : toX); + while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; + var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, + xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); + return pos; + } + var step = Math.ceil(dist / 2), middle = from + step; + if (bidi) { + middle = from; + for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); + } + var middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} + else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} + } + } + + var measureText; + // Compute the default text height. + function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight; + if (measureText == null) { + measureText = elt("pre"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) display.cachedTextHeight = height; + removeChildren(display.measure); + return height || 1; + } + + // Compute the default character width. + function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth; + var anchor = elt("span", "xxxxxxxxxx"); + var pre = elt("pre", [anchor]); + removeChildrenAndAdd(display.measure, pre); + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; + if (width > 2) display.cachedCharWidth = width; + return width || 10; + } + + // OPERATIONS + + // Operations are used to wrap a series of changes to the editor + // state in such a way that each change won't have to update the + // cursor and display (which would be awkward, slow, and + // error-prone). Instead, display updates are batched and then all + // combined and executed at once. + + var operationGroup = null; + + var nextOpId = 0; + // Start a new operation. + function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + }; + if (operationGroup) { + operationGroup.ops.push(cm.curOp); + } else { + cm.curOp.ownsGroup = operationGroup = { + ops: [cm.curOp], + delayedCallbacks: [] + }; + } + } + + function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + var callbacks = group.delayedCallbacks, i = 0; + do { + for (; i < callbacks.length; i++) + callbacks[i].call(null); + for (var j = 0; j < group.ops.length; j++) { + var op = group.ops[j]; + if (op.cursorActivityHandlers) + while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); + } + } while (i < callbacks.length); + } + + // Finish an operation, updating the display and signalling delayed events + function endOperation(cm) { + var op = cm.curOp, group = op.ownsGroup; + if (!group) return; + + try { fireCallbacksForOps(group); } + finally { + operationGroup = null; + for (var i = 0; i < group.ops.length; i++) + group.ops[i].cm.curOp = null; + endOperations(group); + } + } + + // The DOM updates done when an operation finishes are batched so + // that the minimum number of relayouts are required. + function endOperations(group) { + var ops = group.ops; + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R1(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W1(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_R2(ops[i]); + for (var i = 0; i < ops.length; i++) // Write DOM (maybe) + endOperation_W2(ops[i]); + for (var i = 0; i < ops.length; i++) // Read DOM + endOperation_finish(ops[i]); + } + + function endOperation_R1(op) { + var cm = op.cm, display = cm.display; + maybeClipScrollbars(cm); + if (op.updateMaxLine) findMaxLine(cm); + + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping; + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); + } + + function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); + } + + function endOperation_R2(op) { + var cm = op.cm, display = cm.display; + if (op.updatedDisplay) updateHeightsInViewport(cm); + + op.barMeasure = measureForScrollbars(cm); + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; + cm.display.sizerWidth = op.adjustWidthTo; + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); + } + + if (op.updatedDisplay || op.selectionChanged) + op.preparedSelection = display.input.prepareSelection(); + } + + function endOperation_W2(op) { + var cm = op.cm; + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; + if (op.maxScrollLeft < cm.doc.scrollLeft) + setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); + cm.display.maxLineChanged = false; + } + + if (op.preparedSelection) + cm.display.input.showSelection(op.preparedSelection); + if (op.updatedDisplay || op.startHeight != cm.doc.height) + updateScrollbars(cm, op.barMeasure); + if (op.updatedDisplay) + setDocumentHeight(cm, op.barMeasure); + + if (op.selectionChanged) restartBlink(cm); + + if (cm.state.focused && op.updateInput) + cm.display.input.reset(op.typing); + if (op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus())) + ensureFocus(op.cm); + } + + function endOperation_finish(op) { + var cm = op.cm, display = cm.display, doc = cm.doc; + + if (op.updatedDisplay) postUpdateDisplay(cm, op.update); + + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + display.wheelStartX = display.wheelStartY = null; + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { + doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); + display.scrollbars.setScrollTop(doc.scrollTop); + display.scroller.scrollTop = doc.scrollTop; + } + if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { + doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); + display.scrollbars.setScrollLeft(doc.scrollLeft); + display.scroller.scrollLeft = doc.scrollLeft; + alignHorizontally(cm); + } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); + if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); + } + + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) for (var i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide"); + if (unhidden) for (var i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); + + if (display.wrapper.offsetHeight) + doc.scrollTop = cm.display.scroller.scrollTop; + + // Fire change events, and delayed event handlers + if (op.changeObjs) + signal(cm, "changes", cm, op.changeObjs); + if (op.update) + op.update.finish(); + } + + // Run the given function in an operation + function runInOp(cm, f) { + if (cm.curOp) return f(); + startOperation(cm); + try { return f(); } + finally { endOperation(cm); } + } + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm, f) { + return function() { + if (cm.curOp) return f.apply(cm, arguments); + startOperation(cm); + try { return f.apply(cm, arguments); } + finally { endOperation(cm); } + }; + } + // Used to add methods to editor and doc instances, wrapping them in + // operations. + function methodOp(f) { + return function() { + if (this.curOp) return f.apply(this, arguments); + startOperation(this); + try { return f.apply(this, arguments); } + finally { endOperation(this); } + }; + } + function docMethodOp(f) { + return function() { + var cm = this.cm; + if (!cm || cm.curOp) return f.apply(this, arguments); + startOperation(cm); + try { return f.apply(this, arguments); } + finally { endOperation(cm); } + }; + } + + // VIEW TRACKING + + // These objects are used to represent the visible (currently drawn) + // part of the document. A LineView may correspond to multiple + // logical lines, if those are connected by collapsed ranges. + function LineView(doc, line, lineN) { + // The starting line + this.line = line; + // Continuing lines, if any + this.rest = visualLineContinued(line); + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; + this.node = this.text = null; + this.hidden = lineIsHidden(doc, line); + } + + // Create a range of LineView objects for the given lines. + function buildViewArray(cm, from, to) { + var array = [], nextPos; + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); + nextPos = pos + view.size; + array.push(view); + } + return array; + } + + // Updates the display.view data structure for a given change to the + // document. From and to are in pre-change coordinates. Lendiff is + // the amount of lines added or subtracted by the change. This is + // used for changes that span multiple lines, or change the way + // lines are divided into visual lines. regLineChange (below) + // registers single-line changes. + function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first; + if (to == null) to = cm.doc.first + cm.doc.size; + if (!lendiff) lendiff = 0; + + var display = cm.display; + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + display.updateLineNumbers = from; + + cm.curOp.viewChanged = true; + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + resetView(cm); + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm); + } else { + display.viewFrom += lendiff; + display.viewTo += lendiff; + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm); + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cut) { + display.view = display.view.slice(cut.index); + display.viewFrom = cut.lineN; + display.viewTo += lendiff; + } else { + resetView(cm); + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut = viewCuttingPoint(cm, from, from, -1); + if (cut) { + display.view = display.view.slice(0, cut.index); + display.viewTo = cut.lineN; + } else { + resetView(cm); + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1); + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)); + display.viewTo += lendiff; + } else { + resetView(cm); + } + } + + var ext = display.externalMeasured; + if (ext) { + if (to < ext.lineN) + ext.lineN += lendiff; + else if (from < ext.lineN + ext.size) + display.externalMeasured = null; + } + } + + // Register a change to a single line. Type must be one of "text", + // "gutter", "class", "widget" + function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true; + var display = cm.display, ext = cm.display.externalMeasured; + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + display.externalMeasured = null; + + if (line < display.viewFrom || line >= display.viewTo) return; + var lineView = display.view[findViewIndex(cm, line)]; + if (lineView.node == null) return; + var arr = lineView.changes || (lineView.changes = []); + if (indexOf(arr, type) == -1) arr.push(type); + } + + // Clear the view. + function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first; + cm.display.view = []; + cm.display.viewOffset = 0; + } + + // Find the view element corresponding to a given line. Return null + // when the line isn't visible. + function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) return null; + n -= cm.display.viewFrom; + if (n < 0) return null; + var view = cm.display.view; + for (var i = 0; i < view.length; i++) { + n -= view[i].size; + if (n < 0) return i; + } + } + + function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view; + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + return {index: index, lineN: newN}; + for (var i = 0, n = cm.display.viewFrom; i < index; i++) + n += view[i].size; + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) return null; + diff = (n + view[index].size) - oldN; + index++; + } else { + diff = n - oldN; + } + oldN += diff; newN += diff; + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) return null; + newN += dir * view[index - (dir < 0 ? 1 : 0)].size; + index += dir; + } + return {index: index, lineN: newN}; + } + + // Force the view to cover a given range, adding empty view element + // or clipping off existing ones as needed. + function adjustView(cm, from, to) { + var display = cm.display, view = display.view; + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to); + display.viewFrom = from; + } else { + if (display.viewFrom > from) + display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); + else if (display.viewFrom < from) + display.view = display.view.slice(findViewIndex(cm, from)); + display.viewFrom = from; + if (display.viewTo < to) + display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); + else if (display.viewTo > to) + display.view = display.view.slice(0, findViewIndex(cm, to)); + } + display.viewTo = to; + } + + // Count the number of lines in the view whose DOM representation is + // out of date (or nonexistent). + function countDirtyView(cm) { + var view = cm.display.view, dirty = 0; + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; + } + return dirty; + } + + // EVENT HANDLERS + + // Attach the necessary event handlers when initializing the editor + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + on(d.scroller, "dblclick", operation(cm, function(e) { + if (signalDOMEvent(cm, e)) return; + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; + e_preventDefault(e); + var word = cm.findWordAt(pos); + extendSelection(cm.doc, word.anchor, word.head); + })); + else + on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); + + // Used to suppress mouse event handling when a touch happens + var touchFinished, prevTouch = {end: 0}; + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000); + prevTouch = d.activeTouch; + prevTouch.end = +new Date; + } + }; + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) return false; + var touch = e.touches[0]; + return touch.radiusX <= 1 && touch.radiusY <= 1; + } + function farAway(touch, other) { + if (other.left == null) return true; + var dx = other.left - touch.left, dy = other.top - touch.top; + return dx * dx + dy * dy > 20 * 20; + } + on(d.scroller, "touchstart", function(e) { + if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) { + clearTimeout(touchFinished); + var now = +new Date; + d.activeTouch = {start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null}; + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX; + d.activeTouch.top = e.touches[0].pageY; + } + } + }); + on(d.scroller, "touchmove", function() { + if (d.activeTouch) d.activeTouch.moved = true; + }); + on(d.scroller, "touchend", function(e) { + var touch = d.activeTouch; + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + var pos = cm.coordsChar(d.activeTouch, "page"), range; + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + range = new Range(pos, pos); + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + range = cm.findWordAt(pos); + else // Triple tap + range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); + cm.setSelection(range.anchor, range.head); + cm.focus(); + e_preventDefault(e); + } + finishTouch(); + }); + on(d.scroller, "touchcancel", finishTouch); + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function() { + if (d.scroller.clientHeight) { + setScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); + on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); + + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); + + d.dragFunctions = { + enter: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);}, + over: function(e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }}, + start: function(e){onDragStart(cm, e);}, + drop: operation(cm, onDrop), + leave: function(e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); }} + }; + + var inp = d.input.getField(); + on(inp, "keyup", function(e) { onKeyUp.call(cm, e); }); + on(inp, "keydown", operation(cm, onKeyDown)); + on(inp, "keypress", operation(cm, onKeyPress)); + on(inp, "focus", bind(onFocus, cm)); + on(inp, "blur", bind(onBlur, cm)); + } + + function dragDropChanged(cm, value, old) { + var wasOn = old && old != CodeMirror.Init; + if (!value != !wasOn) { + var funcs = cm.display.dragFunctions; + var toggle = value ? on : off; + toggle(cm.display.scroller, "dragstart", funcs.start); + toggle(cm.display.scroller, "dragenter", funcs.enter); + toggle(cm.display.scroller, "dragover", funcs.over); + toggle(cm.display.scroller, "dragleave", funcs.leave); + toggle(cm.display.scroller, "drop", funcs.drop); + } + } + + // Called when the window resizes + function onResize(cm) { + var d = cm.display; + if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) + return; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + d.scrollbarsClipped = false; + cm.setSize(); + } + + // MOUSE EVENTS + + // Return true when the given mouse event happened in a widget + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + return true; + } + } + + // Given a mouse event, find the corresponding position. If liberal + // is false, it checks whether a gutter or scrollbar was clicked, + // and returns null if it was. forRect is used by rectangular + // selections, and tries to estimate a character position even for + // coordinates beyond the right of the text. + function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display; + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; + + var x, y, space = display.lineSpace.getBoundingClientRect(); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top; } + catch (e) { return null; } + var coords = coordsChar(cm, x, y), line; + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); + } + return coords; + } + + // A mouse down can be a single click, double click, triple click, + // start of selection drag, start of text drag, new cursor + // (ctrl-click), rectangle drag (alt-drag), or xwin + // middle-click-paste. Or it might be a click on something we should + // not interfere with, such as a scrollbar or widget. + function onMouseDown(e) { + var cm = this, display = cm.display; + if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return; + display.shift = e.shiftKey; + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false; + setTimeout(function(){display.scroller.draggable = true;}, 100); + } + return; + } + if (clickInGutter(cm, e)) return; + var start = posFromMouse(cm, e); + window.focus(); + + switch (e_button(e)) { + case 1: + // #3261: make sure, that we're not starting a second selection + if (cm.state.selectingText) + cm.state.selectingText(e); + else if (start) + leftButtonDown(cm, e, start); + else if (e_target(e) == display.scroller) + e_preventDefault(e); + break; + case 2: + if (webkit) cm.state.lastMiddleDown = +new Date; + if (start) extendSelection(cm.doc, start); + setTimeout(function() {display.input.focus();}, 20); + e_preventDefault(e); + break; + case 3: + if (captureRightClick) onContextMenu(cm, e); + else delayBlurEvent(cm); + break; + } + } + + var lastClick, lastDoubleClick; + function leftButtonDown(cm, e, start) { + if (ie) setTimeout(bind(ensureFocus, cm), 0); + else cm.curOp.focus = activeElt(); + + var now = +new Date, type; + if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { + type = "triple"; + } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { + type = "double"; + lastDoubleClick = {time: now, pos: start}; + } else { + type = "single"; + lastClick = {time: now, pos: start}; + } + + var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; + if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && + type == "single" && (contained = sel.contains(start)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && + (cmp(contained.to(), start) > 0 || start.xRel < 0)) + leftButtonStartDrag(cm, e, start, modifier); + else + leftButtonSelect(cm, e, start, type, modifier); + } + + // Start a text drag. When it ends, see if any dragging actually + // happen, and treat as a click if it didn't. + function leftButtonStartDrag(cm, e, start, modifier) { + var display = cm.display, startTime = +new Date; + var dragEnd = operation(cm, function(e2) { + if (webkit) display.scroller.draggable = false; + cm.state.draggingText = false; + off(document, "mouseup", dragEnd); + off(display.scroller, "drop", dragEnd); + if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { + e_preventDefault(e2); + if (!modifier && +new Date - 200 < startTime) + extendSelection(cm.doc, start); + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if (webkit || ie && ie_version == 9) + setTimeout(function() {document.body.focus(); display.input.focus();}, 20); + else + display.input.focus(); + } + }); + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true; + cm.state.draggingText = dragEnd; + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop(); + on(document, "mouseup", dragEnd); + on(display.scroller, "drop", dragEnd); + } + + // Normal selection, as opposed to text dragging. + function leftButtonSelect(cm, e, start, type, addNew) { + var display = cm.display, doc = cm.doc; + e_preventDefault(e); + + var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; + if (addNew && !e.shiftKey) { + ourIndex = doc.sel.contains(start); + if (ourIndex > -1) + ourRange = ranges[ourIndex]; + else + ourRange = new Range(start, start); + } else { + ourRange = doc.sel.primary(); + ourIndex = doc.sel.primIndex; + } + + if (chromeOS ? e.shiftKey && e.metaKey : e.altKey) { + type = "rect"; + if (!addNew) ourRange = new Range(start, start); + start = posFromMouse(cm, e, true, true); + ourIndex = -1; + } else if (type == "double") { + var word = cm.findWordAt(start); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, word.anchor, word.head); + else + ourRange = word; + } else if (type == "triple") { + var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, line.anchor, line.head); + else + ourRange = line; + } else { + ourRange = extendRange(doc, ourRange, start); + } + + if (!addNew) { + ourIndex = 0; + setSelection(doc, new Selection([ourRange], 0), sel_mouse); + startSel = doc.sel; + } else if (ourIndex == -1) { + ourIndex = ranges.length; + setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}); + } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { + setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), + {scroll: false, origin: "*mouse"}); + startSel = doc.sel; + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); + } + + var lastPos = start; + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) return; + lastPos = pos; + + if (type == "rect") { + var ranges = [], tabSize = cm.options.tabSize; + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); + if (left == right) + ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); + else if (text.length > leftPos) + ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); + } + if (!ranges.length) ranges.push(new Range(start, start)); + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + {origin: "*mouse", scroll: false}); + cm.scrollIntoView(pos); + } else { + var oldRange = ourRange; + var anchor = oldRange.anchor, head = pos; + if (type != "single") { + if (type == "double") + var range = cm.findWordAt(pos); + else + var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); + if (cmp(range.anchor, anchor) > 0) { + head = range.head; + anchor = minPos(oldRange.from(), range.anchor); + } else { + head = range.anchor; + anchor = maxPos(oldRange.to(), range.head); + } + } + var ranges = startSel.ranges.slice(0); + ranges[ourIndex] = new Range(clipPos(doc, anchor), head); + setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); + } + } + + var editorSize = display.wrapper.getBoundingClientRect(); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; + + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true, type == "rect"); + if (!cur) return; + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt(); + extendTo(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) setTimeout(operation(cm, function() { + if (counter != curCount) return; + display.scroller.scrollTop += outside; + extend(e); + }), 50); + } + } + + function done(e) { + cm.state.selectingText = false; + counter = Infinity; + e_preventDefault(e); + display.input.focus(); + off(document, "mousemove", move); + off(document, "mouseup", up); + doc.history.lastSelOrigin = null; + } + + var move = operation(cm, function(e) { + if (!e_button(e)) done(e); + else extend(e); + }); + var up = operation(cm, done); + cm.state.selectingText = up; + on(document, "mousemove", move); + on(document, "mouseup", up); + } + + // Determines whether an event happened in the gutter, and fires the + // handlers for the corresponding event. + function gutterEvent(cm, e, type, prevent) { + try { var mX = e.clientX, mY = e.clientY; } + catch(e) { return false; } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; + if (prevent) e_preventDefault(e); + + var display = cm.display; + var lineBox = display.lineDiv.getBoundingClientRect(); + + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); + mY -= lineBox.top - display.viewOffset; + + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.options.gutters[i]; + signal(cm, type, cm, line, gutter, e); + return e_defaultPrevented(e); + } + } + } + + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true); + } + + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; + + function onDrop(e) { + var cm = this; + clearDragCursor(cm); + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + return; + e_preventDefault(e); + if (ie) lastDrop = +new Date; + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || cm.isReadOnly()) return; + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var loadFile = function(file, i) { + if (cm.options.allowDropFileTypes && + indexOf(cm.options.allowDropFileTypes, file.type) == -1) + return; + + var reader = new FileReader; + reader.onload = operation(cm, function() { + var content = reader.result; + if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = ""; + text[i] = content; + if (++read == n) { + pos = clipPos(cm.doc, pos); + var change = {from: pos, to: pos, + text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), + origin: "paste"}; + makeChange(cm.doc, change); + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); + } + }); + reader.readAsText(file); + }; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(function() {cm.display.input.focus();}, 20); + return; + } + try { + var text = e.dataTransfer.getData("Text"); + if (text) { + if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey)) + var selected = cm.listSelections(); + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); + if (selected) for (var i = 0; i < selected.length; ++i) + replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); + cm.replaceSelection(text, "around", "paste"); + cm.display.input.focus(); + } + } + catch(e){} + } + } + + function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; + + e.dataTransfer.setData("Text", cm.getSelection()); + e.dataTransfer.effectAllowed = "copyMove" + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (presto) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (presto) img.parentNode.removeChild(img); + } + } + + function onDragOver(cm, e) { + var pos = posFromMouse(cm, e); + if (!pos) return; + var frag = document.createDocumentFragment(); + drawSelectionCursor(cm, pos, frag); + if (!cm.display.dragCursor) { + cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); + cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); + } + removeChildrenAndAdd(cm.display.dragCursor, frag); + } + + function clearDragCursor(cm) { + if (cm.display.dragCursor) { + cm.display.lineSpace.removeChild(cm.display.dragCursor); + cm.display.dragCursor = null; + } + } + + // SCROLL EVENTS + + // Sync the scrollable area and scrollbars, ensure the viewport + // covers the visible area. + function setScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return; + cm.doc.scrollTop = val; + if (!gecko) updateDisplaySimple(cm, {top: val}); + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; + cm.display.scrollbars.setScrollTop(val); + if (gecko) updateDisplaySimple(cm); + startWorker(cm, 100); + } + // Sync scroller and scrollbar, ensure the gutter elements are + // aligned. + function setScrollLeft(cm, val, isScroller) { + if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; + cm.display.scrollbars.setScrollLeft(val); + } + + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. + + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) wheelPixelsPerUnit = -.53; + else if (gecko) wheelPixelsPerUnit = 15; + else if (chrome) wheelPixelsPerUnit = -.7; + else if (safari) wheelPixelsPerUnit = -1/3; + + var wheelEventDelta = function(e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; + else if (dy == null) dy = e.wheelDelta; + return {x: dx, y: dy}; + }; + CodeMirror.wheelEventPixels = function(e) { + var delta = wheelEventDelta(e); + delta.x *= wheelPixelsPerUnit; + delta.y *= wheelPixelsPerUnit; + return delta; + }; + + function onScrollWheel(cm, e) { + var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; + + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + var canScrollX = scroll.scrollWidth > scroll.clientWidth; + var canScrollY = scroll.scrollHeight > scroll.clientHeight; + if (!(dx && canScrollX || dy && canScrollY)) return; + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur; + break outer; + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy && canScrollY) + setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); + setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); + // Only prevent default scrolling if vertical scrolling is + // actually possible. Otherwise, it causes vertical scroll + // jitter on OSX trackpads when deltaX is small and deltaY + // is large (issue #3579) + if (!dy || (dy && canScrollY)) + e_preventDefault(e); + display.wheelStartX = null; // Abort measurement, if in progress + return; + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) top = Math.max(0, top + pixels - 50); + else bot = Math.min(cm.doc.height, bot + pixels + 50); + updateDisplaySimple(cm, {top: top, bottom: bot}); + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function() { + if (display.wheelStartX == null) return; + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) return; + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } + + // KEY EVENTS + + // Run a handler that was bound to a key. + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) return false; + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled(); + var prevShift = cm.display.shift, done = false; + try { + if (cm.isReadOnly()) cm.state.suppressEdits = true; + if (dropShift) cm.display.shift = false; + done = bound(cm) != Pass; + } finally { + cm.display.shift = prevShift; + cm.state.suppressEdits = false; + } + return done; + } + + function lookupKeyForEditor(cm, name, handle) { + for (var i = 0; i < cm.state.keyMaps.length; i++) { + var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); + if (result) return result; + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm); + } + + var stopSeq = new Delayed; + function dispatchKey(cm, name, e, handle) { + var seq = cm.state.keySeq; + if (seq) { + if (isModifierKey(name)) return "handled"; + stopSeq.set(50, function() { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null; + cm.display.input.reset(); + } + }); + name = seq + " " + name; + } + var result = lookupKeyForEditor(cm, name, handle); + + if (result == "multi") + cm.state.keySeq = name; + if (result == "handled") + signalLater(cm, "keyHandled", cm, name, e); + + if (result == "handled" || result == "multi") { + e_preventDefault(e); + restartBlink(cm); + } + + if (seq && !result && /\'$/.test(name)) { + e_preventDefault(e); + return true; + } + return !!result; + } + + // Handle a key from the keydown event. + function handleKeyBinding(cm, e) { + var name = keyName(e, true); + if (!name) return false; + + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);}) + || dispatchKey(cm, name, e, function(b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b); + }); + } else { + return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); }); + } + } + + // Handle a key from the keypress event + function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, + function(b) { return doHandleBinding(cm, b, true); }); + } + + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + cm.curOp.focus = activeElt(); + if (signalDOMEvent(cm, e)) return; + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; + var code = e.keyCode; + cm.display.shift = code == 16 || e.shiftKey; + var handled = handleKeyBinding(cm, e); + if (presto) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection("", null, "cut"); + } + + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + showCrossHair(cm); + } + + function showCrossHair(cm) { + var lineDiv = cm.display.lineDiv; + addClass(lineDiv, "CodeMirror-crosshair"); + + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair"); + off(document, "keyup", up); + off(document, "mouseover", up); + } + } + on(document, "keyup", up); + on(document, "mouseover", up); + } + + function onKeyUp(e) { + if (e.keyCode == 16) this.doc.sel.shift = false; + signalDOMEvent(this, e); + } + + function onKeyPress(e) { + var cm = this; + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; + var keyCode = e.keyCode, charCode = e.charCode; + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + if (handleCharBinding(cm, e, ch)) return; + cm.display.input.onKeyPress(e); + } + + // FOCUS/BLUR EVENTS + + function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true; + setTimeout(function() { + if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false; + onBlur(cm); + } + }, 100); + } + + function onFocus(cm) { + if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; + + if (cm.options.readOnly == "nocursor") return; + if (!cm.state.focused) { + signal(cm, "focus", cm); + cm.state.focused = true; + addClass(cm.display.wrapper, "CodeMirror-focused"); + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset(); + if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730 + } + cm.display.input.receivedFocus(); + } + restartBlink(cm); + } + function onBlur(cm) { + if (cm.state.delayingBlurEvent) return; + + if (cm.state.focused) { + signal(cm, "blur", cm); + cm.state.focused = false; + rmClass(cm.display.wrapper, "CodeMirror-focused"); + } + clearInterval(cm.display.blinker); + setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); + } + + // CONTEXT MENU HANDLING + + // To make the context menu work, we need to briefly unhide the + // textarea (making it as unobtrusive as possible) to let the + // right-click take effect on it. + function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; + if (signalDOMEvent(cm, e, "contextmenu")) return; + cm.display.input.onContextMenu(e); + } + + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false; + return gutterEvent(cm, e, "gutterContextMenu", false); + } + + // UPDATING + + // Compute the position of the end of a change (its 'to' property + // refers to the pre-change end). + var changeEnd = CodeMirror.changeEnd = function(change) { + if (!change.text) return change.to; + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); + }; + + // Adjust a position to refer to the post-change position of the + // same text, or the end of the change if the change covers it. + function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) return pos; + if (cmp(pos, change.to) <= 0) return changeEnd(change); + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; + return Pos(line, ch); + } + + function computeSelAfterChange(doc, change) { + var out = []; + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))); + } + return normalizeSelection(out, doc.sel.primIndex); + } + + function offsetPos(pos, old, nw) { + if (pos.line == old.line) + return Pos(nw.line, pos.ch - old.ch + nw.ch); + else + return Pos(nw.line + (pos.line - old.line), pos.ch); + } + + // Used by replaceSelections to allow moving the selection to the + // start or around the replaced test. Hint may be "start" or "around". + function computeReplacedSel(doc, changes, hint) { + var out = []; + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + var from = offsetPos(change.from, oldPrev, newPrev); + var to = offsetPos(changeEnd(change), oldPrev, newPrev); + oldPrev = change.to; + newPrev = to; + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; + out[i] = new Range(inv ? to : from, inv ? from : to); + } else { + out[i] = new Range(from, from); + } + } + return new Selection(out, doc.sel.primIndex); + } + + // Allow "beforeChange" event handlers to influence a change + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function() { this.canceled = true; } + }; + if (update) obj.update = function(from, to, text, origin) { + if (from) this.from = clipPos(doc, from); + if (to) this.to = clipPos(doc, to); + if (text) this.text = text; + if (origin !== undefined) this.origin = origin; + }; + signal(doc, "beforeChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); + + if (obj.canceled) return null; + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; + } + + // Apply a change to a document, and add it to the document's + // history, and propagating it to all linked documents. + function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); + if (doc.cm.state.suppressEdits) return; + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) return; + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 0; --i) + makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); + } else { + makeChangeInner(doc, change); + } + } + + function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; + var selAfter = computeSelAfterChange(doc, change); + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; + + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } + + // Revert a change stored in a document's history. + function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits) return; + + var hist = doc.history, event, selAfter = doc.sel; + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + for (var i = 0; i < source.length; i++) { + event = source[i]; + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + break; + } + if (i == source.length) return; + hist.lastOrigin = hist.lastSelOrigin = null; + + for (;;) { + event = source.pop(); + if (event.ranges) { + pushSelectionToHistory(event, dest); + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}); + return; + } + selAfter = event; + } + else break; + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = []; + pushSelectionToHistory(selAfter, dest); + dest.push({changes: antiChanges, generation: hist.generation}); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + for (var i = event.changes.length - 1; i >= 0; --i) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + source.length = 0; + return; + } + + antiChanges.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change) : lst(source); + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); + var rebased = []; + + // Propagate to the linked documents + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + } + } + + // Sub-views need their line numbers shifted when text is added + // above or below them in the parent document. + function shiftDoc(doc, distance) { + if (distance == 0) return; + doc.first += distance; + doc.sel = new Selection(map(doc.sel.ranges, function(range) { + return new Range(Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch)); + }), doc.sel.primIndex); + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance); + for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + regLineChange(doc.cm, l, "gutter"); + } + } + + // More lower-level change function, handling only a single document + // (not linked ones). + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return; + } + if (change.from.line > doc.lastLine()) return; + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin}; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin}; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) selAfter = computeSelAfterChange(doc, change); + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); + else updateDoc(doc, change, spans); + setSelectionNoUndo(doc, selAfter, sel_dontScroll); + } + + // Handle the interaction of a change to a document with the editor + // that this document is part of. + function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function(line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true; + } + }); + } + + if (doc.sel.contains(change.from, change.to) > -1) + signalCursorActivity(cm); + + updateDoc(doc, change, spans, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function(line) { + var len = lineLength(line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) cm.curOp.updateMaxLine = true; + } + + // Adjust frontier, schedule worker + doc.frontier = Math.min(doc.frontier, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + if (change.full) + regChange(cm); + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + regLineChange(cm, from.line, "text"); + else + regChange(cm, from.line, to.line + 1, lendiff); + + var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); + if (changeHandler || changesHandler) { + var obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + }; + if (changeHandler) signalLater(cm, "change", cm, obj); + if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); + } + cm.display.selForContextMenu = null; + } + + function replaceRange(doc, code, from, to, origin) { + if (!to) to = from; + if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } + if (typeof code == "string") code = doc.splitLines(code); + makeChange(doc, {from: from, to: to, text: code, origin: origin}); + } + + // SCROLLING THINGS INTO VIEW + + // If an editor sits on the top or bottom of the window, partially + // scrolled out of view, this ensures that the cursor is visible. + function maybeScrollWindow(cm, coords) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) return; + + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; + if (coords.top + box.top < 0) doScroll = true; + else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + + (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + + (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + + coords.left + "px; width: 2px;"); + cm.display.lineSpace.appendChild(scrollNode); + scrollNode.scrollIntoView(doScroll); + cm.display.lineSpace.removeChild(scrollNode); + } + } + + // Scroll a given position into view (immediately), verifying that + // it actually became visible (as line heights are accurately + // measured, the position of something may 'drift' during drawing). + function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) margin = 0; + for (var limit = 0; limit < 5; limit++) { + var changed = false, coords = cursorCoords(cm, pos); + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); + var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), + Math.min(coords.top, endCoords.top) - margin, + Math.max(coords.left, endCoords.left), + Math.max(coords.bottom, endCoords.bottom) + margin); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + setScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; + } + if (!changed) break; + } + return coords; + } + + // Scroll a given set of coordinates into view (immediately). + function scrollIntoView(cm, x1, y1, x2, y2) { + var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); + if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); + } + + // Calculate a new scroll position needed to scroll the given + // rectangle into view. Returns an object with scrollTop and + // scrollLeft properties. When these are undefined, the + // vertical/horizontal position does not need to be adjusted. + function calculateScrollPos(cm, x1, y1, x2, y2) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (y1 < 0) y1 = 0; + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; + var screen = displayHeight(cm), result = {}; + if (y2 - y1 > screen) y2 = y1 + screen; + var docBottom = cm.doc.height + paddingVert(display); + var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; + if (y1 < screentop) { + result.scrollTop = atTop ? 0 : y1; + } else if (y2 > screentop + screen) { + var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); + if (newTop != screentop) result.scrollTop = newTop; + } + + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; + var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); + var tooWide = x2 - x1 > screenw; + if (tooWide) x2 = x1 + screenw; + if (x1 < 10) + result.scrollLeft = 0; + else if (x1 < screenleft) + result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); + else if (x2 > screenw + screenleft - 3) + result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; + return result; + } + + // Store a relative adjustment to the scroll position in the current + // operation (to be applied when the operation finishes). + function addToScrollPos(cm, left, top) { + if (left != null || top != null) resolveScrollToPos(cm); + if (left != null) + cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; + if (top != null) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; + } + + // Make sure that at the end of the operation the current cursor is + // shown. + function ensureCursorVisible(cm) { + resolveScrollToPos(cm); + var cur = cm.getCursor(), from = cur, to = cur; + if (!cm.options.lineWrapping) { + from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; + to = Pos(cur.line, cur.ch + 1); + } + cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; + } + + // When an operation has its scrollToPos property set, and another + // scroll action is applied before the end of the operation, this + // 'simulates' scrolling that position into view in a cheap way, so + // that the effect of intermediate scroll commands is not ignored. + function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos; + if (range) { + cm.curOp.scrollToPos = null; + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); + var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), + Math.min(from.top, to.top) - range.margin, + Math.max(from.right, to.right), + Math.max(from.bottom, to.bottom) + range.margin); + cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + } + + // API UTILITIES + + // Indent the given line. The how parameter can be "smart", + // "add"/null, "subtract", or "prev". When aggressive is false + // (typically set to true for forced single-line indents), empty + // lines are not indented, and places where the mode returns Pass + // are left alone. + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state; + if (how == null) how = "add"; + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) how = "prev"; + else state = getStateBefore(cm, n); + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + if (line.stateAfter) line.stateAfter = null; + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0; + how = "not"; + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass || indentation > 150) { + if (!aggressive) return; + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); + else indentation = 0; + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + if (pos < indentation) indentString += spaceStr(indentation - pos); + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + line.stateAfter = null; + return true; + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos = Pos(n, curSpaceString.length); + replaceOneSelection(doc, i, new Range(pos, pos)); + break; + } + } + } + } + + // Utility for applying a change to a line by handle or number, + // returning the number and optionally registering the line as + // changed. + function changeLine(doc, handle, changeType, op) { + var no = handle, line = handle; + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); + else no = lineNo(handle); + if (no == null) return null; + if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); + return line; + } + + // Helper for deleting text near the selection(s), used to implement + // backspace, delete, and similar functionality. + function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = []; + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]); + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop(); + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from; + break; + } + } + kill.push(toKill); + } + // Next, remove those actual ranges. + runInOp(cm, function() { + for (var i = kill.length - 1; i >= 0; i--) + replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); + ensureCursorVisible(cm); + }); + } + + // Used for horizontal relative motion. Dir is -1 or 1 (left or + // right), unit can be "char", "column" (like char, but doesn't + // cross line boundaries), "word" (across next word), or "group" (to + // the start of next group of word or non-word-non-whitespace + // chars). The visually param controls whether, in right-to-left + // text, direction 1 means to move towards the next index in the + // string, or towards the character to the right of the current + // position. The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosH(doc, pos, dir, unit, visually) { + var line = pos.line, ch = pos.ch, origDir = dir; + var lineObj = getLine(doc, line); + function findNextLine() { + var l = line + dir; + if (l < doc.first || l >= doc.first + doc.size) return false + line = l; + return lineObj = getLine(doc, l); + } + function moveOnce(boundToLine) { + var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); + if (next == null) { + if (!boundToLine && findNextLine()) { + if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); + else ch = dir < 0 ? lineObj.text.length : 0; + } else return false + } else ch = next; + return true; + } + + if (unit == "char") { + moveOnce() + } else if (unit == "column") { + moveOnce(true) + } else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) break; + var cur = lineObj.text.charAt(ch) || "\n"; + var type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p"; + if (group && !first && !type) type = "s"; + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce();} + break; + } + + if (type) sawType = type; + if (dir > 0 && !moveOnce(!first)) break; + } + } + var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true); + if (!cmp(pos, result)) result.hitSide = true; + return result; + } + + // For relative vertical movement. Dir may be -1 or 1. Unit can be + // "page" or "line". The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + for (;;) { + var target = coordsChar(cm, x, y); + if (!target.outside) break; + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } + y += dir * 5; + } + return target; + } + + // EDITOR METHODS + + // The publicly visible API. Note that methodOp(f) means + // 'wrap f in an operation, performed on its `this` parameter'. + + // This is not the complete set of editor methods. Most of the + // methods defined on the Doc type are also injected into + // CodeMirror.prototype, for backwards compatibility and + // convenience. + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); this.display.input.focus();}, + + setOption: function(option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") return; + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old); + }, + + getOption: function(option) {return this.options[option];}, + getDoc: function() {return this.doc;}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1); + return true; + } + }, + + addOverlay: methodOp(function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) throw new Error("Overlays may not be stateful."); + this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: methodOp(function(spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return; + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; + else dir = dir ? "add" : "subtract"; + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); + }), + indentSelection: methodOp(function(how) { + var ranges = this.doc.sel.ranges, end = -1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) { + var from = range.from(), to = range.to(); + var start = Math.max(end, from.line); + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; + for (var j = start; j < end; ++j) + indentLine(this, j, how); + var newRanges = this.doc.sel.ranges; + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true); + end = range.head.line; + if (i == this.doc.sel.primIndex) ensureCursorVisible(this); + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + return takeToken(this, pos, precise); + }, + + getLineTokens: function(line, precise) { + return takeToken(this, Pos(line), precise, true); + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + var type; + if (ch == 0) type = styles[2]; + else for (;;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; + else if (styles[mid * 2 + 1] < ch) before = mid + 1; + else { type = styles[mid * 2 + 2]; break; } + } + var cut = type ? type.indexOf("cm-overlay ") : -1; + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); + }, + + getModeAt: function(pos) { + var mode = this.doc.mode; + if (!mode.innerMode) return mode; + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0]; + }, + + getHelpers: function(pos, type) { + var found = []; + if (!helpers.hasOwnProperty(type)) return found; + var help = helpers[type], mode = this.getModeAt(pos); + if (typeof mode[type] == "string") { + if (help[mode[type]]) found.push(help[mode[type]]); + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]]; + if (val) found.push(val); + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]); + } else if (help[mode.name]) { + found.push(help[mode.name]); + } + for (var i = 0; i < help._global.length; i++) { + var cur = help._global[i]; + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + found.push(cur.val); + } + return found; + }, + + getStateAfter: function(line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); + return getStateBefore(this, line + 1, precise); + }, + + cursorCoords: function(start, mode) { + var pos, range = this.doc.sel.primary(); + if (start == null) pos = range.head; + else if (typeof start == "object") pos = clipPos(this.doc, start); + else pos = start ? range.from() : range.to(); + return cursorCoords(this, pos, mode || "page"); + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page"); + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top); + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset); + }, + heightAtLine: function(line, mode) { + var end = false, lineObj; + if (typeof line == "number") { + var last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) line = this.doc.first; + else if (line > last) { line = last; end = true; } + lineObj = getLine(this.doc, line); + } else { + lineObj = line; + } + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + + (end ? this.doc.height - heightAtLine(lineObj) : 0); + }, + + defaultTextHeight: function() { return textHeight(this.display); }, + defaultCharWidth: function() { return charWidth(this.display); }, + + setGutterMarker: methodOp(function(line, gutterID, value) { + return changeLine(this.doc, line, "gutter", function(line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) line.gutterMarkers = null; + return true; + }); + }), + + clearGutter: methodOp(function(gutterID) { + var cm = this, doc = cm.doc, i = doc.first; + doc.iter(function(line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + line.gutterMarkers[gutterID] = null; + regLineChange(cm, i, "gutter"); + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; + } + ++i; + }); + }), + + lineInfo: function(line) { + if (typeof line == "number") { + if (!isLine(this.doc, line)) return null; + var n = line; + line = getLine(this.doc, line); + if (!line) return null; + } else { + var n = lineNo(line); + if (n == null) return null; + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets}; + }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + node.setAttribute("cm-ignore-events", "true"); + this.display.input.setUneditable(node); + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight; + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") left = 0; + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; + node.style.left = left + "px"; + } + if (scroll) + scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + return commands[cmd].call(null, this); + }, + + triggerElectric: methodOp(function(text) { triggerElectric(this, text); }), + + findPosH: function(from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) break; + } + return cur; + }, + + moveH: methodOp(function(dir, unit) { + var cm = this; + cm.extendSelectionsBy(function(range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); + else + return dir < 0 ? range.from() : range.to(); + }, sel_move); + }), + + deleteH: methodOp(function(dir, unit) { + var sel = this.doc.sel, doc = this.doc; + if (sel.somethingSelected()) + doc.replaceSelection("", null, "+delete"); + else + deleteNearSelection(this, function(range) { + var other = findPosH(doc, range.head, dir, unit, false); + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; + }); + }), + + findPosV: function(from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) x = coords.left; + else coords.left = x; + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) break; + } + return cur; + }, + + moveV: methodOp(function(dir, unit) { + var cm = this, doc = this.doc, goals = []; + var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); + doc.extendSelectionsBy(function(range) { + if (collapse) + return dir < 0 ? range.from() : range.to(); + var headPos = cursorCoords(cm, range.head, "div"); + if (range.goalColumn != null) headPos.left = range.goalColumn; + goals.push(headPos.left); + var pos = findPosV(cm, headPos, dir, unit); + if (unit == "page" && range == doc.sel.primary()) + addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); + return pos; + }, sel_move); + if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) + doc.sel.ranges[i].goalColumn = goals[i]; + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + var doc = this.doc, line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + var helper = this.getHelper(pos, "wordChars"); + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar, helper) + ? function(ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} + : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)); + }, + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) return; + if (this.state.overwrite = !this.state.overwrite) + addClass(this.display.cursorDiv, "CodeMirror-overwrite"); + else + rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); + + signal(this, "overwriteToggle", this, this.state.overwrite); + }, + hasFocus: function() { return this.display.input.getField() == activeElt(); }, + isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit); }, + + scrollTo: methodOp(function(x, y) { + if (x != null || y != null) resolveScrollToPos(this); + if (x != null) this.curOp.scrollLeft = x; + if (y != null) this.curOp.scrollTop = y; + }), + getScrollInfo: function() { + var scroller = this.display.scroller; + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this)}; + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null}; + if (margin == null) margin = this.options.cursorScrollMargin; + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null}; + } else if (range.from == null) { + range = {from: range, to: null}; + } + if (!range.to) range.to = range.from; + range.margin = margin || 0; + + if (range.from.line != null) { + resolveScrollToPos(this); + this.curOp.scrollToPos = range; + } else { + var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), + Math.min(range.from.top, range.to.top) - range.margin, + Math.max(range.from.right, range.to.right), + Math.max(range.from.bottom, range.to.bottom) + range.margin); + this.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + }), + + setSize: methodOp(function(width, height) { + var cm = this; + function interpret(val) { + return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; + } + if (width != null) cm.display.wrapper.style.width = interpret(width); + if (height != null) cm.display.wrapper.style.height = interpret(height); + if (cm.options.lineWrapping) clearLineMeasurementCache(this); + var lineNo = cm.display.viewFrom; + cm.doc.iter(lineNo, cm.display.viewTo, function(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) + if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } + ++lineNo; + }); + cm.curOp.forceUpdate = true; + signal(cm, "refresh", this); + }), + + operation: function(f){return runInOp(this, f);}, + + refresh: methodOp(function() { + var oldHeight = this.display.cachedTextHeight; + regChange(this); + this.curOp.forceUpdate = true; + clearCaches(this); + this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); + updateGutterSpace(this); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this); + signal(this, "refresh", this); + }), + + swapDoc: methodOp(function(doc) { + var old = this.doc; + old.cm = null; + attachDoc(this, doc); + clearCaches(this); + this.display.input.reset(); + this.scrollTo(doc.scrollLeft, doc.scrollTop); + this.curOp.forceScroll = true; + signalLater(this, "swapDoc", this, old); + return old; + }), + + getInputField: function(){return this.display.input.getField();}, + getWrapperElement: function(){return this.display.wrapper;}, + getScrollerElement: function(){return this.display.scroller;}, + getGutterElement: function(){return this.display.gutters;} + }; + eventMixin(CodeMirror); + + // OPTION DEFAULTS + + // The default configuration options. + var defaults = CodeMirror.defaults = {}; + // Functions to run when options are changed. + var optionHandlers = CodeMirror.optionHandlers = {}; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) optionHandlers[name] = + notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; + } + + // Passed to option handlers when there is no old value. + var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function(cm, val) { + cm.setValue(val); + }, true); + option("mode", null, function(cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function(cm) { + resetModeState(cm); + clearCaches(cm); + regChange(cm); + }, true); + option("lineSeparator", null, function(cm, val) { + cm.doc.lineSep = val; + if (!val) return; + var newBreaks = [], lineNo = cm.doc.first; + cm.doc.iter(function(line) { + for (var pos = 0;;) { + var found = line.text.indexOf(val, pos); + if (found == -1) break; + pos = found + val.length; + newBreaks.push(Pos(lineNo, found)); + } + lineNo++; + }); + for (var i = newBreaks.length - 1; i >= 0; i--) + replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) + }); + option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); + if (old != CodeMirror.Init) cm.refresh(); + }); + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); + option("electricChars", true); + option("inputStyle", mobile ? "contenteditable" : "textarea", function() { + throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME + }, true); + option("rtlMoveVisually", !windows); + option("wholeLineUpdateBefore", true); + + option("theme", "default", function(cm) { + themeChanged(cm); + guttersChanged(cm); + }, true); + option("keyMap", "default", function(cm, val, old) { + var next = getKeyMap(val); + var prev = old != CodeMirror.Init && getKeyMap(old); + if (prev && prev.detach) prev.detach(cm, next); + if (next.attach) next.attach(cm, prev || null); + }); + option("extraKeys", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("fixedGutter", true, function(cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true); + option("scrollbarStyle", "native", function(cm) { + initScrollbars(cm); + updateScrollbars(cm); + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); + }, true); + option("lineNumbers", false, function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("firstLineNumber", 1, guttersChanged, true); + option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("resetSelectionOnContextMenu", true); + option("lineWiseCopyCut", true); + + option("readOnly", false, function(cm, val) { + if (val == "nocursor") { + onBlur(cm); + cm.display.input.blur(); + cm.display.disabled = true; + } else { + cm.display.disabled = false; + } + cm.display.input.readOnlyChanged(val) + }); + option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true); + option("dragDrop", true, dragDropChanged); + option("allowDropFileTypes", null); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1, updateSelection, true); + option("singleCursorHeightPerLine", true, updateSelection, true); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true, resetModeState, true); + option("addModeClass", false, resetModeState, true); + option("pollInterval", 100); + option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); + option("historyEventDelay", 1250); + option("viewportMargin", 10, function(cm){cm.refresh();}, true); + option("maxHighlightLength", 10000, resetModeState, true); + option("moveInputWithCursor", true, function(cm, val) { + if (!val) cm.display.input.resetPosition(); + }); + + option("tabindex", null, function(cm, val) { + cm.display.input.getField().tabIndex = val || ""; + }); + option("autofocus", null); + + // MODE DEFINITION AND QUERYING + + // Known modes, by name and by MIME + var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + CodeMirror.defineMode = function(name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + if (arguments.length > 2) + mode.dependencies = Array.prototype.slice.call(arguments, 2); + modes[name] = mode; + }; + + CodeMirror.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + CodeMirror.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") found = {name: found}; + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return CodeMirror.resolveMode("application/xml"); + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; + }; + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + CodeMirror.getMode = function(options, spec) { + var spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return CodeMirror.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) modeObj.helperType = spec.helperType; + if (spec.modeProps) for (var prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop]; + + return modeObj; + }; + + // Minimal default mode. + CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeMirror.defineMIME("text/plain", "null"); + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = CodeMirror.modeExtensions = {}; + CodeMirror.extendMode = function(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + }; + + // EXTENSIONS + + CodeMirror.defineExtension = function(name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function(name, func) { + Doc.prototype[name] = func; + }; + CodeMirror.defineOption = option; + + var initHooks = []; + CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; + + var helpers = CodeMirror.helpers = {}; + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; + helpers[type][name] = value; + }; + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value); + helpers[type]._global.push({pred: predicate, val: value}); + }; + + // MODE STATE HANDLING + + // Utility functions for working with state. Exported because nested + // modes need to do this for their inner modes. + + var copyState = CodeMirror.copyState = function(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + }; + + var startState = CodeMirror.startState = function(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + }; + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + CodeMirror.innerMode = function(mode, state) { + while (mode.innerMode) { + var info = mode.innerMode(state); + if (!info || info.mode == mode) break; + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state}; + }; + + // STANDARD COMMANDS + + // Commands are parameter-less actions that can be performed on an + // editor, mostly used for keybindings. + var commands = CodeMirror.commands = { + selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, + singleSelection: function(cm) { + cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); + }, + killLine: function(cm) { + deleteNearSelection(cm, function(range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length; + if (range.head.ch == len && range.head.line < cm.lastLine()) + return {from: range.head, to: Pos(range.head.line + 1, 0)}; + else + return {from: range.head, to: Pos(range.head.line, len)}; + } else { + return {from: range.from(), to: range.to()}; + } + }); + }, + deleteLine: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; + }); + }, + delLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), to: range.from()}; + }); + }, + delWrappedLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var leftPos = cm.coordsChar({left: 0, top: top}, "div"); + return {from: leftPos, to: range.from()}; + }); + }, + delWrappedLineRight: function(cm) { + deleteNearSelection(cm, function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + return {from: range.from(), to: rightPos }; + }); + }, + undo: function(cm) {cm.undo();}, + redo: function(cm) {cm.redo();}, + undoSelection: function(cm) {cm.undoSelection();}, + redoSelection: function(cm) {cm.redoSelection();}, + goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, + goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, + goLineStart: function(cm) { + cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, + {origin: "+move", bias: 1}); + }, + goLineStartSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + return lineStartSmart(cm, range.head); + }, {origin: "+move", bias: 1}); + }, + goLineEnd: function(cm) { + cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, + {origin: "+move", bias: -1}); + }, + goLineRight: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + }, sel_move); + }, + goLineLeft: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: 0, top: top}, "div"); + }, sel_move); + }, + goLineLeftSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + var pos = cm.coordsChar({left: 0, top: top}, "div"); + if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); + return pos; + }, sel_move); + }, + goLineUp: function(cm) {cm.moveV(-1, "line");}, + goLineDown: function(cm) {cm.moveV(1, "line");}, + goPageUp: function(cm) {cm.moveV(-1, "page");}, + goPageDown: function(cm) {cm.moveV(1, "page");}, + goCharLeft: function(cm) {cm.moveH(-1, "char");}, + goCharRight: function(cm) {cm.moveH(1, "char");}, + goColumnLeft: function(cm) {cm.moveH(-1, "column");}, + goColumnRight: function(cm) {cm.moveH(1, "column");}, + goWordLeft: function(cm) {cm.moveH(-1, "word");}, + goGroupRight: function(cm) {cm.moveH(1, "group");}, + goGroupLeft: function(cm) {cm.moveH(-1, "group");}, + goWordRight: function(cm) {cm.moveH(1, "word");}, + delCharBefore: function(cm) {cm.deleteH(-1, "char");}, + delCharAfter: function(cm) {cm.deleteH(1, "char");}, + delWordBefore: function(cm) {cm.deleteH(-1, "word");}, + delWordAfter: function(cm) {cm.deleteH(1, "word");}, + delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, + delGroupAfter: function(cm) {cm.deleteH(1, "group");}, + indentAuto: function(cm) {cm.indentSelection("smart");}, + indentMore: function(cm) {cm.indentSelection("add");}, + indentLess: function(cm) {cm.indentSelection("subtract");}, + insertTab: function(cm) {cm.replaceSelection("\t");}, + insertSoftTab: function(cm) { + var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].from(); + var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); + spaces.push(new Array(tabSize - col % tabSize + 1).join(" ")); + } + cm.replaceSelections(spaces); + }, + defaultTab: function(cm) { + if (cm.somethingSelected()) cm.indentSelection("add"); + else cm.execCommand("insertTab"); + }, + transposeChars: function(cm) { + runInOp(cm, function() { + var ranges = cm.listSelections(), newSel = []; + for (var i = 0; i < ranges.length; i++) { + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; + if (line) { + if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1); + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose"); + } else if (cur.line > cm.doc.first) { + var prev = getLine(cm.doc, cur.line - 1).text; + if (prev) + cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); + } + } + newSel.push(new Range(cur, cur)); + } + cm.setSelections(newSel); + }); + }, + newlineAndIndent: function(cm) { + runInOp(cm, function() { + var len = cm.listSelections().length; + for (var i = 0; i < len; i++) { + var range = cm.listSelections()[i]; + cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input"); + cm.indentLine(range.from().line + 1, null, true); + } + ensureCursorVisible(cm); + }); + }, + toggleOverwrite: function(cm) {cm.toggleOverwrite();} + }; + + + // STANDARD KEYMAPS + + var keyMap = CodeMirror.keyMap = {}; + + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" + }; + // Note that the save and find-related commands aren't defined by + // default. User code or addons can define them. Unknown commands + // are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" + }; + // Very basic readline/emacs-style bindings, which are standard on Mac. + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + fallthrough: ["basic", "emacsy"] + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + + // KEYMAP DISPATCH + + function normalizeKeyName(name) { + var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; + var alt, ctrl, shift, cmd; + for (var i = 0; i < parts.length - 1; i++) { + var mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; + else if (/^a(lt)?$/i.test(mod)) alt = true; + else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; + else if (/^s(hift)$/i.test(mod)) shift = true; + else throw new Error("Unrecognized modifier name: " + mod); + } + if (alt) name = "Alt-" + name; + if (ctrl) name = "Ctrl-" + name; + if (cmd) name = "Cmd-" + name; + if (shift) name = "Shift-" + name; + return name; + } + + // This is a kludge to keep keymaps mostly working as raw objects + // (backwards compatibility) while at the same time support features + // like normalization and multi-stroke key bindings. It compiles a + // new normalized keymap, and then updates the old object to reflect + // this. + CodeMirror.normalizeKeyMap = function(keymap) { + var copy = {}; + for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { + var value = keymap[keyname]; + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; + if (value == "...") { delete keymap[keyname]; continue; } + + var keys = map(keyname.split(" "), normalizeKeyName); + for (var i = 0; i < keys.length; i++) { + var val, name; + if (i == keys.length - 1) { + name = keys.join(" "); + val = value; + } else { + name = keys.slice(0, i + 1).join(" "); + val = "..."; + } + var prev = copy[name]; + if (!prev) copy[name] = val; + else if (prev != val) throw new Error("Inconsistent bindings for " + name); + } + delete keymap[keyname]; + } + for (var prop in copy) keymap[prop] = copy[prop]; + return keymap; + }; + + var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) { + map = getKeyMap(map); + var found = map.call ? map.call(key, context) : map[key]; + if (found === false) return "nothing"; + if (found === "...") return "multi"; + if (found != null && handle(found)) return "handled"; + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + return lookupKey(key, map.fallthrough, handle, context); + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle, context); + if (result) return result; + } + } + }; + + // Modifier key presses don't count as 'real' key presses for the + // purpose of keymap fallthrough. + var isModifierKey = CodeMirror.isModifierKey = function(value) { + var name = typeof value == "string" ? value : keyNames[value.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; + }; + + // Look up the name of a key as indicated by an event object. + var keyName = CodeMirror.keyName = function(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) return false; + var base = keyNames[event.keyCode], name = base; + if (name == null || event.altGraphKey) return false; + if (event.altKey && base != "Alt") name = "Alt-" + name; + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; + if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; + return name; + }; + + function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val; + } + + // FROMTEXTAREA + + CodeMirror.fromTextArea = function(textarea, options) { + options = options ? copyObj(options) : {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabIndex) + options.tabindex = textarea.tabIndex; + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder; + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt(); + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() {textarea.value = cm.getValue();} + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form, realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function() { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch(e) {} + } + } + + options.finishInit = function(cm) { + cm.save = save; + cm.getTextArea = function() { return textarea; }; + cm.toTextArea = function() { + cm.toTextArea = isNaN; // Prevent this from being ran twice + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + }; + + textarea.style.display = "none"; + var cm = CodeMirror(function(node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + return cm; + }; + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = CodeMirror.StringStream = function(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + }; + + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == this.lineStart;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + indentation: function() { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } + }; + + // TEXTMARKERS + + // Created with markText and setBookmark methods. A TextMarker is a + // handle that can be used to clear or find a marked position in the + // document. Line objects hold arrays (markedSpans) containing + // {from, to, marker} object pointing to such marker objects, and + // indicating that such a marker is present on that line. Multiple + // lines may point to the same marker when it spans across lines. + // The spans will have null for their from/to properties when the + // marker continues beyond the start/end of the line. Markers have + // links back to the lines they currently touch. + + var nextMarkerId = 0; + + var TextMarker = CodeMirror.TextMarker = function(doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + this.id = ++nextMarkerId; + }; + eventMixin(TextMarker); + + // Clear the marker. + TextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) startOperation(cm); + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) signalLater(this, "clear", found.from, found.to); + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); + else if (cm) { + if (span.to != null) max = lineNo(line); + if (span.from != null) min = lineNo(line); + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)); + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { + var visual = visualLine(this.lines[i]), len = lineLength(visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } + + if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) reCheckSelection(cm.doc); + } + if (cm) signalLater(cm, "markerCleared", cm, this); + if (withOp) endOperation(cm); + if (this.parent) this.parent.clear(); + }; + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + TextMarker.prototype.find = function(side, lineObj) { + if (side == null && this.type == "bookmark") side = 1; + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from); + if (side == -1) return from; + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to); + if (side == 1) return to; + } + } + return from && {from: from, to: to}; + }; + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + TextMarker.prototype.changed = function() { + var pos = this.find(-1, true), widget = this, cm = this.doc.cm; + if (!pos || !cm) return; + runInOp(cm, function() { + var line = pos.line, lineN = lineNo(pos.line); + var view = findViewForLine(cm, lineN); + if (view) { + clearLineMeasurementCacheFor(view); + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; + } + cm.curOp.updateMaxLine = true; + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height; + widget.height = null; + var dHeight = widgetHeight(widget) - oldHeight; + if (dHeight) + updateLineHeight(line, line.height + dHeight); + } + }); + }; + + TextMarker.prototype.attachLine = function(line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); + } + this.lines.push(line); + }; + TextMarker.prototype.detachLine = function(line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + + // Collapsed markers have unique ids, in order to be able to order + // them, which is needed for uniquely determining an outer marker + // when they overlap (they may nest, but not partially overlap). + var nextMarkerId = 0; + + // Create a marker, wire it up to the right lines, and + function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) return markTextShared(doc, from, to, options, type); + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); + + var marker = new TextMarker(doc, type), diff = cmp(from, to); + if (options) copyObj(options, marker, false); + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + return marker; + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true; + marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); + if (options.insertLeft) marker.widgetNode.insertLeft = true; + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + throw new Error("Inserting collapsed marker partially overlapping an existing one"); + sawCollapsedSpans = true; + } + + if (marker.addToHistory) + addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); + + var curLine = from.line, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function(line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + updateMaxLine = true; + if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)); + ++curLine; + }); + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0); + }); + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); + + if (marker.readOnly) { + sawReadOnlySpans = true; + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory(); + } + if (marker.collapsed) { + marker.id = ++nextMarkerId; + marker.atomic = true; + } + if (cm) { + // Sync editor state + if (updateMaxLine) cm.curOp.updateMaxLine = true; + if (marker.collapsed) + regChange(cm, from.line, to.line + 1); + else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) + for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); + if (marker.atomic) reCheckSelection(cm.doc); + signalLater(cm, "markerAdded", cm, marker); + } + return marker; + } + + // SHARED TEXTMARKERS + + // A shared marker spans multiple linked documents. It is + // implemented as a meta-marker-object controlling multiple normal + // markers. + var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0; i < markers.length; ++i) + markers[i].parent = this; + }; + eventMixin(SharedTextMarker); + + SharedTextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + this.markers[i].clear(); + signalLater(this, "clear"); + }; + SharedTextMarker.prototype.find = function(side, lineObj) { + return this.primary.find(side, lineObj); + }; + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.widgetNode; + linkedDocs(doc, function(doc) { + if (widget) options.widgetNode = widget.cloneNode(true); + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return; + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary); + } + + function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), + function(m) { return m.parent; }); + } + + function copySharedMarkers(doc, markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], pos = marker.find(); + var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); + if (cmp(mFrom, mTo)) { + var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); + marker.markers.push(subMark); + subMark.parent = marker; + } + } + } + + function detachSharedMarkers(markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], linked = [marker.primary.doc];; + linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); + for (var j = 0; j < marker.markers.length; j++) { + var subMarker = marker.markers[j]; + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null; + marker.markers.splice(j--, 1); + } + } + } + } + + // TEXTMARKER SPANS + + function MarkedSpan(marker, from, to) { + this.marker = marker; + this.from = from; this.to = to; + } + + // Search an array of spans for a span matching the given marker. + function getMarkedSpanFor(spans, marker) { + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) return span; + } + } + // Remove a span from an array, returning undefined if no spans are + // left (we don't store arrays for lines without spans). + function removeMarkedSpan(spans, span) { + for (var r, i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + // Add a span to a line. + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + // Used for the algorithm that adjusts markers for a change in the + // document. These functions cut an array of spans at a given + // character position, returning an array of remaining chunks (or + // undefined if nothing remains). + function markedSpansBefore(old, startCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); + (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); + } + } + return nw; + } + function markedSpansAfter(old, endCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); + (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)); + } + } + return nw; + } + + // Given a change object, compute the new set of marker spans that + // cover the line in which the change took place. Removes spans + // entirely within the change, reconnects spans belonging to the + // same marker that appear on both sides of the change, and cuts off + // spans partially within the change. Returns an array of span + // arrays with one element for each line in (after) the change. + function stretchSpansOverChange(doc, change) { + if (change.full) return null; + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) return null; + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) span.to = startCh; + else if (sameLine) span.to = found.to == null ? null : found.to + offset; + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i = 0; i < last.length; ++i) { + var span = last[i]; + if (span.to != null) span.to += offset; + if (span.from == null) { + var found = getMarkedSpanFor(first, span.marker); + if (!found) { + span.from = offset; + if (sameLine) (first || (first = [])).push(span); + } + } else { + span.from += offset; + if (sameLine) (first || (first = [])).push(span); + } + } + } + // Make sure we didn't create any zero-length spans + if (first) first = clearEmptySpans(first); + if (last && last != first) last = clearEmptySpans(last); + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + for (var i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); + for (var i = 0; i < gap; ++i) + newMarkers.push(gapMarkers); + newMarkers.push(last); + } + return newMarkers; + } + + // Remove spans that are empty and don't have a clearWhenEmpty + // option of false. + function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + spans.splice(i--, 1); + } + if (!spans.length) return null; + return spans; + } + + // Used for un/re-doing changes from the history. Combines the + // result of computing the existing spans with the set of spans that + // existed in the history (so that deleting around a span and then + // undoing brings back the span). + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) return stretched; + if (!stretched) return old; + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans; + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old; + } + + // Used to 'clip' out readOnly ranges when making a change. + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function(line) { + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark); + } + }); + if (!markers) return null; + var parts = [{from: from, to: to}]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + newParts.push({from: p.from, to: m.from}); + if (dto > 0 || !mk.inclusiveRight && !dto) + newParts.push({from: m.to, to: p.to}); + parts.splice.apply(parts, newParts); + j += newParts.length - 1; + } + } + return parts; + } + + // Connect or disconnect spans from a line. + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line); + line.markedSpans = null; + } + function attachMarkedSpans(line, spans) { + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line); + line.markedSpans = spans; + } + + // Helpers used when computing which overlapping collapsed span + // counts as the larger one. + function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } + function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } + + // Returns a number indicating which of two overlapping collapsed + // spans is larger (and thus includes the other). Falls back to + // comparing ids when the spans cover exactly the same range. + function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length; + if (lenDiff != 0) return lenDiff; + var aPos = a.find(), bPos = b.find(); + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); + if (fromCmp) return -fromCmp; + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); + if (toCmp) return toCmp; + return b.id - a.id; + } + + // Find out whether a line ends or starts in a collapsed span. If + // so, return the marker for that span. + function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + found = sp.marker; + } + return found; + } + function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } + function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } + + // Test whether there exists a collapsed span that partially + // overlaps (covers the start or end, but not both) of a new span. + // Such overlap is not allowed. + function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo); + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (!sp.marker.collapsed) continue; + var found = sp.marker.find(0); + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; + if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) || + fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight))) + return true; + } + } + + // A visual line is a line as drawn on the screen. Folding, for + // example, can cause multiple logical lines to appear on the same + // visual line. This finds the start of the visual line that the + // given line is part of (usually that is the line itself). + function visualLine(line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + line = merged.find(-1, true).line; + return line; + } + + // Returns an array of logical lines that continue the visual line + // started by the argument, or undefined if there are no such lines. + function visualLineContinued(line) { + var merged, lines; + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + (lines || (lines = [])).push(line); + } + return lines; + } + + // Get the line number of the start of the visual line that the + // given line number is part of. + function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line); + if (line == vis) return lineN; + return lineNo(vis); + } + // Get the line number of the start of the next visual line after + // the given line. + function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) return lineN; + var line = getLine(doc, lineN), merged; + if (!lineIsHidden(doc, line)) return lineN; + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line; + return lineNo(line) + 1; + } + + // Compute whether a line is hidden. Lines count as hidden when they + // are part of a visual line that starts with another line, or when + // they are entirely covered by collapsed, non-widget span. + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if (sp.from == null) return true; + if (sp.marker.widgetNode) continue; + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true; + } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true); + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true; + for (var sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true; + } + } + + // LINE WIDGETS + + // Line widgets are block elements displayed above or below a line. + + var LineWidget = CodeMirror.LineWidget = function(doc, node, options) { + if (options) for (var opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt]; + this.doc = doc; + this.node = node; + }; + eventMixin(LineWidget); + + function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + addToScrollPos(cm, null, diff); + } + + LineWidget.prototype.clear = function() { + var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); + if (no == null || !ws) return; + for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); + if (!ws.length) line.widgets = null; + var height = widgetHeight(this); + updateLineHeight(line, Math.max(0, line.height - height)); + if (cm) runInOp(cm, function() { + adjustScrollWhenAboveVisible(cm, line, -height); + regLineChange(cm, no, "widget"); + }); + }; + LineWidget.prototype.changed = function() { + var oldH = this.height, cm = this.doc.cm, line = this.line; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) return; + updateLineHeight(line, line.height + diff); + if (cm) runInOp(cm, function() { + cm.curOp.forceUpdate = true; + adjustScrollWhenAboveVisible(cm, line, diff); + }); + }; + + function widgetHeight(widget) { + if (widget.height != null) return widget.height; + var cm = widget.doc.cm; + if (!cm) return 0; + if (!contains(document.body, widget.node)) { + var parentStyle = "position: relative;"; + if (widget.coverGutter) + parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; + if (widget.noHScroll) + parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); + } + return widget.height = widget.node.parentNode.offsetHeight; + } + + function addLineWidget(doc, handle, node, options) { + var widget = new LineWidget(doc, node, options); + var cm = doc.cm; + if (cm && widget.noHScroll) cm.display.alignWidgets = true; + changeLine(doc, handle, "widget", function(line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) widgets.push(widget); + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); + widget.line = line; + if (cm && !lineIsHidden(doc, line)) { + var aboveVisible = heightAtLine(line) < doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) addToScrollPos(cm, null, widget.height); + cm.curOp.forceUpdate = true; + } + return true; + }); + return widget; + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + eventMixin(Line); + Line.prototype.lineNo = function() { return lineNo(this); }; + + // Change the content (text, markers) of a line. Automatically + // invalidates cached information and tries to re-estimate the + // line's height. + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + if (line.order != null) line.order = null; + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) updateLineHeight(line, estHeight); + } + + // Detach a line from the document tree and its markers. + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + function extractLineClasses(type, output) { + if (type) for (;;) { + var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); + if (!lineClass) break; + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (output[prop] == null) + output[prop] = lineClass[2]; + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) + output[prop] += " " + lineClass[2]; + } + return type; + } + + function callBlankLine(mode, state) { + if (mode.blankLine) return mode.blankLine(state); + if (!mode.innerMode) return; + var inner = CodeMirror.innerMode(mode, state); + if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); + } + + function readToken(mode, stream, state, inner) { + for (var i = 0; i < 10; i++) { + if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; + var style = mode.token(stream, state); + if (stream.pos > stream.start) return style; + } + throw new Error("Mode " + mode.name + " failed to advance stream."); + } + + // Utility for getTokenAt and getLineTokens + function takeToken(cm, pos, precise, asArray) { + function getObj(copy) { + return {start: stream.start, end: stream.pos, + string: stream.current(), + type: style || null, + state: copy ? copyState(doc.mode, state) : state}; + } + + var doc = cm.doc, mode = doc.mode, style; + pos = clipPos(doc, pos); + var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); + var stream = new StringStream(line.text, cm.options.tabSize), tokens; + if (asArray) tokens = []; + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos; + style = readToken(mode, stream, state); + if (asArray) tokens.push(getObj(true)); + } + return asArray ? tokens : getObj(); + } + + // Run the given mode's parser over a line, calling f for each token. + function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize), style; + var inner = cm.options.addModeClass && [null]; + if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + if (forceToEnd) processLine(cm, text, state, stream.pos); + stream.pos = text.length; + style = null; + } else { + style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); + } + if (inner) { + var mName = inner[0].name; + if (mName) style = "m-" + (style ? mName + " " + style : mName); + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 50000); + f(curStart, curStyle); + } + curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 characters + var pos = Math.min(stream.pos, curStart + 50000); + f(pos, curStyle); + curStart = pos; + } + } + + // Compute a style array (an array starting with a mode generation + // -- for invalidation -- followed by pairs of end positions and + // style strings), which is used to highlight the tokens on the + // line. + function highlightLine(cm, line, state, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen], lineClasses = {}; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, state, function(end, style) { + st.push(end, style); + }, lineClasses, forceToEnd); + + // Run overlays, adjust style array. + for (var o = 0; o < cm.state.overlays.length; ++o) { + var overlay = cm.state.overlays[o], i = 1, at = 0; + runMode(cm, line.text, overlay.mode, true, function(end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + st.splice(i, 1, end, st[i+1], i_end); + i += 2; + at = Math.min(end, i_end); + } + if (!style) return; + if (overlay.opaque) { + st.splice(start, i - start, end, "cm-overlay " + style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start+1]; + st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; + } + } + }, lineClasses); + } + + return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; + } + + function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + var state = getStateBefore(cm, lineNo(line)); + var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state); + line.stateAfter = state; + line.styles = result.styles; + if (result.classes) line.styleClasses = result.classes; + else if (line.styleClasses) line.styleClasses = null; + if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; + } + return line.styles; + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. Used for lines that + // aren't currently visible. + function processLine(cm, text, state, startAt) { + var mode = cm.doc.mode; + var stream = new StringStream(text, cm.options.tabSize); + stream.start = stream.pos = startAt || 0; + if (text == "") callBlankLine(mode, state); + while (!stream.eol()) { + readToken(mode, stream, state); + stream.start = stream.pos; + } + } + + // Convert a style as returned by a mode (either null, or a string + // containing one or more styles) to a CSS style. This is cached, + // and also looks for line-wide styles. + var styleToClassCache = {}, styleToClassCacheWithMode = {}; + function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) return null; + var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")); + } + + // Render the DOM representation of the text of a line. Also builds + // up a 'line map', which points at the DOM nodes that represent + // specific stretches of text, and is used by the measuring code. + // The returned object contains the DOM node, this map, and + // information about line-wide styles that were set by the mode. + function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); + var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}; + lineView.measure = {}; + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order; + builder.pos = 0; + builder.addToken = buildToken; + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) + builder.addToken = buildTokenBadBidi(builder.addToken, order); + builder.map = []; + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); + if (line.styleClasses) { + if (line.styleClasses.bgClass) + builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); + if (line.styleClasses.textClass) + builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map; + lineView.measure.cache = {}; + } else { + (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); + (lineView.measure.caches || (lineView.measure.caches = [])).push({}); + } + } + + // See issue #2901 + if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className)) + builder.content.className = "cm-tab-wrap-hack"; + + signal(cm, "renderLine", cm, lineView.line, builder.pre); + if (builder.pre.className) + builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); + + return builder; + } + + function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + ch.charCodeAt(0).toString(16); + token.setAttribute("aria-label", token.title); + return token; + } + + // Build up the DOM representation for a single token, and add it to + // the line map. Takes care to render special characters separately. + function buildToken(builder, text, style, startStyle, endStyle, title, css) { + if (!text) return; + var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text; + var special = builder.cm.state.specialChars, mustWrap = false; + if (!special.test(text)) { + builder.col += text.length; + var content = document.createTextNode(displayText); + builder.map.push(builder.pos, builder.pos + text.length, content); + if (ie && ie_version < 9) mustWrap = true; + builder.pos += text.length; + } else { + var content = document.createDocumentFragment(), pos = 0; + while (true) { + special.lastIndex = pos; + var m = special.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.map.push(builder.pos, builder.pos + skipped, txt); + builder.col += skipped; + builder.pos += skipped; + } + if (!m) break; + pos += skipped + 1; + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + txt.setAttribute("role", "presentation"); + txt.setAttribute("cm-text", "\t"); + builder.col += tabWidth; + } else if (m[0] == "\r" || m[0] == "\n") { + var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); + txt.setAttribute("cm-text", m[0]); + builder.col += 1; + } else { + var txt = builder.cm.options.specialCharPlaceholder(m[0]); + txt.setAttribute("cm-text", m[0]); + if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.col += 1; + } + builder.map.push(builder.pos, builder.pos + 1, txt); + builder.pos++; + } + } + if (style || startStyle || endStyle || mustWrap || css) { + var fullStyle = style || ""; + if (startStyle) fullStyle += startStyle; + if (endStyle) fullStyle += endStyle; + var token = elt("span", [content], fullStyle, css); + if (title) token.title = title; + return builder.content.appendChild(token); + } + builder.content.appendChild(content); + } + + function splitSpaces(old) { + var out = " "; + for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; + out += " "; + return out; + } + + // Work around nonsense dimensions being reported for stretches of + // right-to-left text. + function buildTokenBadBidi(inner, order) { + return function(builder, text, style, startStyle, endStyle, title, css) { + style = style ? style + " cm-force-border" : "cm-force-border"; + var start = builder.pos, end = start + text.length; + for (;;) { + // Find the part that overlaps with the start of this text + for (var i = 0; i < order.length; i++) { + var part = order[i]; + if (part.to > start && part.from <= start) break; + } + if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); + startStyle = null; + text = text.slice(part.to - start); + start = part.to; + } + }; + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode; + if (widget) builder.map.push(builder.pos, builder.pos + size, widget); + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + widget = builder.content.appendChild(document.createElement("span")); + widget.setAttribute("cm-marker", marker.id); + } + if (widget) { + builder.cm.display.input.setUneditable(widget); + builder.content.appendChild(widget); + } + builder.pos += size; + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i = 1; i < styles.length; i+=2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); + return; + } + + var len = allText.length, pos = 0, i = 1, text = "", style, css; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = css = ""; + collapsed = null; nextChange = Infinity; + var foundBookmarks = [], endStyles + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m); + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to; + spanEndStyle = ""; + } + if (m.className) spanStyle += " " + m.className; + if (m.css) css = (css ? css + ";" : "") + m.css; + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; + if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to) + if (m.title && !title) title = m.title; + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + collapsed = sp; + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + } + if (endStyles) for (var j = 0; j < endStyles.length; j += 2) + if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j] + + if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]); + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) return; + if (collapsed.to == pos) collapsed = false; + } + } + if (pos >= len) break; + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder.cm.options); + } + } + } + + // DOCUMENT DATA STRUCTURE + + // By default, updates that start and end at the beginning of a line + // are treated specially, in order to make the association of line + // widgets and marker elements with the text behave more intuitive. + function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore); + } + + // Perform a change on the document data structure. + function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null;} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + function linesFor(start, end) { + for (var i = start, result = []; i < end; ++i) + result.push(new Line(text[i], spansFor(i), estimateHeight)); + return result; + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)); + doc.remove(text.length, doc.size - text.length); + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + var added = linesFor(0, text.length - 1); + update(lastLine, lastLine.text, lastSpans); + if (nlines) doc.remove(from.line, nlines); + if (added.length) doc.insert(from.line, added); + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + var added = linesFor(1, text.length - 1); + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + var added = linesFor(1, text.length - 1); + if (nlines > 1) doc.remove(from.line + 1, nlines - 1); + doc.insert(from.line + 1, added); + } + + signalLater(doc, "change", doc, change); + } + + // The document is represented as a BTree consisting of leaves, with + // chunk of lines in them, and branches, with up to ten leaves or + // other branch nodes below them. The top node is always a branch + // node, and is the document object itself (meaning it has + // additional methods and properties). + // + // All nodes have parent links. The tree is used both to go from + // line numbers to line objects, and to go from objects to numbers. + // It also indexes by height, and is used to convert between height + // and line object, and to find the total height of the document. + // + // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + for (var i = 0, height = 0; i < lines.length; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function() { return this.lines.length; }, + // Remove the n lines at offset 'at'. + removeInner: function(at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + // Helper used to collapse a small branch into a single leaf. + collapse: function(lines) { + lines.push.apply(lines, this.lines); + }, + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function(at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0; i < lines.length; ++i) lines[i].parent = this; + }, + // Used to iterate over a part of the tree. + iterN: function(at, n, op) { + for (var e = at + n; at < e; ++at) + if (op(this.lines[at])) return true; + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0; i < children.length; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function() { return this.size; }, + removeInner: function(at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) break; + at = 0; + } else at -= sz; + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + collapse: function(lines) { + for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); + }, + insertInner: function(at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + while (child.lines.length > 50) { + var spilled = child.lines.splice(child.lines.length - 25, 25); + var newleaf = new LeafChunk(spilled); + child.height -= newleaf.height; + this.children.splice(i + 1, 0, newleaf); + newleaf.parent = this; + } + this.maybeSpill(); + } + break; + } + at -= sz; + } + }, + // When a node has grown, check whether it should be split. + maybeSpill: function() { + if (this.children.length <= 10) return; + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10); + me.parent.maybeSpill(); + }, + iterN: function(at, n, op) { + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) return true; + if ((n -= used) == 0) break; + at = 0; + } else at -= sz; + } + } + }; + + var nextDocId = 0; + var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep); + if (firstLine == null) firstLine = 0; + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.cleanGeneration = 1; + this.frontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = simpleSelection(start); + this.history = new History(null); + this.id = ++nextDocId; + this.modeOption = mode; + this.lineSep = lineSep; + this.extend = false; + + if (typeof text == "string") text = this.splitLines(text); + updateDoc(this, {from: start, to: start, text: text}); + setSelection(this, simpleSelection(start), sel_dontScroll); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) this.iterN(from - this.first, to - from, op); + else this.iterN(this.first, this.first + this.size, from); + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + var height = 0; + for (var i = 0; i < lines.length; ++i) height += lines[i].height; + this.insertInner(at - this.first, lines, height); + }, + remove: function(at, n) { this.removeInner(at - this.first, n); }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep) { + var lines = getLines(this, this.first, this.first + this.size); + if (lineSep === false) return lines; + return lines.join(lineSep || this.lineSeparator()); + }, + setValue: docMethodOp(function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: this.splitLines(code), origin: "setValue", full: true}, true); + setSelection(this, simpleSelection(top)); + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) return lines; + return lines.join(lineSep || this.lineSeparator()); + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, + + getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, + getLineNumber: function(line) {return lineNo(line);}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") line = getLine(this, line); + return visualLine(line); + }, + + lineCount: function() {return this.size;}, + firstLine: function() {return this.first;}, + lastLine: function() {return this.first + this.size - 1;}, + + clipPos: function(pos) {return clipPos(this, pos);}, + + getCursor: function(start) { + var range = this.sel.primary(), pos; + if (start == null || start == "head") pos = range.head; + else if (start == "anchor") pos = range.anchor; + else if (start == "end" || start == "to" || start === false) pos = range.to(); + else pos = range.from(); + return pos; + }, + listSelections: function() { return this.sel.ranges; }, + somethingSelected: function() {return this.sel.somethingSelected();}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads), options); + }), + extendSelectionsBy: docMethodOp(function(f, options) { + var heads = map(this.sel.ranges, f); + extendSelections(this, clipPosArray(this, heads), options); + }), + setSelections: docMethodOp(function(ranges, primary, options) { + if (!ranges.length) return; + for (var i = 0, out = []; i < ranges.length; i++) + out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)); + if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); + setSelection(this, normalizeSelection(out, primary), options); + }), + addSelection: docMethodOp(function(anchor, head, options) { + var ranges = this.sel.ranges.slice(0); + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); + }), + + getSelection: function(lineSep) { + var ranges = this.sel.ranges, lines; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + lines = lines ? lines.concat(sel) : sel; + } + if (lineSep === false) return lines; + else return lines.join(lineSep || this.lineSeparator()); + }, + getSelections: function(lineSep) { + var parts = [], ranges = this.sel.ranges; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator()); + parts[i] = sel; + } + return parts; + }, + replaceSelection: function(code, collapse, origin) { + var dup = []; + for (var i = 0; i < this.sel.ranges.length; i++) + dup[i] = code; + this.replaceSelections(dup, collapse, origin || "+input"); + }, + replaceSelections: docMethodOp(function(code, collapse, origin) { + var changes = [], sel = this.sel; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin}; + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); + for (var i = changes.length - 1; i >= 0; i--) + makeChange(this, changes[i]); + if (newSel) setSelectionReplaceHistory(this, newSel); + else if (this.cm) ensureCursorVisible(this.cm); + }), + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), + + setExtending: function(val) {this.extend = val;}, + getExtending: function() {return this.extend;}, + + historySize: function() { + var hist = this.history, done = 0, undone = 0; + for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; + for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; + return {undo: done, redo: undone}; + }, + clearHistory: function() {this.history = new History(this.history.maxGeneration);}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true); + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; + return this.history.generation; + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration); + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)}; + }, + setHistory: function(histData) { + var hist = this.history = new History(this.history.maxGeneration); + hist.done = copyHistoryArray(histData.done.slice(0), null, true); + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); + }, + + addLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + if (!line[prop]) line[prop] = cls; + else if (classTest(cls).test(line[prop])) return false; + else line[prop] += " " + cls; + return true; + }); + }), + removeLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) return false; + else if (cls == null) line[prop] = null; + else { + var found = cur.match(classTest(cls)); + if (!found) return false; + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true; + }); + }), + + addLineWidget: docMethodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options); + }), + removeLineWidget: function(widget) { widget.clear(); }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range"); + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents}; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark"); + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker); + } + return markers; + }, + findMarks: function(from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to); + var found = [], lineNo = from.line; + this.iter(from.line, to.line + 1, function(line) { + var spans = line.markedSpans; + if (spans) for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + if (!(span.to != null && lineNo == from.line && from.ch >= span.to || + span.from == null && lineNo != from.line || + span.from != null && lineNo == to.line && span.from >= to.ch) && + (!filter || filter(span.marker))) + found.push(span.marker.parent || span.marker); + } + ++lineNo; + }); + return found; + }, + getAllMarks: function() { + var markers = []; + this.iter(function(line) { + var sps = line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker); + }); + return markers; + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first, sepSize = this.lineSeparator().length; + this.iter(function(line) { + var sz = line.text.length + sepSize; + if (sz > off) { ch = off; return true; } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)); + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) return 0; + var sepSize = this.lineSeparator().length; + this.iter(this.first, coords.line, function (line) { + index += line.text.length + sepSize; + }); + return index; + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), + this.modeOption, this.first, this.lineSep); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = this.sel; + doc.extend = false; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc; + }, + + linkedDoc: function(options) { + if (!options) options = {}; + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) from = options.from; + if (options.to != null && options.to < to) to = options.to; + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep); + if (options.sharedHist) copy.history = this.history; + (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; + copySharedMarkers(copy, findSharedMarkers(this)); + return copy; + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) other = other.doc; + if (this.linked) for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) continue; + this.linked.splice(i, 1); + other.unlinkDoc(this); + detachSharedMarkers(findSharedMarkers(this)); + break; + } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); + other.history = new History(null); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f);}, + + getMode: function() {return this.mode;}, + getEditor: function() {return this.cm;}, + + splitLines: function(str) { + if (this.lineSep) return str.split(this.lineSep); + return splitLinesAuto(str); + }, + lineSeparator: function() { return this.lineSep || "\n"; } + }); + + // Public alias. + Doc.prototype.eachLine = Doc.prototype.iter; + + // Set up methods on CodeMirror's prototype to redirect to the editor's document. + var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); + for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments);}; + })(Doc.prototype[prop]); + + eventMixin(Doc); + + // Call f for all linked documents. + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) continue; + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) continue; + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } + } + propagate(doc, null, true); + } + + // Attach a document to an editor. + function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use."); + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + if (!cm.options.lineWrapping) findMaxLine(cm); + cm.options.mode = doc.modeOption; + regChange(cm); + } + + // LINE UTILITIES + + // Find the line object corresponding to the given line number. + function getLine(doc, n) { + n -= doc.first; + if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); + for (var chunk = doc; !chunk.lines;) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break; } + n -= sz; + } + } + return chunk.lines[n]; + } + + // Get the part of a document between two positions, as an array of + // strings. + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function(line) { + var text = line.text; + if (n == end.line) text = text.slice(0, end.ch); + if (n == start.line) text = text.slice(start.ch); + out.push(text); + ++n; + }); + return out; + } + // Get the lines between from and to, as array of strings. + function getLines(doc, from, to) { + var out = []; + doc.iter(from, to, function(line) { out.push(line.text); }); + return out; + } + + // Update the height of a line, propagating the height change + // upwards to parent nodes. + function updateLineHeight(line, height) { + var diff = height - line.height; + if (diff) for (var n = line; n; n = n.parent) n.height += diff; + } + + // Given a line object, find its line number by walking up through + // its parent links. + function lineNo(line) { + if (line.parent == null) return null; + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) break; + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first; + } + + // Find the line at the given vertical position, using the height + // information in the document tree. + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i = 0; i < chunk.children.length; ++i) { + var child = chunk.children[i], ch = child.height; + if (h < ch) { chunk = child; continue outer; } + h -= ch; + n += child.chunkSize(); + } + return n; + } while (!chunk.lines); + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) break; + h -= lh; + } + return n + i; + } + + + // Find the height above the given line. + function heightAtLine(lineObj) { + lineObj = visualLine(lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) break; + else h += line.height; + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i = 0; i < p.children.length; ++i) { + var cur = p.children[i]; + if (cur == chunk) break; + else h += cur.height; + } + } + return h; + } + + // Get the bidi ordering for the given line (and cache it). Returns + // false for lines that are fully left-to-right, and an array of + // BidiSpan objects otherwise. + function getOrder(line) { + var order = line.order; + if (order == null) order = line.order = bidiOrdering(line.text); + return order; + } + + // HISTORY + + function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = []; + this.undoDepth = Infinity; + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0; + this.lastOp = this.lastSelOp = null; + this.lastOrigin = this.lastSelOrigin = null; + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1; + } + + // Create a history change event from an updateDoc-style change + // object. + function historyChangeFromChange(doc, change) { + var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); + return histChange; + } + + // Pop all selection events off the end of a history array. Stop at + // a change event. + function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array); + if (last.ranges) array.pop(); + else break; + } + } + + // Find the top change event in the history. Pop off selection + // events that are in the way. + function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done); + return lst(hist.done); + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done); + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop(); + return lst(hist.done); + } + } + + // Register a change in the history. Merges changes that are within + // a single operation, ore are close together with an origin that + // allows merging (starting with "+") into a single event. + function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur; + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + var last = lst(cur.changes); + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done); + if (!before || !before.ranges) + pushSelectionToHistory(doc.sel, hist.done); + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation}; + hist.done.push(cur); + while (hist.done.length > hist.undoDepth) { + hist.done.shift(); + if (!hist.done[0].ranges) hist.done.shift(); + } + } + hist.done.push(selAfter); + hist.generation = ++hist.maxGeneration; + hist.lastModTime = hist.lastSelTime = time; + hist.lastOp = hist.lastSelOp = opId; + hist.lastOrigin = hist.lastSelOrigin = change.origin; + + if (!last) signal(doc, "historyAdded"); + } + + function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0); + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); + } + + // Called whenever the selection changes, sets the new selection as + // the pending selection in the history, and pushes the old pending + // selection into the 'done' array when it was significantly + // different (in number of selected ranges, emptiness, or time). + function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin; + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + hist.done[hist.done.length - 1] = sel; + else + pushSelectionToHistory(sel, hist.done); + + hist.lastSelTime = +new Date; + hist.lastSelOrigin = origin; + hist.lastSelOp = opId; + if (options && options.clearRedo !== false) + clearSelectionEvents(hist.undone); + } + + function pushSelectionToHistory(sel, dest) { + var top = lst(dest); + if (!(top && top.ranges && top.equals(sel))) + dest.push(sel); + } + + // Used to store marked span information in the history. + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; + ++n; + }); + } + + // When un/re-doing restores text containing marked spans, those + // that have been explicitly cleared should not be restored. + function removeClearedSpans(spans) { + if (!spans) return null; + for (var i = 0, out; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } + + // Retrieve and filter the old marked spans stored in a change event. + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) return null; + for (var i = 0, nw = []; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])); + return nw; + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup, instantiateSel) { + for (var i = 0, copy = []; i < events.length; ++i) { + var event = events[i]; + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); + continue; + } + var changes = event.changes, newChanges = []; + copy.push({changes: newChanges}); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m; + newChanges.push({from: change.from, to: change.to, text: change.text}); + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } + } + } + return copy; + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); + } + continue; + } + for (var j = 0; j < sub.changes.length; ++j) { + var cur = sub.changes[j]; + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch); + cur.to = Pos(cur.to.line + diff, cur.to.ch); + } else if (from <= cur.to.line) { + ok = false; + break; + } + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // EVENT UTILITIES + + // Due to the fact that we still support jurassic IE versions, some + // compatibility wrappers are needed. + + var e_preventDefault = CodeMirror.e_preventDefault = function(e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + }; + var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + }; + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; + } + var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; + + function e_target(e) {return e.target || e.srcElement;} + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) b = 1; + else if (e.button & 2) b = 3; + else if (e.button & 4) b = 2; + } + if (mac && e.ctrlKey && b == 1) b = 3; + return b; + } + + // EVENT HANDLING + + // Lightweight event framework. on/off also work on DOM nodes, + // registering native DOM handlers. + + var on = CodeMirror.on = function(emitter, type, f) { + if (emitter.addEventListener) + emitter.addEventListener(type, f, false); + else if (emitter.attachEvent) + emitter.attachEvent("on" + type, f); + else { + var map = emitter._handlers || (emitter._handlers = {}); + var arr = map[type] || (map[type] = []); + arr.push(f); + } + }; + + var noHandlers = [] + function getHandlers(emitter, type, copy) { + var arr = emitter._handlers && emitter._handlers[type] + if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers + else return arr || noHandlers + } + + var off = CodeMirror.off = function(emitter, type, f) { + if (emitter.removeEventListener) + emitter.removeEventListener(type, f, false); + else if (emitter.detachEvent) + emitter.detachEvent("on" + type, f); + else { + var handlers = getHandlers(emitter, type, false) + for (var i = 0; i < handlers.length; ++i) + if (handlers[i] == f) { handlers.splice(i, 1); break; } + } + }; + + var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { + var handlers = getHandlers(emitter, type, true) + if (!handlers.length) return; + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args); + }; + + var orphanDelayedCallbacks = null; + + // Often, we want to signal events at a point where we are in the + // middle of some work, but don't want the handler to start calling + // other methods on the editor, which might be in an inconsistent + // state or simply not expect any other events to happen. + // signalLater looks whether there are any handlers, and schedules + // them to be executed when the last operation ends, or, if no + // operation is active, when a timeout fires. + function signalLater(emitter, type /*, values...*/) { + var arr = getHandlers(emitter, type, false) + if (!arr.length) return; + var args = Array.prototype.slice.call(arguments, 2), list; + if (operationGroup) { + list = operationGroup.delayedCallbacks; + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks; + } else { + list = orphanDelayedCallbacks = []; + setTimeout(fireOrphanDelayed, 0); + } + function bnd(f) {return function(){f.apply(null, args);};}; + for (var i = 0; i < arr.length; ++i) + list.push(bnd(arr[i])); + } + + function fireOrphanDelayed() { + var delayed = orphanDelayedCallbacks; + orphanDelayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // The DOM events that CodeMirror handles can be overridden by + // registering a (non-DOM) handler on the editor for the event name, + // and preventDefault-ing the event in that handler. + function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore; + } + + function signalCursorActivity(cm) { + var arr = cm._handlers && cm._handlers.cursorActivity; + if (!arr) return; + var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); + for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) + set.push(arr[i]); + } + + function hasHandler(emitter, type) { + return getHandlers(emitter, type).length > 0 + } + + // Add on and off methods to a constructor's prototype, to make + // registering events on such objects more convenient. + function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f);}; + ctor.prototype.off = function(type, f) {off(this, type, f);}; + } + + // MISC UTILITIES + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerGap = 30; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; + + // Reused option objects for setSelection & friends + var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; + + function Delayed() {this.id = null;} + Delayed.prototype.set = function(ms, f) { + clearTimeout(this.id); + this.id = setTimeout(f, ms); + }; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + return n + (end - i); + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + }; + + // The inverse of countColumn -- find the offset that corresponds to + // a particular column. + var findColumn = CodeMirror.findColumn = function(string, goal, tabSize) { + for (var pos = 0, col = 0;;) { + var nextTab = string.indexOf("\t", pos); + if (nextTab == -1) nextTab = string.length; + var skipped = nextTab - pos; + if (nextTab == string.length || col + skipped >= goal) + return pos + Math.min(skipped, goal - col); + col += nextTab - pos; + col += tabSize - (col % tabSize); + pos = nextTab + 1; + if (col >= goal) return pos; + } + } + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " "); + return spaceStrs[n]; + } + + function lst(arr) { return arr[arr.length-1]; } + + var selectInput = function(node) { node.select(); }; + if (ios) // Mobile Safari apparently has a bug where select() is broken. + selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; + else if (ie) // Suppress mysterious IE10 errors + selectInput = function(node) { try { node.select(); } catch(_e) {} }; + + function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + if (array[i] == elt) return i; + return -1; + } + function map(array, f) { + var out = []; + for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); + return out; + } + + function nothing() {} + + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) copyObj(props, inst); + return inst; + }; + + function copyObj(obj, target, overwrite) { + if (!target) target = {}; + for (var prop in obj) + if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + target[prop] = obj[prop]; + return target; + } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function(){return f.apply(null, args);}; + } + + var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var isWordCharBasic = CodeMirror.isWordChar = function(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); + }; + function isWordChar(ch, helper) { + if (!helper) return isWordCharBasic(ch); + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; + return helper.test(ch); + } + + function isEmpty(obj) { + for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; + return true; + } + + // Extending unicode characters. A series of a non-extending char + + // any number of extending chars is treated as a single unit as far + // as editing and measuring is concerned. This is not fully correct, + // since some scripts/fonts/browsers also treat other configurations + // of code points as a group. + var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; + function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } + + // DOM UTILITIES + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + var range; + if (document.createRange) range = function(node, start, end, endNode) { + var r = document.createRange(); + r.setEnd(endNode || node, end); + r.setStart(node, start); + return r; + }; + else range = function(node, start, end) { + var r = document.body.createTextRange(); + try { r.moveToElementText(node.parentNode); } + catch(e) { return r; } + r.collapse(true); + r.moveEnd("character", end); + r.moveStart("character", start); + return r; + }; + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild); + return e; + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e); + } + + var contains = CodeMirror.contains = function(parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + child = child.parentNode; + if (parent.contains) + return parent.contains(child); + do { + if (child.nodeType == 11) child = child.host; + if (child == parent) return true; + } while (child = child.parentNode); + }; + + function activeElt() { + var activeElement = document.activeElement; + while (activeElement && activeElement.root && activeElement.root.activeElement) + activeElement = activeElement.root.activeElement; + return activeElement; + } + // Older versions of IE throws unspecified error when touching + // document.activeElement in some cases (during loading, in iframe) + if (ie && ie_version < 11) activeElt = function() { + try { return document.activeElement; } + catch(e) { return document.body; } + }; + + function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } + var rmClass = CodeMirror.rmClass = function(node, cls) { + var current = node.className; + var match = classTest(cls).exec(current); + if (match) { + var after = current.slice(match.index + match[0].length); + node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); + } + }; + var addClass = CodeMirror.addClass = function(node, cls) { + var current = node.className; + if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; + }; + function joinClasses(a, b) { + var as = a.split(" "); + for (var i = 0; i < as.length; i++) + if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; + return b; + } + + // WINDOW-WIDE EVENTS + + // These must be handled carefully, because naively registering a + // handler for each editor will cause the editors to never be + // garbage collected. + + function forEachCodeMirror(f) { + if (!document.body.getElementsByClassName) return; + var byClass = document.body.getElementsByClassName("CodeMirror"); + for (var i = 0; i < byClass.length; i++) { + var cm = byClass[i].CodeMirror; + if (cm) f(cm); + } + } + + var globalsRegistered = false; + function ensureGlobalHandlers() { + if (globalsRegistered) return; + registerGlobalHandlers(); + globalsRegistered = true; + } + function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + var resizeTimer; + on(window, "resize", function() { + if (resizeTimer == null) resizeTimer = setTimeout(function() { + resizeTimer = null; + forEachCodeMirror(onResize); + }, 100); + }); + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", function() { + forEachCodeMirror(onBlur); + }); + } + + // FEATURE DETECTION + + // Detect drag-and-drop + var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) return false; + var div = elt('div'); + return "draggable" in div || "dragDrop" in div; + }(); + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); + } + var node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + node.setAttribute("cm-text", ""); + return node; + } + + // Feature-detect IE's crummy client rect reporting for bidi text + var badBidiRects; + function hasBadBidiRects(measure) { + if (badBidiRects != null) return badBidiRects; + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); + var r0 = range(txt, 0, 1).getBoundingClientRect(); + if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) + var r1 = range(txt, 1, 2).getBoundingClientRect(); + return badBidiRects = (r1.right - r0.right < 3); + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) nl = string.length; + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result; + } : function(string){return string.split(/\r\n?|\n/);}; + + var hasSelection = window.getSelection ? function(te) { + try { return te.selectionStart != te.selectionEnd; } + catch(e) { return false; } + } : function(te) { + try {var range = te.ownerDocument.selection.createRange();} + catch(e) {} + if (!range || range.parentElement() != te) return false; + return range.compareEndPoints("StartToEnd", range) != 0; + }; + + var hasCopyEvent = (function() { + var e = elt("div"); + if ("oncopy" in e) return true; + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == "function"; + })(); + + var badZoomedRects = null; + function hasBadZoomedRects(measure) { + if (badZoomedRects != null) return badZoomedRects; + var node = removeChildrenAndAdd(measure, elt("span", "x")); + var normal = node.getBoundingClientRect(); + var fromRange = range(node, 0, 1).getBoundingClientRect(); + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; + } + + // KEY NAMES + + var keyNames = CodeMirror.keyNames = { + 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" + }; + (function() { + // Number keys + for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); + // Alphabetic keys + for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); + // Function keys + for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; + })(); + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr"); + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); + found = true; + } + } + if (!found) f(from, to, "ltr"); + } + + function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } + function bidiRight(part) { return part.level % 2 ? part.from : part.to; } + + function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } + function lineRight(line) { + var order = getOrder(line); + if (!order) return line.text.length; + return bidiRight(lst(order)); + } + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(line); + if (visual != line) lineN = lineNo(visual); + var order = getOrder(visual); + var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); + return Pos(lineN, ch); + } + function lineEnd(cm, lineN) { + var merged, line = getLine(cm.doc, lineN); + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + lineN = null; + } + var order = getOrder(line); + var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); + return Pos(lineN == null ? lineNo(line) : lineN, ch); + } + function lineStartSmart(cm, pos) { + var start = lineStart(cm, pos.line); + var line = getLine(cm.doc, start.line); + var order = getOrder(line); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)); + var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; + return Pos(start.line, inWS ? 0 : firstNonWS); + } + return start; + } + + function compareBidiLevel(order, a, b) { + var linedir = order[0].level; + if (a == linedir) return true; + if (b == linedir) return false; + return a < b; + } + var bidiOther; + function getBidiPartAt(order, pos) { + bidiOther = null; + for (var i = 0, found; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < pos && cur.to > pos) return i; + if ((cur.from == pos || cur.to == pos)) { + if (found == null) { + found = i; + } else if (compareBidiLevel(order, cur.level, order[found].level)) { + if (cur.from != cur.to) bidiOther = found; + return i; + } else { + if (cur.from != cur.to) bidiOther = i; + return found; + } + } + } + return found; + } + + function moveInLine(line, pos, dir, byUnit) { + if (!byUnit) return pos + dir; + do pos += dir; + while (pos > 0 && isExtendingChar(line.text.charAt(pos))); + return pos; + } + + // This is needed in order to move 'visually' through bi-directional + // text -- i.e., pressing left should make the cursor go left, even + // when in RTL text. The tricky part is the 'jumps', where RTL and + // LTR text touch each other. This often requires the cursor offset + // to move more than one unit, in order to visually move one unit. + function moveVisually(line, start, dir, byUnit) { + var bidi = getOrder(line); + if (!bidi) return moveLogically(line, start, dir, byUnit); + var pos = getBidiPartAt(bidi, start), part = bidi[pos]; + var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); + + for (;;) { + if (target > part.from && target < part.to) return target; + if (target == part.from || target == part.to) { + if (getBidiPartAt(bidi, target) == pos) return target; + part = bidi[pos += dir]; + return (dir > 0) == part.level % 2 ? part.to : part.from; + } else { + part = bidi[pos += dir]; + if (!part) return null; + if ((dir > 0) == part.level % 2) + target = moveInLine(line, part.to, -1, byUnit); + else + target = moveInLine(line, part.from, 1, byUnit); + } + } + } + + function moveLogically(line, start, dir, byUnit) { + var target = start + dir; + if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; + return target < 0 || target > line.text.length ? null : target; + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; + // Character types for codepoints 0x600 to 0x6ff + var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; + function charType(code) { + if (code <= 0xf7) return lowTypes.charAt(code); + else if (0x590 <= code && code <= 0x5f4) return "R"; + else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); + else if (0x6ee <= code && code <= 0x8ac) return "r"; + else if (0x2000 <= code && code <= 0x200b) return "w"; + else if (code == 0x200c) return "b"; + else return "L"; + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + // Browsers seem to always treat the boundaries of block elements as being L. + var outerType = "L"; + + function BidiSpan(level, from, to) { + this.level = level; + this.from = from; this.to = to; + } + + return function(str) { + if (!bidiRE.test(str)) return false; + var len = str.length, types = []; + for (var i = 0, type; i < len; ++i) + types.push(type = charType(str.charCodeAt(i))); + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i = 0, prev = outerType; i < len; ++i) { + var type = types[i]; + if (type == "m") types[i] = prev; + else prev = type; + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (type == "1" && cur == "r") types[i] = "n"; + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i = 1, prev = types[0]; i < len - 1; ++i) { + var type = types[i]; + if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; + else if (type == "," && prev == types[i+1] && + (prev == "1" || prev == "n")) types[i] = prev; + prev = type; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i = 0; i < len; ++i) { + var type = types[i]; + if (type == ",") types[i] = "N"; + else if (type == "%") { + for (var end = i + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (cur == "L" && type == "1") types[i] = "L"; + else if (isStrong.test(type)) cur = type; + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} + var before = (i ? types[i-1] : outerType) == "L"; + var after = (end < len ? types[end] : outerType) == "L"; + var replace = before || after ? "L" : "R"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + var start = i; + for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} + order.push(new BidiSpan(0, start, i)); + } else { + var pos = i, at = order.length; + for (++i; i < len && types[i] != "L"; ++i) {} + for (var j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); + var nstart = j; + for (++j; j < i && countsAsNum.test(types[j]); ++j) {} + order.splice(at, 0, new BidiSpan(2, nstart, j)); + pos = j; + } else ++j; + } + if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); + } + } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); + } + if (order[0].level == 2) + order.unshift(new BidiSpan(1, order[0].to, order[0].to)); + if (order[0].level != lst(order).level) + order.push(new BidiSpan(order[0].level, len, len)); + + return order; + }; + })(); + + // THE END + + CodeMirror.version = "5.14.2"; + + return CodeMirror; +}); diff --git a/shared/codemirror/mode/css/css.js b/shared/codemirror/mode/css/css.js index e9656e3..9cee203 100644 --- a/shared/codemirror/mode/css/css.js +++ b/shared/codemirror/mode/css/css.js @@ -1,825 +1,825 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("css", function(config, parserConfig) { - var inline = parserConfig.inline - if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); - - var indentUnit = config.indentUnit, - tokenHooks = parserConfig.tokenHooks, - documentTypes = parserConfig.documentTypes || {}, - mediaTypes = parserConfig.mediaTypes || {}, - mediaFeatures = parserConfig.mediaFeatures || {}, - mediaValueKeywords = parserConfig.mediaValueKeywords || {}, - propertyKeywords = parserConfig.propertyKeywords || {}, - nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {}, - fontProperties = parserConfig.fontProperties || {}, - counterDescriptors = parserConfig.counterDescriptors || {}, - colorKeywords = parserConfig.colorKeywords || {}, - valueKeywords = parserConfig.valueKeywords || {}, - allowNested = parserConfig.allowNested, - supportsAtComponent = parserConfig.supportsAtComponent === true; - - var type, override; - function ret(style, tp) { type = tp; return style; } - - // Tokenizers - - function tokenBase(stream, state) { - var ch = stream.next(); - if (tokenHooks[ch]) { - var result = tokenHooks[ch](stream, state); - if (result !== false) return result; - } - if (ch == "@") { - stream.eatWhile(/[\w\\\-]/); - return ret("def", stream.current()); - } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) { - return ret(null, "compare"); - } else if (ch == "\"" || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } else if (ch == "#") { - stream.eatWhile(/[\w\\\-]/); - return ret("atom", "hash"); - } else if (ch == "!") { - stream.match(/^\s*\w*/); - return ret("keyword", "important"); - } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } else if (ch === "-") { - if (/[\d.]/.test(stream.peek())) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } else if (stream.match(/^-[\w\\\-]+/)) { - stream.eatWhile(/[\w\\\-]/); - if (stream.match(/^\s*:/, false)) - return ret("variable-2", "variable-definition"); - return ret("variable-2", "variable"); - } else if (stream.match(/^\w+-/)) { - return ret("meta", "meta"); - } - } else if (/[,+>*\/]/.test(ch)) { - return ret(null, "select-op"); - } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { - return ret("qualifier", "qualifier"); - } else if (/[:;{}\[\]\(\)]/.test(ch)) { - return ret(null, ch); - } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || - (ch == "d" && stream.match("omain(")) || - (ch == "r" && stream.match("egexp("))) { - stream.backUp(1); - state.tokenize = tokenParenthesized; - return ret("property", "word"); - } else if (/[\w\\\-]/.test(ch)) { - stream.eatWhile(/[\w\\\-]/); - return ret("property", "word"); - } else { - return ret(null, null); - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) { - if (quote == ")") stream.backUp(1); - break; - } - escaped = !escaped && ch == "\\"; - } - if (ch == quote || !escaped && quote != ")") state.tokenize = null; - return ret("string", "string"); - }; - } - - function tokenParenthesized(stream, state) { - stream.next(); // Must be '(' - if (!stream.match(/\s*[\"\')]/, false)) - state.tokenize = tokenString(")"); - else - state.tokenize = null; - return ret(null, "("); - } - - // Context management - - function Context(type, indent, prev) { - this.type = type; - this.indent = indent; - this.prev = prev; - } - - function pushContext(state, stream, type, indent) { - state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context); - return type; - } - - function popContext(state) { - if (state.context.prev) - state.context = state.context.prev; - return state.context.type; - } - - function pass(type, stream, state) { - return states[state.context.type](type, stream, state); - } - function popAndPass(type, stream, state, n) { - for (var i = n || 1; i > 0; i--) - state.context = state.context.prev; - return pass(type, stream, state); - } - - // Parser - - function wordAsValue(stream) { - var word = stream.current().toLowerCase(); - if (valueKeywords.hasOwnProperty(word)) - override = "atom"; - else if (colorKeywords.hasOwnProperty(word)) - override = "keyword"; - else - override = "variable"; - } - - var states = {}; - - states.top = function(type, stream, state) { - if (type == "{") { - return pushContext(state, stream, "block"); - } else if (type == "}" && state.context.prev) { - return popContext(state); - } else if (supportsAtComponent && /@component/.test(type)) { - return pushContext(state, stream, "atComponentBlock"); - } else if (/^@(-moz-)?document$/.test(type)) { - return pushContext(state, stream, "documentTypes"); - } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { - return pushContext(state, stream, "atBlock"); - } else if (/^@(font-face|counter-style)/.test(type)) { - state.stateArg = type; - return "restricted_atBlock_before"; - } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { - return "keyframes"; - } else if (type && type.charAt(0) == "@") { - return pushContext(state, stream, "at"); - } else if (type == "hash") { - override = "builtin"; - } else if (type == "word") { - override = "tag"; - } else if (type == "variable-definition") { - return "maybeprop"; - } else if (type == "interpolation") { - return pushContext(state, stream, "interpolation"); - } else if (type == ":") { - return "pseudo"; - } else if (allowNested && type == "(") { - return pushContext(state, stream, "parens"); - } - return state.context.type; - }; - - states.block = function(type, stream, state) { - if (type == "word") { - var word = stream.current().toLowerCase(); - if (propertyKeywords.hasOwnProperty(word)) { - override = "property"; - return "maybeprop"; - } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { - override = "string-2"; - return "maybeprop"; - } else if (allowNested) { - override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; - return "block"; - } else { - override += " error"; - return "maybeprop"; - } - } else if (type == "meta") { - return "block"; - } else if (!allowNested && (type == "hash" || type == "qualifier")) { - override = "error"; - return "block"; - } else { - return states.top(type, stream, state); - } - }; - - states.maybeprop = function(type, stream, state) { - if (type == ":") return pushContext(state, stream, "prop"); - return pass(type, stream, state); - }; - - states.prop = function(type, stream, state) { - if (type == ";") return popContext(state); - if (type == "{" && allowNested) return pushContext(state, stream, "propBlock"); - if (type == "}" || type == "{") return popAndPass(type, stream, state); - if (type == "(") return pushContext(state, stream, "parens"); - - if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) { - override += " error"; - } else if (type == "word") { - wordAsValue(stream); - } else if (type == "interpolation") { - return pushContext(state, stream, "interpolation"); - } - return "prop"; - }; - - states.propBlock = function(type, _stream, state) { - if (type == "}") return popContext(state); - if (type == "word") { override = "property"; return "maybeprop"; } - return state.context.type; - }; - - states.parens = function(type, stream, state) { - if (type == "{" || type == "}") return popAndPass(type, stream, state); - if (type == ")") return popContext(state); - if (type == "(") return pushContext(state, stream, "parens"); - if (type == "interpolation") return pushContext(state, stream, "interpolation"); - if (type == "word") wordAsValue(stream); - return "parens"; - }; - - states.pseudo = function(type, stream, state) { - if (type == "word") { - override = "variable-3"; - return state.context.type; - } - return pass(type, stream, state); - }; - - states.documentTypes = function(type, stream, state) { - if (type == "word" && documentTypes.hasOwnProperty(stream.current())) { - override = "tag"; - return state.context.type; - } else { - return states.atBlock(type, stream, state); - } - }; - - states.atBlock = function(type, stream, state) { - if (type == "(") return pushContext(state, stream, "atBlock_parens"); - if (type == "}" || type == ";") return popAndPass(type, stream, state); - if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top"); - - if (type == "interpolation") return pushContext(state, stream, "interpolation"); - - if (type == "word") { - var word = stream.current().toLowerCase(); - if (word == "only" || word == "not" || word == "and" || word == "or") - override = "keyword"; - else if (mediaTypes.hasOwnProperty(word)) - override = "attribute"; - else if (mediaFeatures.hasOwnProperty(word)) - override = "property"; - else if (mediaValueKeywords.hasOwnProperty(word)) - override = "keyword"; - else if (propertyKeywords.hasOwnProperty(word)) - override = "property"; - else if (nonStandardPropertyKeywords.hasOwnProperty(word)) - override = "string-2"; - else if (valueKeywords.hasOwnProperty(word)) - override = "atom"; - else if (colorKeywords.hasOwnProperty(word)) - override = "keyword"; - else - override = "error"; - } - return state.context.type; - }; - - states.atComponentBlock = function(type, stream, state) { - if (type == "}") - return popAndPass(type, stream, state); - if (type == "{") - return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false); - if (type == "word") - override = "error"; - return state.context.type; - }; - - states.atBlock_parens = function(type, stream, state) { - if (type == ")") return popContext(state); - if (type == "{" || type == "}") return popAndPass(type, stream, state, 2); - return states.atBlock(type, stream, state); - }; - - states.restricted_atBlock_before = function(type, stream, state) { - if (type == "{") - return pushContext(state, stream, "restricted_atBlock"); - if (type == "word" && state.stateArg == "@counter-style") { - override = "variable"; - return "restricted_atBlock_before"; - } - return pass(type, stream, state); - }; - - states.restricted_atBlock = function(type, stream, state) { - if (type == "}") { - state.stateArg = null; - return popContext(state); - } - if (type == "word") { - if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) || - (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase()))) - override = "error"; - else - override = "property"; - return "maybeprop"; - } - return "restricted_atBlock"; - }; - - states.keyframes = function(type, stream, state) { - if (type == "word") { override = "variable"; return "keyframes"; } - if (type == "{") return pushContext(state, stream, "top"); - return pass(type, stream, state); - }; - - states.at = function(type, stream, state) { - if (type == ";") return popContext(state); - if (type == "{" || type == "}") return popAndPass(type, stream, state); - if (type == "word") override = "tag"; - else if (type == "hash") override = "builtin"; - return "at"; - }; - - states.interpolation = function(type, stream, state) { - if (type == "}") return popContext(state); - if (type == "{" || type == ";") return popAndPass(type, stream, state); - if (type == "word") override = "variable"; - else if (type != "variable" && type != "(" && type != ")") override = "error"; - return "interpolation"; - }; - - return { - startState: function(base) { - return {tokenize: null, - state: inline ? "block" : "top", - stateArg: null, - context: new Context(inline ? "block" : "top", base || 0, null)}; - }, - - token: function(stream, state) { - if (!state.tokenize && stream.eatSpace()) return null; - var style = (state.tokenize || tokenBase)(stream, state); - if (style && typeof style == "object") { - type = style[1]; - style = style[0]; - } - override = style; - state.state = states[state.state](type, stream, state); - return override; - }, - - indent: function(state, textAfter) { - var cx = state.context, ch = textAfter && textAfter.charAt(0); - var indent = cx.indent; - if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev; - if (cx.prev) { - if (ch == "}" && (cx.type == "block" || cx.type == "top" || - cx.type == "interpolation" || cx.type == "restricted_atBlock")) { - // Resume indentation from parent context. - cx = cx.prev; - indent = cx.indent; - } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") || - ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { - // Dedent relative to current context. - indent = Math.max(0, cx.indent - indentUnit); - cx = cx.prev; - } - } - return indent; - }, - - electricChars: "}", - blockCommentStart: "/*", - blockCommentEnd: "*/", - fold: "brace" - }; -}); - - function keySet(array) { - var keys = {}; - for (var i = 0; i < array.length; ++i) { - keys[array[i]] = true; - } - return keys; - } - - var documentTypes_ = [ - "domain", "regexp", "url", "url-prefix" - ], documentTypes = keySet(documentTypes_); - - var mediaTypes_ = [ - "all", "aural", "braille", "handheld", "print", "projection", "screen", - "tty", "tv", "embossed" - ], mediaTypes = keySet(mediaTypes_); - - var mediaFeatures_ = [ - "width", "min-width", "max-width", "height", "min-height", "max-height", - "device-width", "min-device-width", "max-device-width", "device-height", - "min-device-height", "max-device-height", "aspect-ratio", - "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", - "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", - "max-color", "color-index", "min-color-index", "max-color-index", - "monochrome", "min-monochrome", "max-monochrome", "resolution", - "min-resolution", "max-resolution", "scan", "grid", "orientation", - "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", - "pointer", "any-pointer", "hover", "any-hover" - ], mediaFeatures = keySet(mediaFeatures_); - - var mediaValueKeywords_ = [ - "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", - "interlace", "progressive" - ], mediaValueKeywords = keySet(mediaValueKeywords_); - - var propertyKeywords_ = [ - "align-content", "align-items", "align-self", "alignment-adjust", - "alignment-baseline", "anchor-point", "animation", "animation-delay", - "animation-direction", "animation-duration", "animation-fill-mode", - "animation-iteration-count", "animation-name", "animation-play-state", - "animation-timing-function", "appearance", "azimuth", "backface-visibility", - "background", "background-attachment", "background-blend-mode", "background-clip", - "background-color", "background-image", "background-origin", "background-position", - "background-repeat", "background-size", "baseline-shift", "binding", - "bleed", "bookmark-label", "bookmark-level", "bookmark-state", - "bookmark-target", "border", "border-bottom", "border-bottom-color", - "border-bottom-left-radius", "border-bottom-right-radius", - "border-bottom-style", "border-bottom-width", "border-collapse", - "border-color", "border-image", "border-image-outset", - "border-image-repeat", "border-image-slice", "border-image-source", - "border-image-width", "border-left", "border-left-color", - "border-left-style", "border-left-width", "border-radius", "border-right", - "border-right-color", "border-right-style", "border-right-width", - "border-spacing", "border-style", "border-top", "border-top-color", - "border-top-left-radius", "border-top-right-radius", "border-top-style", - "border-top-width", "border-width", "bottom", "box-decoration-break", - "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", - "caption-side", "clear", "clip", "color", "color-profile", "column-count", - "column-fill", "column-gap", "column-rule", "column-rule-color", - "column-rule-style", "column-rule-width", "column-span", "column-width", - "columns", "content", "counter-increment", "counter-reset", "crop", "cue", - "cue-after", "cue-before", "cursor", "direction", "display", - "dominant-baseline", "drop-initial-after-adjust", - "drop-initial-after-align", "drop-initial-before-adjust", - "drop-initial-before-align", "drop-initial-size", "drop-initial-value", - "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", - "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", - "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", - "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", - "font-stretch", "font-style", "font-synthesis", "font-variant", - "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", - "font-variant-ligatures", "font-variant-numeric", "font-variant-position", - "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", - "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end", - "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", - "grid-template", "grid-template-areas", "grid-template-columns", - "grid-template-rows", "hanging-punctuation", "height", "hyphens", - "icon", "image-orientation", "image-rendering", "image-resolution", - "inline-box-align", "justify-content", "left", "letter-spacing", - "line-break", "line-height", "line-stacking", "line-stacking-ruby", - "line-stacking-shift", "line-stacking-strategy", "list-style", - "list-style-image", "list-style-position", "list-style-type", "margin", - "margin-bottom", "margin-left", "margin-right", "margin-top", - "marker-offset", "marks", "marquee-direction", "marquee-loop", - "marquee-play-count", "marquee-speed", "marquee-style", "max-height", - "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", - "nav-left", "nav-right", "nav-up", "object-fit", "object-position", - "opacity", "order", "orphans", "outline", - "outline-color", "outline-offset", "outline-style", "outline-width", - "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", - "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", - "page", "page-break-after", "page-break-before", "page-break-inside", - "page-policy", "pause", "pause-after", "pause-before", "perspective", - "perspective-origin", "pitch", "pitch-range", "play-during", "position", - "presentation-level", "punctuation-trim", "quotes", "region-break-after", - "region-break-before", "region-break-inside", "region-fragment", - "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", - "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", - "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", - "shape-outside", "size", "speak", "speak-as", "speak-header", - "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", - "tab-size", "table-layout", "target", "target-name", "target-new", - "target-position", "text-align", "text-align-last", "text-decoration", - "text-decoration-color", "text-decoration-line", "text-decoration-skip", - "text-decoration-style", "text-emphasis", "text-emphasis-color", - "text-emphasis-position", "text-emphasis-style", "text-height", - "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", - "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", - "text-wrap", "top", "transform", "transform-origin", "transform-style", - "transition", "transition-delay", "transition-duration", - "transition-property", "transition-timing-function", "unicode-bidi", - "vertical-align", "visibility", "voice-balance", "voice-duration", - "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", - "voice-volume", "volume", "white-space", "widows", "width", "word-break", - "word-spacing", "word-wrap", "z-index", - // SVG-specific - "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", - "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", - "color-interpolation", "color-interpolation-filters", - "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", - "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", - "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", - "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", - "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", - "glyph-orientation-vertical", "text-anchor", "writing-mode" - ], propertyKeywords = keySet(propertyKeywords_); - - var nonStandardPropertyKeywords_ = [ - "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color", - "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color", - "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside", - "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", - "searchfield-results-decoration", "zoom" - ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_); - - var fontProperties_ = [ - "font-family", "src", "unicode-range", "font-variant", "font-feature-settings", - "font-stretch", "font-weight", "font-style" - ], fontProperties = keySet(fontProperties_); - - var counterDescriptors_ = [ - "additive-symbols", "fallback", "negative", "pad", "prefix", "range", - "speak-as", "suffix", "symbols", "system" - ], counterDescriptors = keySet(counterDescriptors_); - - var colorKeywords_ = [ - "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", - "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", - "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", - "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", - "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", - "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", - "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", - "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", - "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", - "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", - "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", - "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", - "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", - "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", - "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", - "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", - "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", - "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", - "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", - "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", - "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", - "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", - "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", - "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", - "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", - "whitesmoke", "yellow", "yellowgreen" - ], colorKeywords = keySet(colorKeywords_); - - var valueKeywords_ = [ - "above", "absolute", "activeborder", "additive", "activecaption", "afar", - "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", - "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", - "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page", - "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", - "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", - "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian", - "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", - "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", - "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", - "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", - "compact", "condensed", "contain", "content", - "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop", - "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", - "decimal-leading-zero", "default", "default-button", "destination-atop", - "destination-in", "destination-out", "destination-over", "devanagari", "difference", - "disc", "discard", "disclosure-closed", "disclosure-open", "document", - "dot-dash", "dot-dot-dash", - "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", - "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", - "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", - "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", - "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", - "ethiopic-halehame-gez", "ethiopic-halehame-om-et", - "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", - "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", - "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", - "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", - "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", - "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew", - "help", "hidden", "hide", "higher", "highlight", "highlighttext", - "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore", - "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", - "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", - "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert", - "italic", "japanese-formal", "japanese-informal", "justify", "kannada", - "katakana", "katakana-iroha", "keep-all", "khmer", - "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", - "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten", - "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem", - "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", - "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", - "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d", - "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", - "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", - "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", - "media-volume-slider-container", "media-volume-sliderthumb", "medium", - "menu", "menulist", "menulist-button", "menulist-text", - "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", - "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize", - "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", - "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", - "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", - "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", - "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", - "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter", - "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", - "progress", "push-button", "radial-gradient", "radio", "read-only", - "read-write", "read-write-plaintext-only", "rectangle", "region", - "relative", "repeat", "repeating-linear-gradient", - "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", - "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", - "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", - "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", - "scroll", "scrollbar", "se-resize", "searchfield", - "searchfield-cancel-button", "searchfield-decoration", - "searchfield-results-button", "searchfield-results-decoration", - "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", - "simp-chinese-formal", "simp-chinese-informal", "single", - "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", - "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", - "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", - "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square", - "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", - "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table", - "table-caption", "table-cell", "table-column", "table-column-group", - "table-footer-group", "table-header-group", "table-row", "table-row-group", - "tamil", - "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", - "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", - "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", - "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", - "trad-chinese-formal", "trad-chinese-informal", - "translate", "translate3d", "translateX", "translateY", "translateZ", - "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", - "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", - "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", - "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", - "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", - "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", - "xx-large", "xx-small" - ], valueKeywords = keySet(valueKeywords_); - - var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_) - .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_) - .concat(valueKeywords_); - CodeMirror.registerHelper("hintWords", "css", allWords); - - function tokenCComment(stream, state) { - var maybeEnd = false, ch; - while ((ch = stream.next()) != null) { - if (maybeEnd && ch == "/") { - state.tokenize = null; - break; - } - maybeEnd = (ch == "*"); - } - return ["comment", "comment"]; - } - - CodeMirror.defineMIME("text/css", { - documentTypes: documentTypes, - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - mediaValueKeywords: mediaValueKeywords, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - fontProperties: fontProperties, - counterDescriptors: counterDescriptors, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - tokenHooks: { - "/": function(stream, state) { - if (!stream.eat("*")) return false; - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } - }, - name: "css" - }); - - CodeMirror.defineMIME("text/x-scss", { - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - mediaValueKeywords: mediaValueKeywords, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - fontProperties: fontProperties, - allowNested: true, - tokenHooks: { - "/": function(stream, state) { - if (stream.eat("/")) { - stream.skipToEnd(); - return ["comment", "comment"]; - } else if (stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } else { - return ["operator", "operator"]; - } - }, - ":": function(stream) { - if (stream.match(/\s*\{/)) - return [null, "{"]; - return false; - }, - "$": function(stream) { - stream.match(/^[\w-]+/); - if (stream.match(/^\s*:/, false)) - return ["variable-2", "variable-definition"]; - return ["variable-2", "variable"]; - }, - "#": function(stream) { - if (!stream.eat("{")) return false; - return [null, "interpolation"]; - } - }, - name: "css", - helperType: "scss" - }); - - CodeMirror.defineMIME("text/x-less", { - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - mediaValueKeywords: mediaValueKeywords, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - fontProperties: fontProperties, - allowNested: true, - tokenHooks: { - "/": function(stream, state) { - if (stream.eat("/")) { - stream.skipToEnd(); - return ["comment", "comment"]; - } else if (stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } else { - return ["operator", "operator"]; - } - }, - "@": function(stream) { - if (stream.eat("{")) return [null, "interpolation"]; - if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; - stream.eatWhile(/[\w\\\-]/); - if (stream.match(/^\s*:/, false)) - return ["variable-2", "variable-definition"]; - return ["variable-2", "variable"]; - }, - "&": function() { - return ["atom", "atom"]; - } - }, - name: "css", - helperType: "less" - }); - - CodeMirror.defineMIME("text/x-gss", { - documentTypes: documentTypes, - mediaTypes: mediaTypes, - mediaFeatures: mediaFeatures, - propertyKeywords: propertyKeywords, - nonStandardPropertyKeywords: nonStandardPropertyKeywords, - fontProperties: fontProperties, - counterDescriptors: counterDescriptors, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - supportsAtComponent: true, - tokenHooks: { - "/": function(stream, state) { - if (!stream.eat("*")) return false; - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } - }, - name: "css", - helperType: "gss" - }); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("css", function(config, parserConfig) { + var inline = parserConfig.inline + if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); + + var indentUnit = config.indentUnit, + tokenHooks = parserConfig.tokenHooks, + documentTypes = parserConfig.documentTypes || {}, + mediaTypes = parserConfig.mediaTypes || {}, + mediaFeatures = parserConfig.mediaFeatures || {}, + mediaValueKeywords = parserConfig.mediaValueKeywords || {}, + propertyKeywords = parserConfig.propertyKeywords || {}, + nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {}, + fontProperties = parserConfig.fontProperties || {}, + counterDescriptors = parserConfig.counterDescriptors || {}, + colorKeywords = parserConfig.colorKeywords || {}, + valueKeywords = parserConfig.valueKeywords || {}, + allowNested = parserConfig.allowNested, + supportsAtComponent = parserConfig.supportsAtComponent === true; + + var type, override; + function ret(style, tp) { type = tp; return style; } + + // Tokenizers + + function tokenBase(stream, state) { + var ch = stream.next(); + if (tokenHooks[ch]) { + var result = tokenHooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == "@") { + stream.eatWhile(/[\w\\\-]/); + return ret("def", stream.current()); + } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) { + return ret(null, "compare"); + } else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "#") { + stream.eatWhile(/[\w\\\-]/); + return ret("atom", "hash"); + } else if (ch == "!") { + stream.match(/^\s*\w*/); + return ret("keyword", "important"); + } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (ch === "-") { + if (/[\d.]/.test(stream.peek())) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (stream.match(/^-[\w\\\-]+/)) { + stream.eatWhile(/[\w\\\-]/); + if (stream.match(/^\s*:/, false)) + return ret("variable-2", "variable-definition"); + return ret("variable-2", "variable"); + } else if (stream.match(/^\w+-/)) { + return ret("meta", "meta"); + } + } else if (/[,+>*\/]/.test(ch)) { + return ret(null, "select-op"); + } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { + return ret("qualifier", "qualifier"); + } else if (/[:;{}\[\]\(\)]/.test(ch)) { + return ret(null, ch); + } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || + (ch == "d" && stream.match("omain(")) || + (ch == "r" && stream.match("egexp("))) { + stream.backUp(1); + state.tokenize = tokenParenthesized; + return ret("property", "word"); + } else if (/[\w\\\-]/.test(ch)) { + stream.eatWhile(/[\w\\\-]/); + return ret("property", "word"); + } else { + return ret(null, null); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + if (quote == ")") stream.backUp(1); + break; + } + escaped = !escaped && ch == "\\"; + } + if (ch == quote || !escaped && quote != ")") state.tokenize = null; + return ret("string", "string"); + }; + } + + function tokenParenthesized(stream, state) { + stream.next(); // Must be '(' + if (!stream.match(/\s*[\"\')]/, false)) + state.tokenize = tokenString(")"); + else + state.tokenize = null; + return ret(null, "("); + } + + // Context management + + function Context(type, indent, prev) { + this.type = type; + this.indent = indent; + this.prev = prev; + } + + function pushContext(state, stream, type, indent) { + state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context); + return type; + } + + function popContext(state) { + if (state.context.prev) + state.context = state.context.prev; + return state.context.type; + } + + function pass(type, stream, state) { + return states[state.context.type](type, stream, state); + } + function popAndPass(type, stream, state, n) { + for (var i = n || 1; i > 0; i--) + state.context = state.context.prev; + return pass(type, stream, state); + } + + // Parser + + function wordAsValue(stream) { + var word = stream.current().toLowerCase(); + if (valueKeywords.hasOwnProperty(word)) + override = "atom"; + else if (colorKeywords.hasOwnProperty(word)) + override = "keyword"; + else + override = "variable"; + } + + var states = {}; + + states.top = function(type, stream, state) { + if (type == "{") { + return pushContext(state, stream, "block"); + } else if (type == "}" && state.context.prev) { + return popContext(state); + } else if (supportsAtComponent && /@component/.test(type)) { + return pushContext(state, stream, "atComponentBlock"); + } else if (/^@(-moz-)?document$/.test(type)) { + return pushContext(state, stream, "documentTypes"); + } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { + return pushContext(state, stream, "atBlock"); + } else if (/^@(font-face|counter-style)/.test(type)) { + state.stateArg = type; + return "restricted_atBlock_before"; + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + return "keyframes"; + } else if (type && type.charAt(0) == "@") { + return pushContext(state, stream, "at"); + } else if (type == "hash") { + override = "builtin"; + } else if (type == "word") { + override = "tag"; + } else if (type == "variable-definition") { + return "maybeprop"; + } else if (type == "interpolation") { + return pushContext(state, stream, "interpolation"); + } else if (type == ":") { + return "pseudo"; + } else if (allowNested && type == "(") { + return pushContext(state, stream, "parens"); + } + return state.context.type; + }; + + states.block = function(type, stream, state) { + if (type == "word") { + var word = stream.current().toLowerCase(); + if (propertyKeywords.hasOwnProperty(word)) { + override = "property"; + return "maybeprop"; + } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { + override = "string-2"; + return "maybeprop"; + } else if (allowNested) { + override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; + return "block"; + } else { + override += " error"; + return "maybeprop"; + } + } else if (type == "meta") { + return "block"; + } else if (!allowNested && (type == "hash" || type == "qualifier")) { + override = "error"; + return "block"; + } else { + return states.top(type, stream, state); + } + }; + + states.maybeprop = function(type, stream, state) { + if (type == ":") return pushContext(state, stream, "prop"); + return pass(type, stream, state); + }; + + states.prop = function(type, stream, state) { + if (type == ";") return popContext(state); + if (type == "{" && allowNested) return pushContext(state, stream, "propBlock"); + if (type == "}" || type == "{") return popAndPass(type, stream, state); + if (type == "(") return pushContext(state, stream, "parens"); + + if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) { + override += " error"; + } else if (type == "word") { + wordAsValue(stream); + } else if (type == "interpolation") { + return pushContext(state, stream, "interpolation"); + } + return "prop"; + }; + + states.propBlock = function(type, _stream, state) { + if (type == "}") return popContext(state); + if (type == "word") { override = "property"; return "maybeprop"; } + return state.context.type; + }; + + states.parens = function(type, stream, state) { + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == ")") return popContext(state); + if (type == "(") return pushContext(state, stream, "parens"); + if (type == "interpolation") return pushContext(state, stream, "interpolation"); + if (type == "word") wordAsValue(stream); + return "parens"; + }; + + states.pseudo = function(type, stream, state) { + if (type == "word") { + override = "variable-3"; + return state.context.type; + } + return pass(type, stream, state); + }; + + states.documentTypes = function(type, stream, state) { + if (type == "word" && documentTypes.hasOwnProperty(stream.current())) { + override = "tag"; + return state.context.type; + } else { + return states.atBlock(type, stream, state); + } + }; + + states.atBlock = function(type, stream, state) { + if (type == "(") return pushContext(state, stream, "atBlock_parens"); + if (type == "}" || type == ";") return popAndPass(type, stream, state); + if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top"); + + if (type == "interpolation") return pushContext(state, stream, "interpolation"); + + if (type == "word") { + var word = stream.current().toLowerCase(); + if (word == "only" || word == "not" || word == "and" || word == "or") + override = "keyword"; + else if (mediaTypes.hasOwnProperty(word)) + override = "attribute"; + else if (mediaFeatures.hasOwnProperty(word)) + override = "property"; + else if (mediaValueKeywords.hasOwnProperty(word)) + override = "keyword"; + else if (propertyKeywords.hasOwnProperty(word)) + override = "property"; + else if (nonStandardPropertyKeywords.hasOwnProperty(word)) + override = "string-2"; + else if (valueKeywords.hasOwnProperty(word)) + override = "atom"; + else if (colorKeywords.hasOwnProperty(word)) + override = "keyword"; + else + override = "error"; + } + return state.context.type; + }; + + states.atComponentBlock = function(type, stream, state) { + if (type == "}") + return popAndPass(type, stream, state); + if (type == "{") + return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false); + if (type == "word") + override = "error"; + return state.context.type; + }; + + states.atBlock_parens = function(type, stream, state) { + if (type == ")") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state, 2); + return states.atBlock(type, stream, state); + }; + + states.restricted_atBlock_before = function(type, stream, state) { + if (type == "{") + return pushContext(state, stream, "restricted_atBlock"); + if (type == "word" && state.stateArg == "@counter-style") { + override = "variable"; + return "restricted_atBlock_before"; + } + return pass(type, stream, state); + }; + + states.restricted_atBlock = function(type, stream, state) { + if (type == "}") { + state.stateArg = null; + return popContext(state); + } + if (type == "word") { + if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) || + (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase()))) + override = "error"; + else + override = "property"; + return "maybeprop"; + } + return "restricted_atBlock"; + }; + + states.keyframes = function(type, stream, state) { + if (type == "word") { override = "variable"; return "keyframes"; } + if (type == "{") return pushContext(state, stream, "top"); + return pass(type, stream, state); + }; + + states.at = function(type, stream, state) { + if (type == ";") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == "word") override = "tag"; + else if (type == "hash") override = "builtin"; + return "at"; + }; + + states.interpolation = function(type, stream, state) { + if (type == "}") return popContext(state); + if (type == "{" || type == ";") return popAndPass(type, stream, state); + if (type == "word") override = "variable"; + else if (type != "variable" && type != "(" && type != ")") override = "error"; + return "interpolation"; + }; + + return { + startState: function(base) { + return {tokenize: null, + state: inline ? "block" : "top", + stateArg: null, + context: new Context(inline ? "block" : "top", base || 0, null)}; + }, + + token: function(stream, state) { + if (!state.tokenize && stream.eatSpace()) return null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style && typeof style == "object") { + type = style[1]; + style = style[0]; + } + override = style; + state.state = states[state.state](type, stream, state); + return override; + }, + + indent: function(state, textAfter) { + var cx = state.context, ch = textAfter && textAfter.charAt(0); + var indent = cx.indent; + if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev; + if (cx.prev) { + if (ch == "}" && (cx.type == "block" || cx.type == "top" || + cx.type == "interpolation" || cx.type == "restricted_atBlock")) { + // Resume indentation from parent context. + cx = cx.prev; + indent = cx.indent; + } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") || + ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { + // Dedent relative to current context. + indent = Math.max(0, cx.indent - indentUnit); + cx = cx.prev; + } + } + return indent; + }, + + electricChars: "}", + blockCommentStart: "/*", + blockCommentEnd: "*/", + fold: "brace" + }; +}); + + function keySet(array) { + var keys = {}; + for (var i = 0; i < array.length; ++i) { + keys[array[i]] = true; + } + return keys; + } + + var documentTypes_ = [ + "domain", "regexp", "url", "url-prefix" + ], documentTypes = keySet(documentTypes_); + + var mediaTypes_ = [ + "all", "aural", "braille", "handheld", "print", "projection", "screen", + "tty", "tv", "embossed" + ], mediaTypes = keySet(mediaTypes_); + + var mediaFeatures_ = [ + "width", "min-width", "max-width", "height", "min-height", "max-height", + "device-width", "min-device-width", "max-device-width", "device-height", + "min-device-height", "max-device-height", "aspect-ratio", + "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", + "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", + "max-color", "color-index", "min-color-index", "max-color-index", + "monochrome", "min-monochrome", "max-monochrome", "resolution", + "min-resolution", "max-resolution", "scan", "grid", "orientation", + "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", + "pointer", "any-pointer", "hover", "any-hover" + ], mediaFeatures = keySet(mediaFeatures_); + + var mediaValueKeywords_ = [ + "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", + "interlace", "progressive" + ], mediaValueKeywords = keySet(mediaValueKeywords_); + + var propertyKeywords_ = [ + "align-content", "align-items", "align-self", "alignment-adjust", + "alignment-baseline", "anchor-point", "animation", "animation-delay", + "animation-direction", "animation-duration", "animation-fill-mode", + "animation-iteration-count", "animation-name", "animation-play-state", + "animation-timing-function", "appearance", "azimuth", "backface-visibility", + "background", "background-attachment", "background-blend-mode", "background-clip", + "background-color", "background-image", "background-origin", "background-position", + "background-repeat", "background-size", "baseline-shift", "binding", + "bleed", "bookmark-label", "bookmark-level", "bookmark-state", + "bookmark-target", "border", "border-bottom", "border-bottom-color", + "border-bottom-left-radius", "border-bottom-right-radius", + "border-bottom-style", "border-bottom-width", "border-collapse", + "border-color", "border-image", "border-image-outset", + "border-image-repeat", "border-image-slice", "border-image-source", + "border-image-width", "border-left", "border-left-color", + "border-left-style", "border-left-width", "border-radius", "border-right", + "border-right-color", "border-right-style", "border-right-width", + "border-spacing", "border-style", "border-top", "border-top-color", + "border-top-left-radius", "border-top-right-radius", "border-top-style", + "border-top-width", "border-width", "bottom", "box-decoration-break", + "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", + "caption-side", "clear", "clip", "color", "color-profile", "column-count", + "column-fill", "column-gap", "column-rule", "column-rule-color", + "column-rule-style", "column-rule-width", "column-span", "column-width", + "columns", "content", "counter-increment", "counter-reset", "crop", "cue", + "cue-after", "cue-before", "cursor", "direction", "display", + "dominant-baseline", "drop-initial-after-adjust", + "drop-initial-after-align", "drop-initial-before-adjust", + "drop-initial-before-align", "drop-initial-size", "drop-initial-value", + "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", + "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", + "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", + "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", + "font-stretch", "font-style", "font-synthesis", "font-variant", + "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", + "font-variant-ligatures", "font-variant-numeric", "font-variant-position", + "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", + "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end", + "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", + "grid-template", "grid-template-areas", "grid-template-columns", + "grid-template-rows", "hanging-punctuation", "height", "hyphens", + "icon", "image-orientation", "image-rendering", "image-resolution", + "inline-box-align", "justify-content", "left", "letter-spacing", + "line-break", "line-height", "line-stacking", "line-stacking-ruby", + "line-stacking-shift", "line-stacking-strategy", "list-style", + "list-style-image", "list-style-position", "list-style-type", "margin", + "margin-bottom", "margin-left", "margin-right", "margin-top", + "marker-offset", "marks", "marquee-direction", "marquee-loop", + "marquee-play-count", "marquee-speed", "marquee-style", "max-height", + "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", + "nav-left", "nav-right", "nav-up", "object-fit", "object-position", + "opacity", "order", "orphans", "outline", + "outline-color", "outline-offset", "outline-style", "outline-width", + "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", + "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", + "page", "page-break-after", "page-break-before", "page-break-inside", + "page-policy", "pause", "pause-after", "pause-before", "perspective", + "perspective-origin", "pitch", "pitch-range", "play-during", "position", + "presentation-level", "punctuation-trim", "quotes", "region-break-after", + "region-break-before", "region-break-inside", "region-fragment", + "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", + "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", + "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", + "shape-outside", "size", "speak", "speak-as", "speak-header", + "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", + "tab-size", "table-layout", "target", "target-name", "target-new", + "target-position", "text-align", "text-align-last", "text-decoration", + "text-decoration-color", "text-decoration-line", "text-decoration-skip", + "text-decoration-style", "text-emphasis", "text-emphasis-color", + "text-emphasis-position", "text-emphasis-style", "text-height", + "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", + "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", + "text-wrap", "top", "transform", "transform-origin", "transform-style", + "transition", "transition-delay", "transition-duration", + "transition-property", "transition-timing-function", "unicode-bidi", + "vertical-align", "visibility", "voice-balance", "voice-duration", + "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", + "voice-volume", "volume", "white-space", "widows", "width", "word-break", + "word-spacing", "word-wrap", "z-index", + // SVG-specific + "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", + "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", + "color-interpolation", "color-interpolation-filters", + "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", + "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", + "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", + "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", + "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", + "glyph-orientation-vertical", "text-anchor", "writing-mode" + ], propertyKeywords = keySet(propertyKeywords_); + + var nonStandardPropertyKeywords_ = [ + "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color", + "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color", + "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside", + "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", + "searchfield-results-decoration", "zoom" + ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_); + + var fontProperties_ = [ + "font-family", "src", "unicode-range", "font-variant", "font-feature-settings", + "font-stretch", "font-weight", "font-style" + ], fontProperties = keySet(fontProperties_); + + var counterDescriptors_ = [ + "additive-symbols", "fallback", "negative", "pad", "prefix", "range", + "speak-as", "suffix", "symbols", "system" + ], counterDescriptors = keySet(counterDescriptors_); + + var colorKeywords_ = [ + "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", + "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", + "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", + "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", + "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", + "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", + "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", + "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", + "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", + "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", + "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", + "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", + "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", + "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", + "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", + "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", + "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", + "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", + "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", + "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", + "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", + "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", + "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", + "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", + "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", + "whitesmoke", "yellow", "yellowgreen" + ], colorKeywords = keySet(colorKeywords_); + + var valueKeywords_ = [ + "above", "absolute", "activeborder", "additive", "activecaption", "afar", + "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", + "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", + "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page", + "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", + "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", + "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", + "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian", + "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", + "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", + "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", + "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", + "compact", "condensed", "contain", "content", + "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop", + "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", + "decimal-leading-zero", "default", "default-button", "destination-atop", + "destination-in", "destination-out", "destination-over", "devanagari", "difference", + "disc", "discard", "disclosure-closed", "disclosure-open", "document", + "dot-dash", "dot-dot-dash", + "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", + "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", + "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", + "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", + "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", + "ethiopic-halehame-gez", "ethiopic-halehame-om-et", + "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", + "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", + "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", + "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", + "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", + "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew", + "help", "hidden", "hide", "higher", "highlight", "highlighttext", + "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore", + "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", + "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", + "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert", + "italic", "japanese-formal", "japanese-informal", "justify", "kannada", + "katakana", "katakana-iroha", "keep-all", "khmer", + "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal", + "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten", + "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem", + "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", + "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", + "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d", + "media-controls-background", "media-current-time-display", + "media-fullscreen-button", "media-mute-button", "media-play-button", + "media-return-to-realtime-button", "media-rewind-button", + "media-seek-back-button", "media-seek-forward-button", "media-slider", + "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", + "media-volume-slider-container", "media-volume-sliderthumb", "medium", + "menu", "menulist", "menulist-button", "menulist-text", + "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", + "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize", + "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", + "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", + "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", + "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", + "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", + "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter", + "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", + "progress", "push-button", "radial-gradient", "radio", "read-only", + "read-write", "read-write-plaintext-only", "rectangle", "region", + "relative", "repeat", "repeating-linear-gradient", + "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", + "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", + "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", + "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", + "scroll", "scrollbar", "se-resize", "searchfield", + "searchfield-cancel-button", "searchfield-decoration", + "searchfield-results-button", "searchfield-results-decoration", + "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", + "simp-chinese-formal", "simp-chinese-informal", "single", + "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", + "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", + "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", + "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square", + "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", + "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table", + "table-caption", "table-cell", "table-column", "table-column-group", + "table-footer-group", "table-header-group", "table-row", "table-row-group", + "tamil", + "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", + "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", + "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", + "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", + "trad-chinese-formal", "trad-chinese-informal", + "translate", "translate3d", "translateX", "translateY", "translateZ", + "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", + "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", + "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", + "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", + "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", + "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", + "xx-large", "xx-small" + ], valueKeywords = keySet(valueKeywords_); + + var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_) + .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_) + .concat(valueKeywords_); + CodeMirror.registerHelper("hintWords", "css", allWords); + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return ["comment", "comment"]; + } + + CodeMirror.defineMIME("text/css", { + documentTypes: documentTypes, + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + mediaValueKeywords: mediaValueKeywords, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + fontProperties: fontProperties, + counterDescriptors: counterDescriptors, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + tokenHooks: { + "/": function(stream, state) { + if (!stream.eat("*")) return false; + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + }, + name: "css" + }); + + CodeMirror.defineMIME("text/x-scss", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + mediaValueKeywords: mediaValueKeywords, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + allowNested: true, + tokenHooks: { + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + ":": function(stream) { + if (stream.match(/\s*\{/)) + return [null, "{"]; + return false; + }, + "$": function(stream) { + stream.match(/^[\w-]+/); + if (stream.match(/^\s*:/, false)) + return ["variable-2", "variable-definition"]; + return ["variable-2", "variable"]; + }, + "#": function(stream) { + if (!stream.eat("{")) return false; + return [null, "interpolation"]; + } + }, + name: "css", + helperType: "scss" + }); + + CodeMirror.defineMIME("text/x-less", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + mediaValueKeywords: mediaValueKeywords, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + allowNested: true, + tokenHooks: { + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + "@": function(stream) { + if (stream.eat("{")) return [null, "interpolation"]; + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; + stream.eatWhile(/[\w\\\-]/); + if (stream.match(/^\s*:/, false)) + return ["variable-2", "variable-definition"]; + return ["variable-2", "variable"]; + }, + "&": function() { + return ["atom", "atom"]; + } + }, + name: "css", + helperType: "less" + }); + + CodeMirror.defineMIME("text/x-gss", { + documentTypes: documentTypes, + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + propertyKeywords: propertyKeywords, + nonStandardPropertyKeywords: nonStandardPropertyKeywords, + fontProperties: fontProperties, + counterDescriptors: counterDescriptors, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + supportsAtComponent: true, + tokenHooks: { + "/": function(stream, state) { + if (!stream.eat("*")) return false; + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + }, + name: "css", + helperType: "gss" + }); + +}); diff --git a/shared/codemirror/mode/gfm/gfm.js b/shared/codemirror/mode/gfm/gfm.js index 6e74ad4..b7beb7a 100644 --- a/shared/codemirror/mode/gfm/gfm.js +++ b/shared/codemirror/mode/gfm/gfm.js @@ -1,130 +1,130 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i - -CodeMirror.defineMode("gfm", function(config, modeConfig) { - var codeDepth = 0; - function blankLine(state) { - state.code = false; - return null; - } - var gfmOverlay = { - startState: function() { - return { - code: false, - codeBlock: false, - ateSpace: false - }; - }, - copyState: function(s) { - return { - code: s.code, - codeBlock: s.codeBlock, - ateSpace: s.ateSpace - }; - }, - token: function(stream, state) { - state.combineTokens = null; - - // Hack to prevent formatting override inside code blocks (block and inline) - if (state.codeBlock) { - if (stream.match(/^```+/)) { - state.codeBlock = false; - return null; - } - stream.skipToEnd(); - return null; - } - if (stream.sol()) { - state.code = false; - } - if (stream.sol() && stream.match(/^```+/)) { - stream.skipToEnd(); - state.codeBlock = true; - return null; - } - // If this block is changed, it may need to be updated in Markdown mode - if (stream.peek() === '`') { - stream.next(); - var before = stream.pos; - stream.eatWhile('`'); - var difference = 1 + stream.pos - before; - if (!state.code) { - codeDepth = difference; - state.code = true; - } else { - if (difference === codeDepth) { // Must be exact - state.code = false; - } - } - return null; - } else if (state.code) { - stream.next(); - return null; - } - // Check if space. If so, links can be formatted later on - if (stream.eatSpace()) { - state.ateSpace = true; - return null; - } - if (stream.sol() || state.ateSpace) { - state.ateSpace = false; - if (modeConfig.gitHubSpice !== false) { - if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) { - // User/Project@SHA - // User@SHA - // SHA - state.combineTokens = true; - return "link"; - } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) { - // User/Project#Num - // User#Num - // #Num - state.combineTokens = true; - return "link"; - } - } - } - if (stream.match(urlRE) && - stream.string.slice(stream.start - 2, stream.start) != "](" && - (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) { - // URLs - // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls - // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine - // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL - state.combineTokens = true; - return "link"; - } - stream.next(); - return null; - }, - blankLine: blankLine - }; - - var markdownConfig = { - underscoresBreakWords: false, - taskLists: true, - fencedCodeBlocks: '```', - strikethrough: true - }; - for (var attr in modeConfig) { - markdownConfig[attr] = modeConfig[attr]; - } - markdownConfig.name = "markdown"; - return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay); - -}, "markdown"); - - CodeMirror.defineMIME("text/x-gfm", "gfm"); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../markdown/markdown"), require("../../addon/mode/overlay")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../markdown/markdown", "../../addon/mode/overlay"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i + +CodeMirror.defineMode("gfm", function(config, modeConfig) { + var codeDepth = 0; + function blankLine(state) { + state.code = false; + return null; + } + var gfmOverlay = { + startState: function() { + return { + code: false, + codeBlock: false, + ateSpace: false + }; + }, + copyState: function(s) { + return { + code: s.code, + codeBlock: s.codeBlock, + ateSpace: s.ateSpace + }; + }, + token: function(stream, state) { + state.combineTokens = null; + + // Hack to prevent formatting override inside code blocks (block and inline) + if (state.codeBlock) { + if (stream.match(/^```+/)) { + state.codeBlock = false; + return null; + } + stream.skipToEnd(); + return null; + } + if (stream.sol()) { + state.code = false; + } + if (stream.sol() && stream.match(/^```+/)) { + stream.skipToEnd(); + state.codeBlock = true; + return null; + } + // If this block is changed, it may need to be updated in Markdown mode + if (stream.peek() === '`') { + stream.next(); + var before = stream.pos; + stream.eatWhile('`'); + var difference = 1 + stream.pos - before; + if (!state.code) { + codeDepth = difference; + state.code = true; + } else { + if (difference === codeDepth) { // Must be exact + state.code = false; + } + } + return null; + } else if (state.code) { + stream.next(); + return null; + } + // Check if space. If so, links can be formatted later on + if (stream.eatSpace()) { + state.ateSpace = true; + return null; + } + if (stream.sol() || state.ateSpace) { + state.ateSpace = false; + if (modeConfig.gitHubSpice !== false) { + if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) { + // User/Project@SHA + // User@SHA + // SHA + state.combineTokens = true; + return "link"; + } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) { + // User/Project#Num + // User#Num + // #Num + state.combineTokens = true; + return "link"; + } + } + } + if (stream.match(urlRE) && + stream.string.slice(stream.start - 2, stream.start) != "](" && + (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) { + // URLs + // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls + // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine + // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL + state.combineTokens = true; + return "link"; + } + stream.next(); + return null; + }, + blankLine: blankLine + }; + + var markdownConfig = { + underscoresBreakWords: false, + taskLists: true, + fencedCodeBlocks: '```', + strikethrough: true + }; + for (var attr in modeConfig) { + markdownConfig[attr] = modeConfig[attr]; + } + markdownConfig.name = "markdown"; + return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay); + +}, "markdown"); + + CodeMirror.defineMIME("text/x-gfm", "gfm"); +}); diff --git a/shared/codemirror/mode/htmlembedded/htmlembedded.js b/shared/codemirror/mode/htmlembedded/htmlembedded.js index 464dc57..0e91465 100644 --- a/shared/codemirror/mode/htmlembedded/htmlembedded.js +++ b/shared/codemirror/mode/htmlembedded/htmlembedded.js @@ -1,28 +1,28 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), - require("../../addon/mode/multiplex")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../htmlmixed/htmlmixed", - "../../addon/mode/multiplex"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { - return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { - open: parserConfig.open || parserConfig.scriptStartRegex || "<%", - close: parserConfig.close || parserConfig.scriptEndRegex || "%>", - mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) - }); - }, "htmlmixed"); - - CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"}); - CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); - CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"}); - CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"}); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), + require("../../addon/mode/multiplex")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../htmlmixed/htmlmixed", + "../../addon/mode/multiplex"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { + return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), { + open: parserConfig.open || parserConfig.scriptStartRegex || "<%", + close: parserConfig.close || parserConfig.scriptEndRegex || "%>", + mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec) + }); + }, "htmlmixed"); + + CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"}); + CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); + CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"}); + CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"}); +}); diff --git a/shared/codemirror/mode/htmlmixed/htmlmixed.js b/shared/codemirror/mode/htmlmixed/htmlmixed.js index 6574fbd..0186ea7 100644 --- a/shared/codemirror/mode/htmlmixed/htmlmixed.js +++ b/shared/codemirror/mode/htmlmixed/htmlmixed.js @@ -1,152 +1,152 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var defaultTags = { - script: [ - ["lang", /(javascript|babel)/i, "javascript"], - ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"], - ["type", /./, "text/plain"], - [null, null, "javascript"] - ], - style: [ - ["lang", /^css$/i, "css"], - ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"], - ["type", /./, "text/plain"], - [null, null, "css"] - ] - }; - - function maybeBackup(stream, pat, style) { - var cur = stream.current(), close = cur.search(pat); - if (close > -1) { - stream.backUp(cur.length - close); - } else if (cur.match(/<\/?$/)) { - stream.backUp(cur.length); - if (!stream.match(pat, false)) stream.match(cur); - } - return style; - } - - var attrRegexpCache = {}; - function getAttrRegexp(attr) { - var regexp = attrRegexpCache[attr]; - if (regexp) return regexp; - return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"); - } - - function getAttrValue(text, attr) { - var match = text.match(getAttrRegexp(attr)) - return match ? match[2] : "" - } - - function getTagRegexp(tagName, anchored) { - return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); - } - - function addTags(from, to) { - for (var tag in from) { - var dest = to[tag] || (to[tag] = []); - var source = from[tag]; - for (var i = source.length - 1; i >= 0; i--) - dest.unshift(source[i]) - } - } - - function findMatchingMode(tagInfo, tagText) { - for (var i = 0; i < tagInfo.length; i++) { - var spec = tagInfo[i]; - if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2]; - } - } - - CodeMirror.defineMode("htmlmixed", function (config, parserConfig) { - var htmlMode = CodeMirror.getMode(config, { - name: "xml", - htmlMode: true, - multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, - multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag - }); - - var tags = {}; - var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes; - addTags(defaultTags, tags); - if (configTags) addTags(configTags, tags); - if (configScript) for (var i = configScript.length - 1; i >= 0; i--) - tags.script.unshift(["type", configScript[i].matches, configScript[i].mode]) - - function html(stream, state) { - var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName - if (tag && !/[<>\s\/]/.test(stream.current()) && - (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) && - tags.hasOwnProperty(tagName)) { - state.inTag = tagName + " " - } else if (state.inTag && tag && />$/.test(stream.current())) { - var inTag = /^([\S]+) (.*)/.exec(state.inTag) - state.inTag = null - var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2]) - var mode = CodeMirror.getMode(config, modeSpec) - var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false); - state.token = function (stream, state) { - if (stream.match(endTagA, false)) { - state.token = html; - state.localState = state.localMode = null; - return null; - } - return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); - }; - state.localMode = mode; - state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); - } else if (state.inTag) { - state.inTag += stream.current() - if (stream.eol()) state.inTag += " " - } - return style; - }; - - return { - startState: function () { - var state = htmlMode.startState(); - return {token: html, inTag: null, localMode: null, localState: null, htmlState: state}; - }, - - copyState: function (state) { - var local; - if (state.localState) { - local = CodeMirror.copyState(state.localMode, state.localState); - } - return {token: state.token, inTag: state.inTag, - localMode: state.localMode, localState: local, - htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; - }, - - token: function (stream, state) { - return state.token(stream, state); - }, - - indent: function (state, textAfter) { - if (!state.localMode || /^\s*<\//.test(textAfter)) - return htmlMode.indent(state.htmlState, textAfter); - else if (state.localMode.indent) - return state.localMode.indent(state.localState, textAfter); - else - return CodeMirror.Pass; - }, - - innerMode: function (state) { - return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; - } - }; - }, "xml", "javascript", "css"); - - CodeMirror.defineMIME("text/html", "htmlmixed"); -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var defaultTags = { + script: [ + ["lang", /(javascript|babel)/i, "javascript"], + ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"], + ["type", /./, "text/plain"], + [null, null, "javascript"] + ], + style: [ + ["lang", /^css$/i, "css"], + ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"], + ["type", /./, "text/plain"], + [null, null, "css"] + ] + }; + + function maybeBackup(stream, pat, style) { + var cur = stream.current(), close = cur.search(pat); + if (close > -1) { + stream.backUp(cur.length - close); + } else if (cur.match(/<\/?$/)) { + stream.backUp(cur.length); + if (!stream.match(pat, false)) stream.match(cur); + } + return style; + } + + var attrRegexpCache = {}; + function getAttrRegexp(attr) { + var regexp = attrRegexpCache[attr]; + if (regexp) return regexp; + return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"); + } + + function getAttrValue(text, attr) { + var match = text.match(getAttrRegexp(attr)) + return match ? match[2] : "" + } + + function getTagRegexp(tagName, anchored) { + return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); + } + + function addTags(from, to) { + for (var tag in from) { + var dest = to[tag] || (to[tag] = []); + var source = from[tag]; + for (var i = source.length - 1; i >= 0; i--) + dest.unshift(source[i]) + } + } + + function findMatchingMode(tagInfo, tagText) { + for (var i = 0; i < tagInfo.length; i++) { + var spec = tagInfo[i]; + if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2]; + } + } + + CodeMirror.defineMode("htmlmixed", function (config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, { + name: "xml", + htmlMode: true, + multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, + multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag + }); + + var tags = {}; + var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes; + addTags(defaultTags, tags); + if (configTags) addTags(configTags, tags); + if (configScript) for (var i = configScript.length - 1; i >= 0; i--) + tags.script.unshift(["type", configScript[i].matches, configScript[i].mode]) + + function html(stream, state) { + var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName + if (tag && !/[<>\s\/]/.test(stream.current()) && + (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) && + tags.hasOwnProperty(tagName)) { + state.inTag = tagName + " " + } else if (state.inTag && tag && />$/.test(stream.current())) { + var inTag = /^([\S]+) (.*)/.exec(state.inTag) + state.inTag = null + var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2]) + var mode = CodeMirror.getMode(config, modeSpec) + var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false); + state.token = function (stream, state) { + if (stream.match(endTagA, false)) { + state.token = html; + state.localState = state.localMode = null; + return null; + } + return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); + }; + state.localMode = mode; + state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); + } else if (state.inTag) { + state.inTag += stream.current() + if (stream.eol()) state.inTag += " " + } + return style; + }; + + return { + startState: function () { + var state = htmlMode.startState(); + return {token: html, inTag: null, localMode: null, localState: null, htmlState: state}; + }, + + copyState: function (state) { + var local; + if (state.localState) { + local = CodeMirror.copyState(state.localMode, state.localState); + } + return {token: state.token, inTag: state.inTag, + localMode: state.localMode, localState: local, + htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; + }, + + token: function (stream, state) { + return state.token(stream, state); + }, + + indent: function (state, textAfter) { + if (!state.localMode || /^\s*<\//.test(textAfter)) + return htmlMode.indent(state.htmlState, textAfter); + else if (state.localMode.indent) + return state.localMode.indent(state.localState, textAfter); + else + return CodeMirror.Pass; + }, + + innerMode: function (state) { + return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; + } + }; + }, "xml", "javascript", "css"); + + CodeMirror.defineMIME("text/html", "htmlmixed"); +}); diff --git a/shared/codemirror/mode/javascript/javascript.js b/shared/codemirror/mode/javascript/javascript.js index fa5721d..95a9393 100644 --- a/shared/codemirror/mode/javascript/javascript.js +++ b/shared/codemirror/mode/javascript/javascript.js @@ -1,742 +1,742 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// TODO actually recognize syntax of TypeScript constructs - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -function expressionAllowed(stream, state, backUp) { - return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) || - (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) -} - -CodeMirror.defineMode("javascript", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var statementIndent = parserConfig.statementIndent; - var jsonldMode = parserConfig.jsonld; - var jsonMode = parserConfig.json || jsonldMode; - var isTS = parserConfig.typescript; - var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; - - // Tokenizer - - var keywords = function(){ - function kw(type) {return {type: type, style: "keyword"};} - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); - var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - - var jsKeywords = { - "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, - "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, - "var": kw("var"), "const": kw("var"), "let": kw("var"), - "function": kw("function"), "catch": kw("catch"), - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), - "in": operator, "typeof": operator, "instanceof": operator, - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, - "this": kw("this"), "class": kw("class"), "super": kw("atom"), - "yield": C, "export": kw("export"), "import": kw("import"), "extends": C - }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = {type: "variable", style: "variable-3"}; - var tsKeywords = { - // object-like things - "interface": kw("class"), - "implements": C, - "namespace": C, - "module": kw("module"), - "enum": kw("module"), - - // scope modifiers - "public": kw("modifier"), - "private": kw("modifier"), - "protected": kw("modifier"), - "abstract": kw("modifier"), - - // operators - "as": operator, - - // types - "string": type, "number": type, "boolean": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; - }(); - - var isOperatorChar = /[+\-*&%=<>!?|~^]/; - var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; - - function readRegexp(stream) { - var escaped = false, next, inSet = false; - while ((next = stream.next()) != null) { - if (!escaped) { - if (next == "/" && !inSet) return; - if (next == "[") inSet = true; - else if (inSet && next == "]") inSet = false; - } - escaped = !escaped && next == "\\"; - } - } - - // Used as scratch variables to communicate multiple values without - // consing up tons of objects. - var type, content; - function ret(tp, style, cont) { - type = tp; content = cont; - return style; - } - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { - return ret("number", "number"); - } else if (ch == "." && stream.match("..")) { - return ret("spread", "meta"); - } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { - return ret(ch); - } else if (ch == "=" && stream.eat(">")) { - return ret("=>", "operator"); - } else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/o/i)) { - stream.eatWhile(/[0-7]/i); - return ret("number", "number"); - } else if (ch == "0" && stream.eat(/b/i)) { - stream.eatWhile(/[01]/i); - return ret("number", "number"); - } else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); - return ret("number", "number"); - } else if (ch == "/") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } else if (stream.eat("/")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } else if (expressionAllowed(stream, state, 1)) { - readRegexp(stream); - stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); - return ret("regexp", "string-2"); - } else { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } - } else if (ch == "`") { - state.tokenize = tokenQuasi; - return tokenQuasi(stream, state); - } else if (ch == "#") { - stream.skipToEnd(); - return ret("error", "error"); - } else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } else if (wordRE.test(ch)) { - stream.eatWhile(wordRE); - var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; - return (known && state.lastType != ".") ? ret(known.type, known.style, word) : - ret("variable", "variable", word); - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next; - if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ - state.tokenize = tokenBase; - return ret("jsonld-keyword", "meta"); - } - while ((next = stream.next()) != null) { - if (next == quote && !escaped) break; - escaped = !escaped && next == "\\"; - } - if (!escaped) state.tokenize = tokenBase; - return ret("string", "string"); - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - function tokenQuasi(stream, state) { - var escaped = false, next; - while ((next = stream.next()) != null) { - if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && next == "\\"; - } - return ret("quasi", "string-2", stream.current()); - } - - var brackets = "([{}])"; - // This is a crude lookahead trick to try and notice that we're - // parsing the argument patterns for a fat-arrow function before we - // actually hit the arrow token. It only works if the arrow is on - // the same line as the arguments and there's no strange noise - // (comments) in between. Fallback is to only notice when we hit the - // arrow, and not declare the arguments as locals for the arrow - // body. - function findFatArrow(stream, state) { - if (state.fatArrowAt) state.fatArrowAt = null; - var arrow = stream.string.indexOf("=>", stream.start); - if (arrow < 0) return; - - var depth = 0, sawSomething = false; - for (var pos = arrow - 1; pos >= 0; --pos) { - var ch = stream.string.charAt(pos); - var bracket = brackets.indexOf(ch); - if (bracket >= 0 && bracket < 3) { - if (!depth) { ++pos; break; } - if (--depth == 0) break; - } else if (bracket >= 3 && bracket < 6) { - ++depth; - } else if (wordRE.test(ch)) { - sawSomething = true; - } else if (/["'\/]/.test(ch)) { - return; - } else if (sawSomething && !depth) { - ++pos; - break; - } - } - if (sawSomething && !depth) state.fatArrowAt = pos; - } - - // Parser - - var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; - - function JSLexical(indented, column, type, align, prev, info) { - this.indented = indented; - this.column = column; - this.type = type; - this.prev = prev; - this.info = info; - if (align != null) this.align = align; - } - - function inScope(state, varname) { - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return true; - for (var cx = state.context; cx; cx = cx.prev) { - for (var v = cx.vars; v; v = v.next) - if (v.name == varname) return true; - } - } - - function parseJS(state, style, type, content, stream) { - var cc = state.cc; - // Communicate our context to the combinators. - // (Less wasteful than consing up a hundred closures on every call.) - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; - - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = true; - - while(true) { - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; - if (combinator(type, content)) { - while(cc.length && cc[cc.length - 1].lex) - cc.pop()(); - if (cx.marked) return cx.marked; - if (type == "variable" && inScope(state, content)) return "variable-2"; - return style; - } - } - } - - // Combinator utils - - var cx = {state: null, column: null, marked: null, cc: null}; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - function register(varname) { - function inList(list) { - for (var v = list; v; v = v.next) - if (v.name == varname) return true; - return false; - } - var state = cx.state; - cx.marked = "def"; - if (state.context) { - if (inList(state.localVars)) return; - state.localVars = {name: varname, next: state.localVars}; - } else { - if (inList(state.globalVars)) return; - if (parserConfig.globalVars) - state.globalVars = {name: varname, next: state.globalVars}; - } - } - - // Combinators - - var defaultVars = {name: "this", next: {name: "arguments"}}; - function pushcontext() { - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; - cx.state.localVars = defaultVars; - } - function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; - } - function pushlex(type, info) { - var result = function() { - var state = cx.state, indent = state.indented; - if (state.lexical.type == "stat") indent = state.lexical.indented; - else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) - indent = outer.indented; - state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); - }; - result.lex = true; - return result; - } - function poplex() { - var state = cx.state; - if (state.lexical.prev) { - if (state.lexical.type == ")") - state.indented = state.lexical.indented; - state.lexical = state.lexical.prev; - } - } - poplex.lex = true; - - function expect(wanted) { - function exp(type) { - if (type == wanted) return cont(); - else if (wanted == ";") return pass(); - else return cont(exp); - }; - return exp; - } - - function statement(type, value) { - if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); - if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); - if (type == "keyword b") return cont(pushlex("form"), statement, poplex); - if (type == "{") return cont(pushlex("}"), block, poplex); - if (type == ";") return cont(); - if (type == "if") { - if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) - cx.state.cc.pop()(); - return cont(pushlex("form"), expression, statement, poplex, maybeelse); - } - if (type == "function") return cont(functiondef); - if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); - if (type == "variable") return cont(pushlex("stat"), maybelabel); - if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), - block, poplex, poplex); - if (type == "case") return cont(expression, expect(":")); - if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - if (type == "class") return cont(pushlex("form"), className, poplex); - if (type == "export") return cont(pushlex("stat"), afterExport, poplex); - if (type == "import") return cont(pushlex("stat"), afterImport, poplex); - if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex) - return pass(pushlex("stat"), expression, expect(";"), poplex); - } - function expression(type) { - return expressionInner(type, false); - } - function expressionNoComma(type) { - return expressionInner(type, true); - } - function expressionInner(type, noComma) { - if (cx.state.fatArrowAt == cx.stream.start) { - var body = noComma ? arrowBodyNoComma : arrowBody; - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); - else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); - } - - var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; - if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); - if (type == "function") return cont(functiondef, maybeop); - if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); - if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); - if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); - if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); - if (type == "{") return contCommasep(objprop, "}", null, maybeop); - if (type == "quasi") return pass(quasi, maybeop); - if (type == "new") return cont(maybeTarget(noComma)); - return cont(); - } - function maybeexpression(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expression); - } - function maybeexpressionNoComma(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expressionNoComma); - } - - function maybeoperatorComma(type, value) { - if (type == ",") return cont(expression); - return maybeoperatorNoComma(type, value, false); - } - function maybeoperatorNoComma(type, value, noComma) { - var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; - var expr = noComma == false ? expression : expressionNoComma; - if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); - if (type == "operator") { - if (/\+\+|--/.test(value)) return cont(me); - if (value == "?") return cont(expression, expect(":"), expr); - return cont(expr); - } - if (type == "quasi") { return pass(quasi, me); } - if (type == ";") return; - if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); - if (type == ".") return cont(property, me); - if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); - } - function quasi(type, value) { - if (type != "quasi") return pass(); - if (value.slice(value.length - 2) != "${") return cont(quasi); - return cont(expression, continueQuasi); - } - function continueQuasi(type) { - if (type == "}") { - cx.marked = "string-2"; - cx.state.tokenize = tokenQuasi; - return cont(quasi); - } - } - function arrowBody(type) { - findFatArrow(cx.stream, cx.state); - return pass(type == "{" ? statement : expression); - } - function arrowBodyNoComma(type) { - findFatArrow(cx.stream, cx.state); - return pass(type == "{" ? statement : expressionNoComma); - } - function maybeTarget(noComma) { - return function(type) { - if (type == ".") return cont(noComma ? targetNoComma : target); - else return pass(noComma ? expressionNoComma : expression); - }; - } - function target(_, value) { - if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } - } - function targetNoComma(_, value) { - if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } - } - function maybelabel(type) { - if (type == ":") return cont(poplex, statement); - return pass(maybeoperatorComma, expect(";"), poplex); - } - function property(type) { - if (type == "variable") {cx.marked = "property"; return cont();} - } - function objprop(type, value) { - if (type == "variable" || cx.style == "keyword") { - cx.marked = "property"; - if (value == "get" || value == "set") return cont(getterSetter); - return cont(afterprop); - } else if (type == "number" || type == "string") { - cx.marked = jsonldMode ? "property" : (cx.style + " property"); - return cont(afterprop); - } else if (type == "jsonld-keyword") { - return cont(afterprop); - } else if (type == "modifier") { - return cont(objprop) - } else if (type == "[") { - return cont(expression, expect("]"), afterprop); - } else if (type == "spread") { - return cont(expression); - } - } - function getterSetter(type) { - if (type != "variable") return pass(afterprop); - cx.marked = "property"; - return cont(functiondef); - } - function afterprop(type) { - if (type == ":") return cont(expressionNoComma); - if (type == "(") return pass(functiondef); - } - function commasep(what, end) { - function proceed(type) { - if (type == ",") { - var lex = cx.state.lexical; - if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; - return cont(what, proceed); - } - if (type == end) return cont(); - return cont(expect(end)); - } - return function(type) { - if (type == end) return cont(); - return pass(what, proceed); - }; - } - function contCommasep(what, end, info) { - for (var i = 3; i < arguments.length; i++) - cx.cc.push(arguments[i]); - return cont(pushlex(end, info), commasep(what, end), poplex); - } - function block(type) { - if (type == "}") return cont(); - return pass(statement, block); - } - function maybetype(type) { - if (isTS && type == ":") return cont(typedef); - } - function maybedefault(_, value) { - if (value == "=") return cont(expressionNoComma); - } - function typedef(type) { - if (type == "variable") {cx.marked = "variable-3"; return cont();} - } - function vardef() { - return pass(pattern, maybetype, maybeAssign, vardefCont); - } - function pattern(type, value) { - if (type == "modifier") return cont(pattern) - if (type == "variable") { register(value); return cont(); } - if (type == "spread") return cont(pattern); - if (type == "[") return contCommasep(pattern, "]"); - if (type == "{") return contCommasep(proppattern, "}"); - } - function proppattern(type, value) { - if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { - register(value); - return cont(maybeAssign); - } - if (type == "variable") cx.marked = "property"; - if (type == "spread") return cont(pattern); - if (type == "}") return pass(); - return cont(expect(":"), pattern, maybeAssign); - } - function maybeAssign(_type, value) { - if (value == "=") return cont(expressionNoComma); - } - function vardefCont(type) { - if (type == ",") return cont(vardef); - } - function maybeelse(type, value) { - if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); - } - function forspec(type) { - if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); - } - function forspec1(type) { - if (type == "var") return cont(vardef, expect(";"), forspec2); - if (type == ";") return cont(forspec2); - if (type == "variable") return cont(formaybeinof); - return pass(expression, expect(";"), forspec2); - } - function formaybeinof(_type, value) { - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return cont(maybeoperatorComma, forspec2); - } - function forspec2(type, value) { - if (type == ";") return cont(forspec3); - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return pass(expression, expect(";"), forspec3); - } - function forspec3(type) { - if (type != ")") cont(expression); - } - function functiondef(type, value) { - if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} - if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); - } - function funarg(type) { - if (type == "spread") return cont(funarg); - return pass(pattern, maybetype, maybedefault); - } - function className(type, value) { - if (type == "variable") {register(value); return cont(classNameAfter);} - } - function classNameAfter(type, value) { - if (value == "extends") return cont(expression, classNameAfter); - if (type == "{") return cont(pushlex("}"), classBody, poplex); - } - function classBody(type, value) { - if (type == "variable" || cx.style == "keyword") { - if (value == "static") { - cx.marked = "keyword"; - return cont(classBody); - } - cx.marked = "property"; - if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); - return cont(functiondef, classBody); - } - if (value == "*") { - cx.marked = "keyword"; - return cont(classBody); - } - if (type == ";") return cont(classBody); - if (type == "}") return cont(); - } - function classGetterSetter(type) { - if (type != "variable") return pass(); - cx.marked = "property"; - return cont(); - } - function afterExport(_type, value) { - if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } - if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } - return pass(statement); - } - function afterImport(type) { - if (type == "string") return cont(); - return pass(importSpec, maybeFrom); - } - function importSpec(type, value) { - if (type == "{") return contCommasep(importSpec, "}"); - if (type == "variable") register(value); - if (value == "*") cx.marked = "keyword"; - return cont(maybeAs); - } - function maybeAs(_type, value) { - if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } - } - function maybeFrom(_type, value) { - if (value == "from") { cx.marked = "keyword"; return cont(expression); } - } - function arrayLiteral(type) { - if (type == "]") return cont(); - return pass(expressionNoComma, maybeArrayComprehension); - } - function maybeArrayComprehension(type) { - if (type == "for") return pass(comprehension, expect("]")); - if (type == ",") return cont(commasep(maybeexpressionNoComma, "]")); - return pass(commasep(expressionNoComma, "]")); - } - function comprehension(type) { - if (type == "for") return cont(forspec, comprehension); - if (type == "if") return cont(expression, comprehension); - } - - function isContinuedStatement(state, textAfter) { - return state.lastType == "operator" || state.lastType == "," || - isOperatorChar.test(textAfter.charAt(0)) || - /[,.]/.test(textAfter.charAt(0)); - } - - // Interface - - return { - startState: function(basecolumn) { - var state = { - tokenize: tokenBase, - lastType: "sof", - cc: [], - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), - localVars: parserConfig.localVars, - context: parserConfig.localVars && {vars: parserConfig.localVars}, - indented: basecolumn || 0 - }; - if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") - state.globalVars = parserConfig.globalVars; - return state; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = false; - state.indented = stream.indentation(); - findFatArrow(stream, state); - } - if (state.tokenize != tokenComment && stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; - return parseJS(state, style, type, content, stream); - }, - - indent: function(state, textAfter) { - if (state.tokenize == tokenComment) return CodeMirror.Pass; - if (state.tokenize != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; - // Kludge to prevent 'maybelse' from blocking lexical scope pops - if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { - var c = state.cc[i]; - if (c == poplex) lexical = lexical.prev; - else if (c != maybeelse) break; - } - if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; - if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") - lexical = lexical.prev; - var type = lexical.type, closing = firstChar == type; - - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); - else if (type == "form" && firstChar == "{") return lexical.indented; - else if (type == "form") return lexical.indented + indentUnit; - else if (type == "stat") - return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); - else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); - else if (lexical.align) return lexical.column + (closing ? 0 : 1); - else return lexical.indented + (closing ? 0 : indentUnit); - }, - - electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, - blockCommentStart: jsonMode ? null : "/*", - blockCommentEnd: jsonMode ? null : "*/", - lineComment: jsonMode ? null : "//", - fold: "brace", - closeBrackets: "()[]{}''\"\"``", - - helperType: jsonMode ? "json" : "javascript", - jsonldMode: jsonldMode, - jsonMode: jsonMode, - - expressionAllowed: expressionAllowed, - skipExpression: function(state) { - var top = state.cc[state.cc.length - 1] - if (top == expression || top == expressionNoComma) state.cc.pop() - } - }; -}); - -CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); - -CodeMirror.defineMIME("text/javascript", "javascript"); -CodeMirror.defineMIME("text/ecmascript", "javascript"); -CodeMirror.defineMIME("application/javascript", "javascript"); -CodeMirror.defineMIME("application/x-javascript", "javascript"); -CodeMirror.defineMIME("application/ecmascript", "javascript"); -CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); -CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); -CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// TODO actually recognize syntax of TypeScript constructs + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +function expressionAllowed(stream, state, backUp) { + return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) || + (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) +} + +CodeMirror.defineMode("javascript", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var statementIndent = parserConfig.statementIndent; + var jsonldMode = parserConfig.jsonld; + var jsonMode = parserConfig.json || jsonldMode; + var isTS = parserConfig.typescript; + var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "atom"}; + + var jsKeywords = { + "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, + "var": kw("var"), "const": kw("var"), "let": kw("var"), + "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, + "this": kw("this"), "class": kw("class"), "super": kw("atom"), + "yield": C, "export": kw("export"), "import": kw("import"), "extends": C + }; + + // Extend the 'normal' keywords with the TypeScript language extensions + if (isTS) { + var type = {type: "variable", style: "variable-3"}; + var tsKeywords = { + // object-like things + "interface": kw("class"), + "implements": C, + "namespace": C, + "module": kw("module"), + "enum": kw("module"), + + // scope modifiers + "public": kw("modifier"), + "private": kw("modifier"), + "protected": kw("modifier"), + "abstract": kw("modifier"), + + // operators + "as": operator, + + // types + "string": type, "number": type, "boolean": type, "any": type + }; + + for (var attr in tsKeywords) { + jsKeywords[attr] = tsKeywords[attr]; + } + } + + return jsKeywords; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|~^]/; + var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; + + function readRegexp(stream) { + var escaped = false, next, inSet = false; + while ((next = stream.next()) != null) { + if (!escaped) { + if (next == "/" && !inSet) return; + if (next == "[") inSet = true; + else if (inSet && next == "]") inSet = false; + } + escaped = !escaped && next == "\\"; + } + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { + return ret("number", "number"); + } else if (ch == "." && stream.match("..")) { + return ret("spread", "meta"); + } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + return ret(ch); + } else if (ch == "=" && stream.eat(">")) { + return ret("=>", "operator"); + } else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "number"); + } else if (ch == "0" && stream.eat(/o/i)) { + stream.eatWhile(/[0-7]/i); + return ret("number", "number"); + } else if (ch == "0" && stream.eat(/b/i)) { + stream.eatWhile(/[01]/i); + return ret("number", "number"); + } else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); + return ret("number", "number"); + } else if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "comment"); + } else if (expressionAllowed(stream, state, 1)) { + readRegexp(stream); + stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); + return ret("regexp", "string-2"); + } else { + stream.eatWhile(isOperatorChar); + return ret("operator", "operator", stream.current()); + } + } else if (ch == "`") { + state.tokenize = tokenQuasi; + return tokenQuasi(stream, state); + } else if (ch == "#") { + stream.skipToEnd(); + return ret("error", "error"); + } else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", "operator", stream.current()); + } else if (wordRE.test(ch)) { + stream.eatWhile(wordRE); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return (known && state.lastType != ".") ? ret(known.type, known.style, word) : + ret("variable", "variable", word); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next; + if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ + state.tokenize = tokenBase; + return ret("jsonld-keyword", "meta"); + } + while ((next = stream.next()) != null) { + if (next == quote && !escaped) break; + escaped = !escaped && next == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return ret("string", "string"); + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + function tokenQuasi(stream, state) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && next == "\\"; + } + return ret("quasi", "string-2", stream.current()); + } + + var brackets = "([{}])"; + // This is a crude lookahead trick to try and notice that we're + // parsing the argument patterns for a fat-arrow function before we + // actually hit the arrow token. It only works if the arrow is on + // the same line as the arguments and there's no strange noise + // (comments) in between. Fallback is to only notice when we hit the + // arrow, and not declare the arguments as locals for the arrow + // body. + function findFatArrow(stream, state) { + if (state.fatArrowAt) state.fatArrowAt = null; + var arrow = stream.string.indexOf("=>", stream.start); + if (arrow < 0) return; + + var depth = 0, sawSomething = false; + for (var pos = arrow - 1; pos >= 0; --pos) { + var ch = stream.string.charAt(pos); + var bracket = brackets.indexOf(ch); + if (bracket >= 0 && bracket < 3) { + if (!depth) { ++pos; break; } + if (--depth == 0) break; + } else if (bracket >= 3 && bracket < 6) { + ++depth; + } else if (wordRE.test(ch)) { + sawSomething = true; + } else if (/["'\/]/.test(ch)) { + return; + } else if (sawSomething && !depth) { + ++pos; + break; + } + } + if (sawSomething && !depth) state.fatArrowAt = pos; + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + for (var cx = state.context; cx; cx = cx.prev) { + for (var v = cx.vars; v; v = v.next) + if (v.name == varname) return true; + } + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "variable-2"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + function inList(list) { + for (var v = list; v; v = v.next) + if (v.name == varname) return true; + return false; + } + var state = cx.state; + cx.marked = "def"; + if (state.context) { + if (inList(state.localVars)) return; + state.localVars = {name: varname, next: state.localVars}; + } else { + if (inList(state.globalVars)) return; + if (parserConfig.globalVars) + state.globalVars = {name: varname, next: state.globalVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + cx.state.localVars = defaultVars; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state, indent = state.indented; + if (state.lexical.type == "stat") indent = state.lexical.indented; + else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) + indent = outer.indented; + state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + function exp(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(exp); + }; + return exp; + } + + function statement(type, value) { + if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "if") { + if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) + cx.state.cc.pop()(); + return cont(pushlex("form"), expression, statement, poplex, maybeelse); + } + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + if (type == "class") return cont(pushlex("form"), className, poplex); + if (type == "export") return cont(pushlex("stat"), afterExport, poplex); + if (type == "import") return cont(pushlex("stat"), afterImport, poplex); + if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex) + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + return expressionInner(type, false); + } + function expressionNoComma(type) { + return expressionInner(type, true); + } + function expressionInner(type, noComma) { + if (cx.state.fatArrowAt == cx.stream.start) { + var body = noComma ? arrowBodyNoComma : arrowBody; + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); + else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); + } + + var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; + if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); + if (type == "function") return cont(functiondef, maybeop); + if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); + if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); + if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); + if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); + if (type == "{") return contCommasep(objprop, "}", null, maybeop); + if (type == "quasi") return pass(quasi, maybeop); + if (type == "new") return cont(maybeTarget(noComma)); + return cont(); + } + function maybeexpression(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expression); + } + function maybeexpressionNoComma(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expressionNoComma); + } + + function maybeoperatorComma(type, value) { + if (type == ",") return cont(expression); + return maybeoperatorNoComma(type, value, false); + } + function maybeoperatorNoComma(type, value, noComma) { + var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; + var expr = noComma == false ? expression : expressionNoComma; + if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); + if (type == "operator") { + if (/\+\+|--/.test(value)) return cont(me); + if (value == "?") return cont(expression, expect(":"), expr); + return cont(expr); + } + if (type == "quasi") { return pass(quasi, me); } + if (type == ";") return; + if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); + if (type == ".") return cont(property, me); + if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); + } + function quasi(type, value) { + if (type != "quasi") return pass(); + if (value.slice(value.length - 2) != "${") return cont(quasi); + return cont(expression, continueQuasi); + } + function continueQuasi(type) { + if (type == "}") { + cx.marked = "string-2"; + cx.state.tokenize = tokenQuasi; + return cont(quasi); + } + } + function arrowBody(type) { + findFatArrow(cx.stream, cx.state); + return pass(type == "{" ? statement : expression); + } + function arrowBodyNoComma(type) { + findFatArrow(cx.stream, cx.state); + return pass(type == "{" ? statement : expressionNoComma); + } + function maybeTarget(noComma) { + return function(type) { + if (type == ".") return cont(noComma ? targetNoComma : target); + else return pass(noComma ? expressionNoComma : expression); + }; + } + function target(_, value) { + if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); } + } + function targetNoComma(_, value) { + if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); } + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperatorComma, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "property"; return cont();} + } + function objprop(type, value) { + if (type == "variable" || cx.style == "keyword") { + cx.marked = "property"; + if (value == "get" || value == "set") return cont(getterSetter); + return cont(afterprop); + } else if (type == "number" || type == "string") { + cx.marked = jsonldMode ? "property" : (cx.style + " property"); + return cont(afterprop); + } else if (type == "jsonld-keyword") { + return cont(afterprop); + } else if (type == "modifier") { + return cont(objprop) + } else if (type == "[") { + return cont(expression, expect("]"), afterprop); + } else if (type == "spread") { + return cont(expression); + } + } + function getterSetter(type) { + if (type != "variable") return pass(afterprop); + cx.marked = "property"; + return cont(functiondef); + } + function afterprop(type) { + if (type == ":") return cont(expressionNoComma); + if (type == "(") return pass(functiondef); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") { + var lex = cx.state.lexical; + if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; + return cont(what, proceed); + } + if (type == end) return cont(); + return cont(expect(end)); + } + return function(type) { + if (type == end) return cont(); + return pass(what, proceed); + }; + } + function contCommasep(what, end, info) { + for (var i = 3; i < arguments.length; i++) + cx.cc.push(arguments[i]); + return cont(pushlex(end, info), commasep(what, end), poplex); + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function maybetype(type) { + if (isTS && type == ":") return cont(typedef); + } + function maybedefault(_, value) { + if (value == "=") return cont(expressionNoComma); + } + function typedef(type) { + if (type == "variable") {cx.marked = "variable-3"; return cont();} + } + function vardef() { + return pass(pattern, maybetype, maybeAssign, vardefCont); + } + function pattern(type, value) { + if (type == "modifier") return cont(pattern) + if (type == "variable") { register(value); return cont(); } + if (type == "spread") return cont(pattern); + if (type == "[") return contCommasep(pattern, "]"); + if (type == "{") return contCommasep(proppattern, "}"); + } + function proppattern(type, value) { + if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { + register(value); + return cont(maybeAssign); + } + if (type == "variable") cx.marked = "property"; + if (type == "spread") return cont(pattern); + if (type == "}") return pass(); + return cont(expect(":"), pattern, maybeAssign); + } + function maybeAssign(_type, value) { + if (value == "=") return cont(expressionNoComma); + } + function vardefCont(type) { + if (type == ",") return cont(vardef); + } + function maybeelse(type, value) { + if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); + } + function forspec(type) { + if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); + } + function forspec1(type) { + if (type == "var") return cont(vardef, expect(";"), forspec2); + if (type == ";") return cont(forspec2); + if (type == "variable") return cont(formaybeinof); + return pass(expression, expect(";"), forspec2); + } + function formaybeinof(_type, value) { + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return cont(maybeoperatorComma, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return pass(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); + } + function funarg(type) { + if (type == "spread") return cont(funarg); + return pass(pattern, maybetype, maybedefault); + } + function className(type, value) { + if (type == "variable") {register(value); return cont(classNameAfter);} + } + function classNameAfter(type, value) { + if (value == "extends") return cont(expression, classNameAfter); + if (type == "{") return cont(pushlex("}"), classBody, poplex); + } + function classBody(type, value) { + if (type == "variable" || cx.style == "keyword") { + if (value == "static") { + cx.marked = "keyword"; + return cont(classBody); + } + cx.marked = "property"; + if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); + return cont(functiondef, classBody); + } + if (value == "*") { + cx.marked = "keyword"; + return cont(classBody); + } + if (type == ";") return cont(classBody); + if (type == "}") return cont(); + } + function classGetterSetter(type) { + if (type != "variable") return pass(); + cx.marked = "property"; + return cont(); + } + function afterExport(_type, value) { + if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } + if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } + return pass(statement); + } + function afterImport(type) { + if (type == "string") return cont(); + return pass(importSpec, maybeFrom); + } + function importSpec(type, value) { + if (type == "{") return contCommasep(importSpec, "}"); + if (type == "variable") register(value); + if (value == "*") cx.marked = "keyword"; + return cont(maybeAs); + } + function maybeAs(_type, value) { + if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } + } + function maybeFrom(_type, value) { + if (value == "from") { cx.marked = "keyword"; return cont(expression); } + } + function arrayLiteral(type) { + if (type == "]") return cont(); + return pass(expressionNoComma, maybeArrayComprehension); + } + function maybeArrayComprehension(type) { + if (type == "for") return pass(comprehension, expect("]")); + if (type == ",") return cont(commasep(maybeexpressionNoComma, "]")); + return pass(commasep(expressionNoComma, "]")); + } + function comprehension(type) { + if (type == "for") return cont(forspec, comprehension); + if (type == "if") return cont(expression, comprehension); + } + + function isContinuedStatement(state, textAfter) { + return state.lastType == "operator" || state.lastType == "," || + isOperatorChar.test(textAfter.charAt(0)) || + /[,.]/.test(textAfter.charAt(0)); + } + + // Interface + + return { + startState: function(basecolumn) { + var state = { + tokenize: tokenBase, + lastType: "sof", + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: parserConfig.localVars, + context: parserConfig.localVars && {vars: parserConfig.localVars}, + indented: basecolumn || 0 + }; + if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") + state.globalVars = parserConfig.globalVars; + return state; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + findFatArrow(stream, state); + } + if (state.tokenize != tokenComment && stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize == tokenComment) return CodeMirror.Pass; + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; + // Kludge to prevent 'maybelse' from blocking lexical scope pops + if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { + var c = state.cc[i]; + if (c == poplex) lexical = lexical.prev; + else if (c != maybeelse) break; + } + if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; + if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") + lexical = lexical.prev; + var type = lexical.type, closing = firstChar == type; + + if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "form") return lexical.indented + indentUnit; + else if (type == "stat") + return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); + else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, + blockCommentStart: jsonMode ? null : "/*", + blockCommentEnd: jsonMode ? null : "*/", + lineComment: jsonMode ? null : "//", + fold: "brace", + closeBrackets: "()[]{}''\"\"``", + + helperType: jsonMode ? "json" : "javascript", + jsonldMode: jsonldMode, + jsonMode: jsonMode, + + expressionAllowed: expressionAllowed, + skipExpression: function(state) { + var top = state.cc[state.cc.length - 1] + if (top == expression || top == expressionNoComma) state.cc.pop() + } + }; +}); + +CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); + +CodeMirror.defineMIME("text/javascript", "javascript"); +CodeMirror.defineMIME("text/ecmascript", "javascript"); +CodeMirror.defineMIME("application/javascript", "javascript"); +CodeMirror.defineMIME("application/x-javascript", "javascript"); +CodeMirror.defineMIME("application/ecmascript", "javascript"); +CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); +CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); +CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); + +}); diff --git a/shared/codemirror/mode/jsx/jsx.js b/shared/codemirror/mode/jsx/jsx.js index aff01b8..e18d0b2 100644 --- a/shared/codemirror/mode/jsx/jsx.js +++ b/shared/codemirror/mode/jsx/jsx.js @@ -1,147 +1,147 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript")) - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod) - else // Plain browser env - mod(CodeMirror) -})(function(CodeMirror) { - "use strict" - - // Depth means the amount of open braces in JS context, in XML - // context 0 means not in tag, 1 means in tag, and 2 means in tag - // and js block comment. - function Context(state, mode, depth, prev) { - this.state = state; this.mode = mode; this.depth = depth; this.prev = prev - } - - function copyContext(context) { - return new Context(CodeMirror.copyState(context.mode, context.state), - context.mode, - context.depth, - context.prev && copyContext(context.prev)) - } - - CodeMirror.defineMode("jsx", function(config, modeConfig) { - var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false}) - var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript") - - function flatXMLIndent(state) { - var tagName = state.tagName - state.tagName = null - var result = xmlMode.indent(state, "") - state.tagName = tagName - return result - } - - function token(stream, state) { - if (state.context.mode == xmlMode) - return xmlToken(stream, state, state.context) - else - return jsToken(stream, state, state.context) - } - - function xmlToken(stream, state, cx) { - if (cx.depth == 2) { // Inside a JS /* */ comment - if (stream.match(/^.*?\*\//)) cx.depth = 1 - else stream.skipToEnd() - return "comment" - } - - if (stream.peek() == "{") { - xmlMode.skipAttribute(cx.state) - - var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context - // If JS starts on same line as tag - if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) { - while (xmlContext.prev && !xmlContext.startOfLine) - xmlContext = xmlContext.prev - // If tag starts the line, use XML indentation level - if (xmlContext.startOfLine) indent -= config.indentUnit - // Else use JS indentation level - else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented - // Else if inside of tag - } else if (cx.depth == 1) { - indent += config.indentUnit - } - - state.context = new Context(CodeMirror.startState(jsMode, indent), - jsMode, 0, state.context) - return null - } - - if (cx.depth == 1) { // Inside of tag - if (stream.peek() == "<") { // Tag inside of tag - xmlMode.skipAttribute(cx.state) - state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)), - xmlMode, 0, state.context) - return null - } else if (stream.match("//")) { - stream.skipToEnd() - return "comment" - } else if (stream.match("/*")) { - cx.depth = 2 - return token(stream, state) - } - } - - var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop - if (/\btag\b/.test(style)) { - if (/>$/.test(cur)) { - if (cx.state.context) cx.depth = 0 - else state.context = state.context.prev - } else if (/^ -1) { - stream.backUp(cur.length - stop) - } - return style - } - - function jsToken(stream, state, cx) { - if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) { - jsMode.skipExpression(cx.state) - state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")), - xmlMode, 0, state.context) - return null - } - - var style = jsMode.token(stream, cx.state) - if (!style && cx.depth != null) { - var cur = stream.current() - if (cur == "{") { - cx.depth++ - } else if (cur == "}") { - if (--cx.depth == 0) state.context = state.context.prev - } - } - return style - } - - return { - startState: function() { - return {context: new Context(CodeMirror.startState(jsMode), jsMode)} - }, - - copyState: function(state) { - return {context: copyContext(state.context)} - }, - - token: token, - - indent: function(state, textAfter, fullLine) { - return state.context.mode.indent(state.context.state, textAfter, fullLine) - }, - - innerMode: function(state) { - return state.context - } - } - }, "xml", "javascript") - - CodeMirror.defineMIME("text/jsx", "jsx") -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript")) + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod) + else // Plain browser env + mod(CodeMirror) +})(function(CodeMirror) { + "use strict" + + // Depth means the amount of open braces in JS context, in XML + // context 0 means not in tag, 1 means in tag, and 2 means in tag + // and js block comment. + function Context(state, mode, depth, prev) { + this.state = state; this.mode = mode; this.depth = depth; this.prev = prev + } + + function copyContext(context) { + return new Context(CodeMirror.copyState(context.mode, context.state), + context.mode, + context.depth, + context.prev && copyContext(context.prev)) + } + + CodeMirror.defineMode("jsx", function(config, modeConfig) { + var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false}) + var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript") + + function flatXMLIndent(state) { + var tagName = state.tagName + state.tagName = null + var result = xmlMode.indent(state, "") + state.tagName = tagName + return result + } + + function token(stream, state) { + if (state.context.mode == xmlMode) + return xmlToken(stream, state, state.context) + else + return jsToken(stream, state, state.context) + } + + function xmlToken(stream, state, cx) { + if (cx.depth == 2) { // Inside a JS /* */ comment + if (stream.match(/^.*?\*\//)) cx.depth = 1 + else stream.skipToEnd() + return "comment" + } + + if (stream.peek() == "{") { + xmlMode.skipAttribute(cx.state) + + var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context + // If JS starts on same line as tag + if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) { + while (xmlContext.prev && !xmlContext.startOfLine) + xmlContext = xmlContext.prev + // If tag starts the line, use XML indentation level + if (xmlContext.startOfLine) indent -= config.indentUnit + // Else use JS indentation level + else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented + // Else if inside of tag + } else if (cx.depth == 1) { + indent += config.indentUnit + } + + state.context = new Context(CodeMirror.startState(jsMode, indent), + jsMode, 0, state.context) + return null + } + + if (cx.depth == 1) { // Inside of tag + if (stream.peek() == "<") { // Tag inside of tag + xmlMode.skipAttribute(cx.state) + state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)), + xmlMode, 0, state.context) + return null + } else if (stream.match("//")) { + stream.skipToEnd() + return "comment" + } else if (stream.match("/*")) { + cx.depth = 2 + return token(stream, state) + } + } + + var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop + if (/\btag\b/.test(style)) { + if (/>$/.test(cur)) { + if (cx.state.context) cx.depth = 0 + else state.context = state.context.prev + } else if (/^ -1) { + stream.backUp(cur.length - stop) + } + return style + } + + function jsToken(stream, state, cx) { + if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) { + jsMode.skipExpression(cx.state) + state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")), + xmlMode, 0, state.context) + return null + } + + var style = jsMode.token(stream, cx.state) + if (!style && cx.depth != null) { + var cur = stream.current() + if (cur == "{") { + cx.depth++ + } else if (cur == "}") { + if (--cx.depth == 0) state.context = state.context.prev + } + } + return style + } + + return { + startState: function() { + return {context: new Context(CodeMirror.startState(jsMode), jsMode)} + }, + + copyState: function(state) { + return {context: copyContext(state.context)} + }, + + token: token, + + indent: function(state, textAfter, fullLine) { + return state.context.mode.indent(state.context.state, textAfter, fullLine) + }, + + innerMode: function(state) { + return state.context + } + } + }, "xml", "javascript") + + CodeMirror.defineMIME("text/jsx", "jsx") +}); diff --git a/shared/codemirror/mode/markdown/markdown.js b/shared/codemirror/mode/markdown/markdown.js index 8bd3cc7..636cf4c 100644 --- a/shared/codemirror/mode/markdown/markdown.js +++ b/shared/codemirror/mode/markdown/markdown.js @@ -1,807 +1,807 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "../xml/xml", "../meta"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { - - var htmlMode = CodeMirror.getMode(cmCfg, "text/html"); - var htmlModeMissing = htmlMode.name == "null" - - function getMode(name) { - if (CodeMirror.findModeByName) { - var found = CodeMirror.findModeByName(name); - if (found) name = found.mime || found.mimes[0]; - } - var mode = CodeMirror.getMode(cmCfg, name); - return mode.name == "null" ? null : mode; - } - - // Should characters that affect highlighting be highlighted separate? - // Does not include characters that will be output (such as `1.` and `-` for lists) - if (modeCfg.highlightFormatting === undefined) - modeCfg.highlightFormatting = false; - - // Maximum number of nested blockquotes. Set to 0 for infinite nesting. - // Excess `>` will emit `error` token. - if (modeCfg.maxBlockquoteDepth === undefined) - modeCfg.maxBlockquoteDepth = 0; - - // Should underscores in words open/close em/strong? - if (modeCfg.underscoresBreakWords === undefined) - modeCfg.underscoresBreakWords = true; - - // Use `fencedCodeBlocks` to configure fenced code blocks. false to - // disable, string to specify a precise regexp that the fence should - // match, and true to allow three or more backticks or tildes (as - // per CommonMark). - - // Turn on task lists? ("- [ ] " and "- [x] ") - if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; - - // Turn on strikethrough syntax - if (modeCfg.strikethrough === undefined) - modeCfg.strikethrough = false; - - // Allow token types to be overridden by user-provided token types. - if (modeCfg.tokenTypeOverrides === undefined) - modeCfg.tokenTypeOverrides = {}; - - var tokenTypes = { - header: "header", - code: "comment", - quote: "quote", - list1: "variable-2", - list2: "variable-3", - list3: "keyword", - hr: "hr", - image: "tag", - formatting: "formatting", - linkInline: "link", - linkEmail: "link", - linkText: "link", - linkHref: "string", - em: "em", - strong: "strong", - strikethrough: "strikethrough" - }; - - for (var tokenType in tokenTypes) { - if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { - tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; - } - } - - var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ - , ulRE = /^[*\-+]\s+/ - , olRE = /^[0-9]+([.)])\s+/ - , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE - , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ - , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/ - , textRE = /^[^#!\[\]*_\\<>` "'(~]+/ - , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) + - ")[ \\t]*([\\w+#\-]*)"); - - function switchInline(stream, state, f) { - state.f = state.inline = f; - return f(stream, state); - } - - function switchBlock(stream, state, f) { - state.f = state.block = f; - return f(stream, state); - } - - function lineIsEmpty(line) { - return !line || !/\S/.test(line.string) - } - - // Blocks - - function blankLine(state) { - // Reset linkTitle state - state.linkTitle = false; - // Reset EM state - state.em = false; - // Reset STRONG state - state.strong = false; - // Reset strikethrough state - state.strikethrough = false; - // Reset state.quote - state.quote = 0; - // Reset state.indentedCode - state.indentedCode = false; - if (htmlModeMissing && state.f == htmlBlock) { - state.f = inlineNormal; - state.block = blockNormal; - } - // Reset state.trailingSpace - state.trailingSpace = 0; - state.trailingSpaceNewLine = false; - // Mark this line as blank - state.prevLine = state.thisLine - state.thisLine = null - return null; - } - - function blockNormal(stream, state) { - - var sol = stream.sol(); - - var prevLineIsList = state.list !== false, - prevLineIsIndentedCode = state.indentedCode; - - state.indentedCode = false; - - if (prevLineIsList) { - if (state.indentationDiff >= 0) { // Continued list - if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block - state.indentation -= state.indentationDiff; - } - state.list = null; - } else if (state.indentation > 0) { - state.list = null; - } else { // No longer a list - state.list = false; - } - } - - var match = null; - if (state.indentationDiff >= 4) { - stream.skipToEnd(); - if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) { - state.indentation -= 4; - state.indentedCode = true; - return tokenTypes.code; - } else { - return null; - } - } else if (stream.eatSpace()) { - return null; - } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) { - state.header = match[1].length; - if (modeCfg.highlightFormatting) state.formatting = "header"; - state.f = state.inline; - return getType(state); - } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList && - !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) { - state.header = match[0].charAt(0) == '=' ? 1 : 2; - if (modeCfg.highlightFormatting) state.formatting = "header"; - state.f = state.inline; - return getType(state); - } else if (stream.eat('>')) { - state.quote = sol ? 1 : state.quote + 1; - if (modeCfg.highlightFormatting) state.formatting = "quote"; - stream.eatSpace(); - return getType(state); - } else if (stream.peek() === '[') { - return switchInline(stream, state, footnoteLink); - } else if (stream.match(hrRE, true)) { - state.hr = true; - return tokenTypes.hr; - } else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) { - var listType = null; - if (stream.match(ulRE, true)) { - listType = 'ul'; - } else { - stream.match(olRE, true); - listType = 'ol'; - } - state.indentation = stream.column() + stream.current().length; - state.list = true; - - // While this list item's marker's indentation - // is less than the deepest list item's content's indentation, - // pop the deepest list item indentation off the stack. - while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) { - state.listStack.pop(); - } - - // Add this list item's content's indentation to the stack - state.listStack.push(state.indentation); - - if (modeCfg.taskLists && stream.match(taskListRE, false)) { - state.taskList = true; - } - state.f = state.inline; - if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; - return getType(state); - } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) { - state.fencedChars = match[1] - // try switching mode - state.localMode = getMode(match[2]); - if (state.localMode) state.localState = state.localMode.startState(); - state.f = state.block = local; - if (modeCfg.highlightFormatting) state.formatting = "code-block"; - state.code = -1 - return getType(state); - } - - return switchInline(stream, state, state.inline); - } - - function htmlBlock(stream, state) { - var style = htmlMode.token(stream, state.htmlState); - if (!htmlModeMissing) { - var inner = CodeMirror.innerMode(htmlMode, state.htmlState) - if ((inner.mode.name == "xml" && inner.state.tagStart === null && - (!inner.state.context && inner.state.tokenize.isInText)) || - (state.md_inside && stream.current().indexOf(">") > -1)) { - state.f = inlineNormal; - state.block = blockNormal; - state.htmlState = null; - } - } - return style; - } - - function local(stream, state) { - if (state.fencedChars && stream.match(state.fencedChars, false)) { - state.localMode = state.localState = null; - state.f = state.block = leavingLocal; - return null; - } else if (state.localMode) { - return state.localMode.token(stream, state.localState); - } else { - stream.skipToEnd(); - return tokenTypes.code; - } - } - - function leavingLocal(stream, state) { - stream.match(state.fencedChars); - state.block = blockNormal; - state.f = inlineNormal; - state.fencedChars = null; - if (modeCfg.highlightFormatting) state.formatting = "code-block"; - state.code = 1 - var returnType = getType(state); - state.code = 0 - return returnType; - } - - // Inline - function getType(state) { - var styles = []; - - if (state.formatting) { - styles.push(tokenTypes.formatting); - - if (typeof state.formatting === "string") state.formatting = [state.formatting]; - - for (var i = 0; i < state.formatting.length; i++) { - styles.push(tokenTypes.formatting + "-" + state.formatting[i]); - - if (state.formatting[i] === "header") { - styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); - } - - // Add `formatting-quote` and `formatting-quote-#` for blockquotes - // Add `error` instead if the maximum blockquote nesting depth is passed - if (state.formatting[i] === "quote") { - if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { - styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); - } else { - styles.push("error"); - } - } - } - } - - if (state.taskOpen) { - styles.push("meta"); - return styles.length ? styles.join(' ') : null; - } - if (state.taskClosed) { - styles.push("property"); - return styles.length ? styles.join(' ') : null; - } - - if (state.linkHref) { - styles.push(tokenTypes.linkHref, "url"); - } else { // Only apply inline styles to non-url text - if (state.strong) { styles.push(tokenTypes.strong); } - if (state.em) { styles.push(tokenTypes.em); } - if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } - if (state.linkText) { styles.push(tokenTypes.linkText); } - if (state.code) { styles.push(tokenTypes.code); } - } - - if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); } - - if (state.quote) { - styles.push(tokenTypes.quote); - - // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth - if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { - styles.push(tokenTypes.quote + "-" + state.quote); - } else { - styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); - } - } - - if (state.list !== false) { - var listMod = (state.listStack.length - 1) % 3; - if (!listMod) { - styles.push(tokenTypes.list1); - } else if (listMod === 1) { - styles.push(tokenTypes.list2); - } else { - styles.push(tokenTypes.list3); - } - } - - if (state.trailingSpaceNewLine) { - styles.push("trailing-space-new-line"); - } else if (state.trailingSpace) { - styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); - } - - return styles.length ? styles.join(' ') : null; - } - - function handleText(stream, state) { - if (stream.match(textRE, true)) { - return getType(state); - } - return undefined; - } - - function inlineNormal(stream, state) { - var style = state.text(stream, state); - if (typeof style !== 'undefined') - return style; - - if (state.list) { // List marker (*, +, -, 1., etc) - state.list = null; - return getType(state); - } - - if (state.taskList) { - var taskOpen = stream.match(taskListRE, true)[1] !== "x"; - if (taskOpen) state.taskOpen = true; - else state.taskClosed = true; - if (modeCfg.highlightFormatting) state.formatting = "task"; - state.taskList = false; - return getType(state); - } - - state.taskOpen = false; - state.taskClosed = false; - - if (state.header && stream.match(/^#+$/, true)) { - if (modeCfg.highlightFormatting) state.formatting = "header"; - return getType(state); - } - - // Get sol() value now, before character is consumed - var sol = stream.sol(); - - var ch = stream.next(); - - // Matches link titles present on next line - if (state.linkTitle) { - state.linkTitle = false; - var matchCh = ch; - if (ch === '(') { - matchCh = ')'; - } - matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); - var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; - if (stream.match(new RegExp(regex), true)) { - return tokenTypes.linkHref; - } - } - - // If this block is changed, it may need to be updated in GFM mode - if (ch === '`') { - var previousFormatting = state.formatting; - if (modeCfg.highlightFormatting) state.formatting = "code"; - stream.eatWhile('`'); - var count = stream.current().length - if (state.code == 0) { - state.code = count - return getType(state) - } else if (count == state.code) { // Must be exact - var t = getType(state) - state.code = 0 - return t - } else { - state.formatting = previousFormatting - return getType(state) - } - } else if (state.code) { - return getType(state); - } - - if (ch === '\\') { - stream.next(); - if (modeCfg.highlightFormatting) { - var type = getType(state); - var formattingEscape = tokenTypes.formatting + "-escape"; - return type ? type + " " + formattingEscape : formattingEscape; - } - } - - if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { - stream.match(/\[[^\]]*\]/); - state.inline = state.f = linkHref; - return tokenTypes.image; - } - - if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) { - state.linkText = true; - if (modeCfg.highlightFormatting) state.formatting = "link"; - return getType(state); - } - - if (ch === ']' && state.linkText && stream.match(/\(.*\)| ?\[.*\]/, false)) { - if (modeCfg.highlightFormatting) state.formatting = "link"; - var type = getType(state); - state.linkText = false; - state.inline = state.f = linkHref; - return type; - } - - if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { - state.f = state.inline = linkInline; - if (modeCfg.highlightFormatting) state.formatting = "link"; - var type = getType(state); - if (type){ - type += " "; - } else { - type = ""; - } - return type + tokenTypes.linkInline; - } - - if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { - state.f = state.inline = linkInline; - if (modeCfg.highlightFormatting) state.formatting = "link"; - var type = getType(state); - if (type){ - type += " "; - } else { - type = ""; - } - return type + tokenTypes.linkEmail; - } - - if (ch === '<' && stream.match(/^(!--|\w)/, false)) { - var end = stream.string.indexOf(">", stream.pos); - if (end != -1) { - var atts = stream.string.substring(stream.start, end); - if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; - } - stream.backUp(1); - state.htmlState = CodeMirror.startState(htmlMode); - return switchBlock(stream, state, htmlBlock); - } - - if (ch === '<' && stream.match(/^\/\w*?>/)) { - state.md_inside = false; - return "tag"; - } - - var ignoreUnderscore = false; - if (!modeCfg.underscoresBreakWords) { - if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) { - var prevPos = stream.pos - 2; - if (prevPos >= 0) { - var prevCh = stream.string.charAt(prevPos); - if (prevCh !== '_' && prevCh.match(/(\w)/, false)) { - ignoreUnderscore = true; - } - } - } - } - if (ch === '*' || (ch === '_' && !ignoreUnderscore)) { - if (sol && stream.peek() === ' ') { - // Do nothing, surrounded by newline and space - } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG - if (modeCfg.highlightFormatting) state.formatting = "strong"; - var t = getType(state); - state.strong = false; - return t; - } else if (!state.strong && stream.eat(ch)) { // Add STRONG - state.strong = ch; - if (modeCfg.highlightFormatting) state.formatting = "strong"; - return getType(state); - } else if (state.em === ch) { // Remove EM - if (modeCfg.highlightFormatting) state.formatting = "em"; - var t = getType(state); - state.em = false; - return t; - } else if (!state.em) { // Add EM - state.em = ch; - if (modeCfg.highlightFormatting) state.formatting = "em"; - return getType(state); - } - } else if (ch === ' ') { - if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces - if (stream.peek() === ' ') { // Surrounded by spaces, ignore - return getType(state); - } else { // Not surrounded by spaces, back up pointer - stream.backUp(1); - } - } - } - - if (modeCfg.strikethrough) { - if (ch === '~' && stream.eatWhile(ch)) { - if (state.strikethrough) {// Remove strikethrough - if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; - var t = getType(state); - state.strikethrough = false; - return t; - } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough - state.strikethrough = true; - if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; - return getType(state); - } - } else if (ch === ' ') { - if (stream.match(/^~~/, true)) { // Probably surrounded by space - if (stream.peek() === ' ') { // Surrounded by spaces, ignore - return getType(state); - } else { // Not surrounded by spaces, back up pointer - stream.backUp(2); - } - } - } - } - - if (ch === ' ') { - if (stream.match(/ +$/, false)) { - state.trailingSpace++; - } else if (state.trailingSpace) { - state.trailingSpaceNewLine = true; - } - } - - return getType(state); - } - - function linkInline(stream, state) { - var ch = stream.next(); - - if (ch === ">") { - state.f = state.inline = inlineNormal; - if (modeCfg.highlightFormatting) state.formatting = "link"; - var type = getType(state); - if (type){ - type += " "; - } else { - type = ""; - } - return type + tokenTypes.linkInline; - } - - stream.match(/^[^>]+/, true); - - return tokenTypes.linkInline; - } - - function linkHref(stream, state) { - // Check if space, and return NULL if so (to avoid marking the space) - if(stream.eatSpace()){ - return null; - } - var ch = stream.next(); - if (ch === '(' || ch === '[') { - state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); - if (modeCfg.highlightFormatting) state.formatting = "link-string"; - state.linkHref = true; - return getType(state); - } - return 'error'; - } - - function getLinkHrefInside(endChar) { - return function(stream, state) { - var ch = stream.next(); - - if (ch === endChar) { - state.f = state.inline = inlineNormal; - if (modeCfg.highlightFormatting) state.formatting = "link-string"; - var returnState = getType(state); - state.linkHref = false; - return returnState; - } - - if (stream.match(inlineRE(endChar), true)) { - stream.backUp(1); - } - - state.linkHref = true; - return getType(state); - }; - } - - function footnoteLink(stream, state) { - if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { - state.f = footnoteLinkInside; - stream.next(); // Consume [ - if (modeCfg.highlightFormatting) state.formatting = "link"; - state.linkText = true; - return getType(state); - } - return switchInline(stream, state, inlineNormal); - } - - function footnoteLinkInside(stream, state) { - if (stream.match(/^\]:/, true)) { - state.f = state.inline = footnoteUrl; - if (modeCfg.highlightFormatting) state.formatting = "link"; - var returnType = getType(state); - state.linkText = false; - return returnType; - } - - stream.match(/^([^\]\\]|\\.)+/, true); - - return tokenTypes.linkText; - } - - function footnoteUrl(stream, state) { - // Check if space, and return NULL if so (to avoid marking the space) - if(stream.eatSpace()){ - return null; - } - // Match URL - stream.match(/^[^\s]+/, true); - // Check for link title - if (stream.peek() === undefined) { // End of line, set flag to check next line - state.linkTitle = true; - } else { // More content on line, check if link title - stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); - } - state.f = state.inline = inlineNormal; - return tokenTypes.linkHref + " url"; - } - - var savedInlineRE = []; - function inlineRE(endChar) { - if (!savedInlineRE[endChar]) { - // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741) - endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); - // Match any non-endChar, escaped character, as well as the closing - // endChar. - savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')'); - } - return savedInlineRE[endChar]; - } - - var mode = { - startState: function() { - return { - f: blockNormal, - - prevLine: null, - thisLine: null, - - block: blockNormal, - htmlState: null, - indentation: 0, - - inline: inlineNormal, - text: handleText, - - formatting: false, - linkText: false, - linkHref: false, - linkTitle: false, - code: 0, - em: false, - strong: false, - header: 0, - hr: false, - taskList: false, - list: false, - listStack: [], - quote: 0, - trailingSpace: 0, - trailingSpaceNewLine: false, - strikethrough: false, - fencedChars: null - }; - }, - - copyState: function(s) { - return { - f: s.f, - - prevLine: s.prevLine, - thisLine: s.thisLine, - - block: s.block, - htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState), - indentation: s.indentation, - - localMode: s.localMode, - localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null, - - inline: s.inline, - text: s.text, - formatting: false, - linkTitle: s.linkTitle, - code: s.code, - em: s.em, - strong: s.strong, - strikethrough: s.strikethrough, - header: s.header, - hr: s.hr, - taskList: s.taskList, - list: s.list, - listStack: s.listStack.slice(0), - quote: s.quote, - indentedCode: s.indentedCode, - trailingSpace: s.trailingSpace, - trailingSpaceNewLine: s.trailingSpaceNewLine, - md_inside: s.md_inside, - fencedChars: s.fencedChars - }; - }, - - token: function(stream, state) { - - // Reset state.formatting - state.formatting = false; - - if (stream != state.thisLine) { - var forceBlankLine = state.header || state.hr; - - // Reset state.header and state.hr - state.header = 0; - state.hr = false; - - if (stream.match(/^\s*$/, true) || forceBlankLine) { - blankLine(state); - if (!forceBlankLine) return null - state.prevLine = null - } - - state.prevLine = state.thisLine - state.thisLine = stream - - // Reset state.taskList - state.taskList = false; - - // Reset state.trailingSpace - state.trailingSpace = 0; - state.trailingSpaceNewLine = false; - - state.f = state.block; - var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length; - state.indentationDiff = Math.min(indentation - state.indentation, 4); - state.indentation = state.indentation + state.indentationDiff; - if (indentation > 0) return null; - } - return state.f(stream, state); - }, - - innerMode: function(state) { - if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode}; - if (state.localState) return {state: state.localState, mode: state.localMode}; - return {state: state, mode: mode}; - }, - - blankLine: blankLine, - - getType: getType, - - fold: "markdown" - }; - return mode; -}, "xml"); - -CodeMirror.defineMIME("text/x-markdown", "markdown"); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../meta"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { + + var htmlMode = CodeMirror.getMode(cmCfg, "text/html"); + var htmlModeMissing = htmlMode.name == "null" + + function getMode(name) { + if (CodeMirror.findModeByName) { + var found = CodeMirror.findModeByName(name); + if (found) name = found.mime || found.mimes[0]; + } + var mode = CodeMirror.getMode(cmCfg, name); + return mode.name == "null" ? null : mode; + } + + // Should characters that affect highlighting be highlighted separate? + // Does not include characters that will be output (such as `1.` and `-` for lists) + if (modeCfg.highlightFormatting === undefined) + modeCfg.highlightFormatting = false; + + // Maximum number of nested blockquotes. Set to 0 for infinite nesting. + // Excess `>` will emit `error` token. + if (modeCfg.maxBlockquoteDepth === undefined) + modeCfg.maxBlockquoteDepth = 0; + + // Should underscores in words open/close em/strong? + if (modeCfg.underscoresBreakWords === undefined) + modeCfg.underscoresBreakWords = true; + + // Use `fencedCodeBlocks` to configure fenced code blocks. false to + // disable, string to specify a precise regexp that the fence should + // match, and true to allow three or more backticks or tildes (as + // per CommonMark). + + // Turn on task lists? ("- [ ] " and "- [x] ") + if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; + + // Turn on strikethrough syntax + if (modeCfg.strikethrough === undefined) + modeCfg.strikethrough = false; + + // Allow token types to be overridden by user-provided token types. + if (modeCfg.tokenTypeOverrides === undefined) + modeCfg.tokenTypeOverrides = {}; + + var tokenTypes = { + header: "header", + code: "comment", + quote: "quote", + list1: "variable-2", + list2: "variable-3", + list3: "keyword", + hr: "hr", + image: "tag", + formatting: "formatting", + linkInline: "link", + linkEmail: "link", + linkText: "link", + linkHref: "string", + em: "em", + strong: "strong", + strikethrough: "strikethrough" + }; + + for (var tokenType in tokenTypes) { + if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { + tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; + } + } + + var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ + , ulRE = /^[*\-+]\s+/ + , olRE = /^[0-9]+([.)])\s+/ + , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE + , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ + , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/ + , textRE = /^[^#!\[\]*_\\<>` "'(~]+/ + , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) + + ")[ \\t]*([\\w+#\-]*)"); + + function switchInline(stream, state, f) { + state.f = state.inline = f; + return f(stream, state); + } + + function switchBlock(stream, state, f) { + state.f = state.block = f; + return f(stream, state); + } + + function lineIsEmpty(line) { + return !line || !/\S/.test(line.string) + } + + // Blocks + + function blankLine(state) { + // Reset linkTitle state + state.linkTitle = false; + // Reset EM state + state.em = false; + // Reset STRONG state + state.strong = false; + // Reset strikethrough state + state.strikethrough = false; + // Reset state.quote + state.quote = 0; + // Reset state.indentedCode + state.indentedCode = false; + if (htmlModeMissing && state.f == htmlBlock) { + state.f = inlineNormal; + state.block = blockNormal; + } + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + // Mark this line as blank + state.prevLine = state.thisLine + state.thisLine = null + return null; + } + + function blockNormal(stream, state) { + + var sol = stream.sol(); + + var prevLineIsList = state.list !== false, + prevLineIsIndentedCode = state.indentedCode; + + state.indentedCode = false; + + if (prevLineIsList) { + if (state.indentationDiff >= 0) { // Continued list + if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block + state.indentation -= state.indentationDiff; + } + state.list = null; + } else if (state.indentation > 0) { + state.list = null; + } else { // No longer a list + state.list = false; + } + } + + var match = null; + if (state.indentationDiff >= 4) { + stream.skipToEnd(); + if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) { + state.indentation -= 4; + state.indentedCode = true; + return tokenTypes.code; + } else { + return null; + } + } else if (stream.eatSpace()) { + return null; + } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) { + state.header = match[1].length; + if (modeCfg.highlightFormatting) state.formatting = "header"; + state.f = state.inline; + return getType(state); + } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList && + !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) { + state.header = match[0].charAt(0) == '=' ? 1 : 2; + if (modeCfg.highlightFormatting) state.formatting = "header"; + state.f = state.inline; + return getType(state); + } else if (stream.eat('>')) { + state.quote = sol ? 1 : state.quote + 1; + if (modeCfg.highlightFormatting) state.formatting = "quote"; + stream.eatSpace(); + return getType(state); + } else if (stream.peek() === '[') { + return switchInline(stream, state, footnoteLink); + } else if (stream.match(hrRE, true)) { + state.hr = true; + return tokenTypes.hr; + } else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) { + var listType = null; + if (stream.match(ulRE, true)) { + listType = 'ul'; + } else { + stream.match(olRE, true); + listType = 'ol'; + } + state.indentation = stream.column() + stream.current().length; + state.list = true; + + // While this list item's marker's indentation + // is less than the deepest list item's content's indentation, + // pop the deepest list item indentation off the stack. + while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) { + state.listStack.pop(); + } + + // Add this list item's content's indentation to the stack + state.listStack.push(state.indentation); + + if (modeCfg.taskLists && stream.match(taskListRE, false)) { + state.taskList = true; + } + state.f = state.inline; + if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; + return getType(state); + } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) { + state.fencedChars = match[1] + // try switching mode + state.localMode = getMode(match[2]); + if (state.localMode) state.localState = state.localMode.startState(); + state.f = state.block = local; + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + state.code = -1 + return getType(state); + } + + return switchInline(stream, state, state.inline); + } + + function htmlBlock(stream, state) { + var style = htmlMode.token(stream, state.htmlState); + if (!htmlModeMissing) { + var inner = CodeMirror.innerMode(htmlMode, state.htmlState) + if ((inner.mode.name == "xml" && inner.state.tagStart === null && + (!inner.state.context && inner.state.tokenize.isInText)) || + (state.md_inside && stream.current().indexOf(">") > -1)) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } + } + return style; + } + + function local(stream, state) { + if (state.fencedChars && stream.match(state.fencedChars, false)) { + state.localMode = state.localState = null; + state.f = state.block = leavingLocal; + return null; + } else if (state.localMode) { + return state.localMode.token(stream, state.localState); + } else { + stream.skipToEnd(); + return tokenTypes.code; + } + } + + function leavingLocal(stream, state) { + stream.match(state.fencedChars); + state.block = blockNormal; + state.f = inlineNormal; + state.fencedChars = null; + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + state.code = 1 + var returnType = getType(state); + state.code = 0 + return returnType; + } + + // Inline + function getType(state) { + var styles = []; + + if (state.formatting) { + styles.push(tokenTypes.formatting); + + if (typeof state.formatting === "string") state.formatting = [state.formatting]; + + for (var i = 0; i < state.formatting.length; i++) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i]); + + if (state.formatting[i] === "header") { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); + } + + // Add `formatting-quote` and `formatting-quote-#` for blockquotes + // Add `error` instead if the maximum blockquote nesting depth is passed + if (state.formatting[i] === "quote") { + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); + } else { + styles.push("error"); + } + } + } + } + + if (state.taskOpen) { + styles.push("meta"); + return styles.length ? styles.join(' ') : null; + } + if (state.taskClosed) { + styles.push("property"); + return styles.length ? styles.join(' ') : null; + } + + if (state.linkHref) { + styles.push(tokenTypes.linkHref, "url"); + } else { // Only apply inline styles to non-url text + if (state.strong) { styles.push(tokenTypes.strong); } + if (state.em) { styles.push(tokenTypes.em); } + if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } + if (state.linkText) { styles.push(tokenTypes.linkText); } + if (state.code) { styles.push(tokenTypes.code); } + } + + if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); } + + if (state.quote) { + styles.push(tokenTypes.quote); + + // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.quote + "-" + state.quote); + } else { + styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); + } + } + + if (state.list !== false) { + var listMod = (state.listStack.length - 1) % 3; + if (!listMod) { + styles.push(tokenTypes.list1); + } else if (listMod === 1) { + styles.push(tokenTypes.list2); + } else { + styles.push(tokenTypes.list3); + } + } + + if (state.trailingSpaceNewLine) { + styles.push("trailing-space-new-line"); + } else if (state.trailingSpace) { + styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); + } + + return styles.length ? styles.join(' ') : null; + } + + function handleText(stream, state) { + if (stream.match(textRE, true)) { + return getType(state); + } + return undefined; + } + + function inlineNormal(stream, state) { + var style = state.text(stream, state); + if (typeof style !== 'undefined') + return style; + + if (state.list) { // List marker (*, +, -, 1., etc) + state.list = null; + return getType(state); + } + + if (state.taskList) { + var taskOpen = stream.match(taskListRE, true)[1] !== "x"; + if (taskOpen) state.taskOpen = true; + else state.taskClosed = true; + if (modeCfg.highlightFormatting) state.formatting = "task"; + state.taskList = false; + return getType(state); + } + + state.taskOpen = false; + state.taskClosed = false; + + if (state.header && stream.match(/^#+$/, true)) { + if (modeCfg.highlightFormatting) state.formatting = "header"; + return getType(state); + } + + // Get sol() value now, before character is consumed + var sol = stream.sol(); + + var ch = stream.next(); + + // Matches link titles present on next line + if (state.linkTitle) { + state.linkTitle = false; + var matchCh = ch; + if (ch === '(') { + matchCh = ')'; + } + matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; + if (stream.match(new RegExp(regex), true)) { + return tokenTypes.linkHref; + } + } + + // If this block is changed, it may need to be updated in GFM mode + if (ch === '`') { + var previousFormatting = state.formatting; + if (modeCfg.highlightFormatting) state.formatting = "code"; + stream.eatWhile('`'); + var count = stream.current().length + if (state.code == 0) { + state.code = count + return getType(state) + } else if (count == state.code) { // Must be exact + var t = getType(state) + state.code = 0 + return t + } else { + state.formatting = previousFormatting + return getType(state) + } + } else if (state.code) { + return getType(state); + } + + if (ch === '\\') { + stream.next(); + if (modeCfg.highlightFormatting) { + var type = getType(state); + var formattingEscape = tokenTypes.formatting + "-escape"; + return type ? type + " " + formattingEscape : formattingEscape; + } + } + + if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { + stream.match(/\[[^\]]*\]/); + state.inline = state.f = linkHref; + return tokenTypes.image; + } + + if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) { + state.linkText = true; + if (modeCfg.highlightFormatting) state.formatting = "link"; + return getType(state); + } + + if (ch === ']' && state.linkText && stream.match(/\(.*\)| ?\[.*\]/, false)) { + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + state.linkText = false; + state.inline = state.f = linkHref; + return type; + } + + if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkEmail; + } + + if (ch === '<' && stream.match(/^(!--|\w)/, false)) { + var end = stream.string.indexOf(">", stream.pos); + if (end != -1) { + var atts = stream.string.substring(stream.start, end); + if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; + } + stream.backUp(1); + state.htmlState = CodeMirror.startState(htmlMode); + return switchBlock(stream, state, htmlBlock); + } + + if (ch === '<' && stream.match(/^\/\w*?>/)) { + state.md_inside = false; + return "tag"; + } + + var ignoreUnderscore = false; + if (!modeCfg.underscoresBreakWords) { + if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) { + var prevPos = stream.pos - 2; + if (prevPos >= 0) { + var prevCh = stream.string.charAt(prevPos); + if (prevCh !== '_' && prevCh.match(/(\w)/, false)) { + ignoreUnderscore = true; + } + } + } + } + if (ch === '*' || (ch === '_' && !ignoreUnderscore)) { + if (sol && stream.peek() === ' ') { + // Do nothing, surrounded by newline and space + } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG + if (modeCfg.highlightFormatting) state.formatting = "strong"; + var t = getType(state); + state.strong = false; + return t; + } else if (!state.strong && stream.eat(ch)) { // Add STRONG + state.strong = ch; + if (modeCfg.highlightFormatting) state.formatting = "strong"; + return getType(state); + } else if (state.em === ch) { // Remove EM + if (modeCfg.highlightFormatting) state.formatting = "em"; + var t = getType(state); + state.em = false; + return t; + } else if (!state.em) { // Add EM + state.em = ch; + if (modeCfg.highlightFormatting) state.formatting = "em"; + return getType(state); + } + } else if (ch === ' ') { + if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(1); + } + } + } + + if (modeCfg.strikethrough) { + if (ch === '~' && stream.eatWhile(ch)) { + if (state.strikethrough) {// Remove strikethrough + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + var t = getType(state); + state.strikethrough = false; + return t; + } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough + state.strikethrough = true; + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + return getType(state); + } + } else if (ch === ' ') { + if (stream.match(/^~~/, true)) { // Probably surrounded by space + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(2); + } + } + } + } + + if (ch === ' ') { + if (stream.match(/ +$/, false)) { + state.trailingSpace++; + } else if (state.trailingSpace) { + state.trailingSpaceNewLine = true; + } + } + + return getType(state); + } + + function linkInline(stream, state) { + var ch = stream.next(); + + if (ch === ">") { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + stream.match(/^[^>]+/, true); + + return tokenTypes.linkInline; + } + + function linkHref(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if(stream.eatSpace()){ + return null; + } + var ch = stream.next(); + if (ch === '(' || ch === '[') { + state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + state.linkHref = true; + return getType(state); + } + return 'error'; + } + + function getLinkHrefInside(endChar) { + return function(stream, state) { + var ch = stream.next(); + + if (ch === endChar) { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + var returnState = getType(state); + state.linkHref = false; + return returnState; + } + + if (stream.match(inlineRE(endChar), true)) { + stream.backUp(1); + } + + state.linkHref = true; + return getType(state); + }; + } + + function footnoteLink(stream, state) { + if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { + state.f = footnoteLinkInside; + stream.next(); // Consume [ + if (modeCfg.highlightFormatting) state.formatting = "link"; + state.linkText = true; + return getType(state); + } + return switchInline(stream, state, inlineNormal); + } + + function footnoteLinkInside(stream, state) { + if (stream.match(/^\]:/, true)) { + state.f = state.inline = footnoteUrl; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var returnType = getType(state); + state.linkText = false; + return returnType; + } + + stream.match(/^([^\]\\]|\\.)+/, true); + + return tokenTypes.linkText; + } + + function footnoteUrl(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if(stream.eatSpace()){ + return null; + } + // Match URL + stream.match(/^[^\s]+/, true); + // Check for link title + if (stream.peek() === undefined) { // End of line, set flag to check next line + state.linkTitle = true; + } else { // More content on line, check if link title + stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); + } + state.f = state.inline = inlineNormal; + return tokenTypes.linkHref + " url"; + } + + var savedInlineRE = []; + function inlineRE(endChar) { + if (!savedInlineRE[endChar]) { + // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741) + endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); + // Match any non-endChar, escaped character, as well as the closing + // endChar. + savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')'); + } + return savedInlineRE[endChar]; + } + + var mode = { + startState: function() { + return { + f: blockNormal, + + prevLine: null, + thisLine: null, + + block: blockNormal, + htmlState: null, + indentation: 0, + + inline: inlineNormal, + text: handleText, + + formatting: false, + linkText: false, + linkHref: false, + linkTitle: false, + code: 0, + em: false, + strong: false, + header: 0, + hr: false, + taskList: false, + list: false, + listStack: [], + quote: 0, + trailingSpace: 0, + trailingSpaceNewLine: false, + strikethrough: false, + fencedChars: null + }; + }, + + copyState: function(s) { + return { + f: s.f, + + prevLine: s.prevLine, + thisLine: s.thisLine, + + block: s.block, + htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState), + indentation: s.indentation, + + localMode: s.localMode, + localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null, + + inline: s.inline, + text: s.text, + formatting: false, + linkTitle: s.linkTitle, + code: s.code, + em: s.em, + strong: s.strong, + strikethrough: s.strikethrough, + header: s.header, + hr: s.hr, + taskList: s.taskList, + list: s.list, + listStack: s.listStack.slice(0), + quote: s.quote, + indentedCode: s.indentedCode, + trailingSpace: s.trailingSpace, + trailingSpaceNewLine: s.trailingSpaceNewLine, + md_inside: s.md_inside, + fencedChars: s.fencedChars + }; + }, + + token: function(stream, state) { + + // Reset state.formatting + state.formatting = false; + + if (stream != state.thisLine) { + var forceBlankLine = state.header || state.hr; + + // Reset state.header and state.hr + state.header = 0; + state.hr = false; + + if (stream.match(/^\s*$/, true) || forceBlankLine) { + blankLine(state); + if (!forceBlankLine) return null + state.prevLine = null + } + + state.prevLine = state.thisLine + state.thisLine = stream + + // Reset state.taskList + state.taskList = false; + + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + + state.f = state.block; + var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length; + state.indentationDiff = Math.min(indentation - state.indentation, 4); + state.indentation = state.indentation + state.indentationDiff; + if (indentation > 0) return null; + } + return state.f(stream, state); + }, + + innerMode: function(state) { + if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode}; + if (state.localState) return {state: state.localState, mode: state.localMode}; + return {state: state, mode: mode}; + }, + + blankLine: blankLine, + + getType: getType, + + fold: "markdown" + }; + return mode; +}, "xml"); + +CodeMirror.defineMIME("text/x-markdown", "markdown"); + +}); diff --git a/shared/codemirror/mode/meta.js b/shared/codemirror/mode/meta.js index eb25e24..51401b9 100644 --- a/shared/codemirror/mode/meta.js +++ b/shared/codemirror/mode/meta.js @@ -1,208 +1,208 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.modeInfo = [ - {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]}, - {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]}, - {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]}, - {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i}, - {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]}, - {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]}, - {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]}, - {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]}, - {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]}, - {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]}, - {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]}, - {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]}, - {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/}, - {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]}, - {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]}, - {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]}, - {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]}, - {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]}, - {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]}, - {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]}, - {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]}, - {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]}, - {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]}, - {name: "Django", mime: "text/x-django", mode: "django"}, - {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/}, - {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]}, - {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]}, - {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"}, - {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]}, - {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]}, - {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]}, - {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]}, - {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]}, - {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]}, - {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]}, - {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]}, - {name: "FCL", mime: "text/x-fcl", mode: "fcl"}, - {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]}, - {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]}, - {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]}, - {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]}, - {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]}, - {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i}, - {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]}, - {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"]}, - {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]}, - {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]}, - {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]}, - {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]}, - {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]}, - {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]}, - {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]}, - {name: "HTTP", mime: "message/http", mode: "http"}, - {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]}, - {name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]}, - {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]}, - {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]}, - {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"], - mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]}, - {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]}, - {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]}, - {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]}, - {name: "Jinja2", mime: "null", mode: "jinja2"}, - {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]}, - {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]}, - {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]}, - {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]}, - {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]}, - {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]}, - {name: "mIRC", mime: "text/mirc", mode: "mirc"}, - {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"}, - {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]}, - {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]}, - {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]}, - {name: "MS SQL", mime: "text/x-mssql", mode: "sql"}, - {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]}, - {name: "MySQL", mime: "text/x-mysql", mode: "sql"}, - {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i}, - {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]}, - {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]}, - {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]}, - {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]}, - {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]}, - {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]}, - {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]}, - {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]}, - {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]}, - {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]}, - {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]}, - {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]}, - {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]}, - {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]}, - {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]}, - {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]}, - {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/}, - {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]}, - {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]}, - {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"], alias: ["rscript"]}, - {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]}, - {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"}, - {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]}, - {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]}, - {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]}, - {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]}, - {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]}, - {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]}, - {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]}, - {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]}, - {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/}, - {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]}, - {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]}, - {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]}, - {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]}, - {name: "Solr", mime: "text/x-solr", mode: "solr"}, - {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]}, - {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]}, - {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]}, - {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]}, - {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]}, - {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]}, - {name: "sTeX", mime: "text/x-stex", mode: "stex"}, - {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]}, - {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]}, - {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]}, - {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]}, - {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"}, - {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"}, - {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]}, - {name: "Tornado", mime: "text/x-tornado", mode: "tornado"}, - {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]}, - {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]}, - {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]}, - {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]}, - {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]}, - {name: "Twig", mime: "text/x-twig", mode: "twig"}, - {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]}, - {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]}, - {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]}, - {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]}, - {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]}, - {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]}, - {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]}, - {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]}, - {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]}, - {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]}, - {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}, - {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]}, - {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]}, - {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]} - ]; - // Ensure all modes have a mime property for backwards compatibility - for (var i = 0; i < CodeMirror.modeInfo.length; i++) { - var info = CodeMirror.modeInfo[i]; - if (info.mimes) info.mime = info.mimes[0]; - } - - CodeMirror.findModeByMIME = function(mime) { - mime = mime.toLowerCase(); - for (var i = 0; i < CodeMirror.modeInfo.length; i++) { - var info = CodeMirror.modeInfo[i]; - if (info.mime == mime) return info; - if (info.mimes) for (var j = 0; j < info.mimes.length; j++) - if (info.mimes[j] == mime) return info; - } - }; - - CodeMirror.findModeByExtension = function(ext) { - for (var i = 0; i < CodeMirror.modeInfo.length; i++) { - var info = CodeMirror.modeInfo[i]; - if (info.ext) for (var j = 0; j < info.ext.length; j++) - if (info.ext[j] == ext) return info; - } - }; - - CodeMirror.findModeByFileName = function(filename) { - for (var i = 0; i < CodeMirror.modeInfo.length; i++) { - var info = CodeMirror.modeInfo[i]; - if (info.file && info.file.test(filename)) return info; - } - var dot = filename.lastIndexOf("."); - var ext = dot > -1 && filename.substring(dot + 1, filename.length); - if (ext) return CodeMirror.findModeByExtension(ext); - }; - - CodeMirror.findModeByName = function(name) { - name = name.toLowerCase(); - for (var i = 0; i < CodeMirror.modeInfo.length; i++) { - var info = CodeMirror.modeInfo[i]; - if (info.name.toLowerCase() == name) return info; - if (info.alias) for (var j = 0; j < info.alias.length; j++) - if (info.alias[j].toLowerCase() == name) return info; - } - }; -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.modeInfo = [ + {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]}, + {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]}, + {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]}, + {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i}, + {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]}, + {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]}, + {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]}, + {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]}, + {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]}, + {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]}, + {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]}, + {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]}, + {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/}, + {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]}, + {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]}, + {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]}, + {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]}, + {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]}, + {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]}, + {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]}, + {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]}, + {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]}, + {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]}, + {name: "Django", mime: "text/x-django", mode: "django"}, + {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/}, + {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]}, + {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]}, + {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"}, + {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]}, + {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]}, + {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]}, + {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]}, + {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]}, + {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]}, + {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]}, + {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]}, + {name: "FCL", mime: "text/x-fcl", mode: "fcl"}, + {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]}, + {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90"]}, + {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]}, + {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]}, + {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]}, + {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i}, + {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]}, + {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"]}, + {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]}, + {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]}, + {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]}, + {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]}, + {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]}, + {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]}, + {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm"], alias: ["xhtml"]}, + {name: "HTTP", mime: "message/http", mode: "http"}, + {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]}, + {name: "Jade", mime: "text/x-jade", mode: "jade", ext: ["jade"]}, + {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]}, + {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]}, + {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"], + mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]}, + {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]}, + {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]}, + {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]}, + {name: "Jinja2", mime: "null", mode: "jinja2"}, + {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]}, + {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]}, + {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]}, + {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]}, + {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]}, + {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]}, + {name: "mIRC", mime: "text/mirc", mode: "mirc"}, + {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"}, + {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb"]}, + {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]}, + {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]}, + {name: "MS SQL", mime: "text/x-mssql", mode: "sql"}, + {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]}, + {name: "MySQL", mime: "text/x-mysql", mode: "sql"}, + {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i}, + {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]}, + {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]}, + {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]}, + {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]}, + {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]}, + {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]}, + {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]}, + {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]}, + {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]}, + {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]}, + {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]}, + {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]}, + {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]}, + {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]}, + {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]}, + {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]}, + {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/}, + {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]}, + {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]}, + {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r"], alias: ["rscript"]}, + {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]}, + {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"}, + {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]}, + {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]}, + {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]}, + {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]}, + {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]}, + {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]}, + {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]}, + {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]}, + {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/}, + {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]}, + {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]}, + {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]}, + {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]}, + {name: "Solr", mime: "text/x-solr", mode: "solr"}, + {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]}, + {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]}, + {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]}, + {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]}, + {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]}, + {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]}, + {name: "sTeX", mime: "text/x-stex", mode: "stex"}, + {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]}, + {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]}, + {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]}, + {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]}, + {name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"}, + {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"}, + {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]}, + {name: "Tornado", mime: "text/x-tornado", mode: "tornado"}, + {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]}, + {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]}, + {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]}, + {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]}, + {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]}, + {name: "Twig", mime: "text/x-twig", mode: "twig"}, + {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]}, + {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]}, + {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]}, + {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]}, + {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]}, + {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]}, + {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]}, + {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]}, + {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]}, + {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]}, + {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}, + {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]}, + {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]}, + {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]} + ]; + // Ensure all modes have a mime property for backwards compatibility + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mimes) info.mime = info.mimes[0]; + } + + CodeMirror.findModeByMIME = function(mime) { + mime = mime.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mime == mime) return info; + if (info.mimes) for (var j = 0; j < info.mimes.length; j++) + if (info.mimes[j] == mime) return info; + } + }; + + CodeMirror.findModeByExtension = function(ext) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.ext) for (var j = 0; j < info.ext.length; j++) + if (info.ext[j] == ext) return info; + } + }; + + CodeMirror.findModeByFileName = function(filename) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.file && info.file.test(filename)) return info; + } + var dot = filename.lastIndexOf("."); + var ext = dot > -1 && filename.substring(dot + 1, filename.length); + if (ext) return CodeMirror.findModeByExtension(ext); + }; + + CodeMirror.findModeByName = function(name) { + name = name.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.name.toLowerCase() == name) return info; + if (info.alias) for (var j = 0; j < info.alias.length; j++) + if (info.alias[j].toLowerCase() == name) return info; + } + }; +}); diff --git a/shared/codemirror/mode/xml/xml.js b/shared/codemirror/mode/xml/xml.js index f987a3a..3b0271b 100644 --- a/shared/codemirror/mode/xml/xml.js +++ b/shared/codemirror/mode/xml/xml.js @@ -1,394 +1,394 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -var htmlConfig = { - 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, 'menuitem': 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: true, - caseFold: true -} - -var xmlConfig = { - autoSelfClosers: {}, - implicitlyClosed: {}, - contextGrabbers: {}, - doNotIndent: {}, - allowUnquoted: false, - allowMissing: false, - caseFold: false -} - -CodeMirror.defineMode("xml", function(editorConf, config_) { - var indentUnit = editorConf.indentUnit - var config = {} - var defaults = config_.htmlMode ? htmlConfig : xmlConfig - for (var prop in defaults) config[prop] = defaults[prop] - for (var prop in config_) config[prop] = config_[prop] - - // Return variables for tokenizers - var type, setStyle; - - function inText(stream, state) { - function chain(parser) { - state.tokenize = parser; - return parser(stream, state); - } - - var ch = stream.next(); - if (ch == "<") { - if (stream.eat("!")) { - if (stream.eat("[")) { - if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); - else return null; - } else if (stream.match("--")) { - return chain(inBlock("comment", "-->")); - } else if (stream.match("DOCTYPE", true, true)) { - stream.eatWhile(/[\w\._\-]/); - return chain(doctype(1)); - } else { - return null; - } - } else if (stream.eat("?")) { - stream.eatWhile(/[\w\._\-]/); - state.tokenize = inBlock("meta", "?>"); - return "meta"; - } else { - type = stream.eat("/") ? "closeTag" : "openTag"; - state.tokenize = inTag; - return "tag bracket"; - } - } else if (ch == "&") { - var ok; - if (stream.eat("#")) { - if (stream.eat("x")) { - ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); - } else { - ok = stream.eatWhile(/[\d]/) && stream.eat(";"); - } - } else { - ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); - } - return ok ? "atom" : "error"; - } else { - stream.eatWhile(/[^&<]/); - return null; - } - } - inText.isInText = true; - - function inTag(stream, state) { - var ch = stream.next(); - if (ch == ">" || (ch == "/" && stream.eat(">"))) { - state.tokenize = inText; - type = ch == ">" ? "endTag" : "selfcloseTag"; - return "tag bracket"; - } else if (ch == "=") { - type = "equals"; - return null; - } else if (ch == "<") { - state.tokenize = inText; - state.state = baseState; - state.tagName = state.tagStart = null; - var next = state.tokenize(stream, state); - return next ? next + " tag error" : "tag error"; - } else if (/[\'\"]/.test(ch)) { - state.tokenize = inAttribute(ch); - state.stringStartCol = stream.column(); - return state.tokenize(stream, state); - } else { - stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); - return "word"; - } - } - - function inAttribute(quote) { - var closure = function(stream, state) { - while (!stream.eol()) { - if (stream.next() == quote) { - state.tokenize = inTag; - break; - } - } - return "string"; - }; - closure.isInAttribute = true; - return closure; - } - - function inBlock(style, terminator) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.match(terminator)) { - state.tokenize = inText; - break; - } - stream.next(); - } - return style; - }; - } - function doctype(depth) { - return function(stream, state) { - var ch; - while ((ch = stream.next()) != null) { - if (ch == "<") { - state.tokenize = doctype(depth + 1); - return state.tokenize(stream, state); - } else if (ch == ">") { - if (depth == 1) { - state.tokenize = inText; - break; - } else { - state.tokenize = doctype(depth - 1); - return state.tokenize(stream, state); - } - } - } - return "meta"; - }; - } - - function Context(state, tagName, startOfLine) { - this.prev = state.context; - this.tagName = tagName; - this.indent = state.indented; - this.startOfLine = startOfLine; - if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) - this.noIndent = true; - } - function popContext(state) { - if (state.context) state.context = state.context.prev; - } - function maybePopContext(state, nextTagName) { - var parentTagName; - while (true) { - if (!state.context) { - return; - } - parentTagName = state.context.tagName; - if (!config.contextGrabbers.hasOwnProperty(parentTagName) || - !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { - return; - } - popContext(state); - } - } - - function baseState(type, stream, state) { - if (type == "openTag") { - state.tagStart = stream.column(); - return tagNameState; - } else if (type == "closeTag") { - return closeTagNameState; - } else { - return baseState; - } - } - function tagNameState(type, stream, state) { - if (type == "word") { - state.tagName = stream.current(); - setStyle = "tag"; - return attrState; - } else { - setStyle = "error"; - return tagNameState; - } - } - function closeTagNameState(type, stream, state) { - if (type == "word") { - var tagName = stream.current(); - if (state.context && state.context.tagName != tagName && - config.implicitlyClosed.hasOwnProperty(state.context.tagName)) - popContext(state); - if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { - setStyle = "tag"; - return closeState; - } else { - setStyle = "tag error"; - return closeStateErr; - } - } else { - setStyle = "error"; - return closeStateErr; - } - } - - function closeState(type, _stream, state) { - if (type != "endTag") { - setStyle = "error"; - return closeState; - } - popContext(state); - return baseState; - } - function closeStateErr(type, stream, state) { - setStyle = "error"; - return closeState(type, stream, state); - } - - function attrState(type, _stream, state) { - if (type == "word") { - setStyle = "attribute"; - return attrEqState; - } else if (type == "endTag" || type == "selfcloseTag") { - var tagName = state.tagName, tagStart = state.tagStart; - state.tagName = state.tagStart = null; - if (type == "selfcloseTag" || - config.autoSelfClosers.hasOwnProperty(tagName)) { - maybePopContext(state, tagName); - } else { - maybePopContext(state, tagName); - state.context = new Context(state, tagName, tagStart == state.indented); - } - return baseState; - } - setStyle = "error"; - return attrState; - } - function attrEqState(type, stream, state) { - if (type == "equals") return attrValueState; - if (!config.allowMissing) setStyle = "error"; - return attrState(type, stream, state); - } - function attrValueState(type, stream, state) { - if (type == "string") return attrContinuedState; - if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;} - setStyle = "error"; - return attrState(type, stream, state); - } - function attrContinuedState(type, stream, state) { - if (type == "string") return attrContinuedState; - return attrState(type, stream, state); - } - - return { - startState: function(baseIndent) { - var state = {tokenize: inText, - state: baseState, - indented: baseIndent || 0, - tagName: null, tagStart: null, - context: null} - if (baseIndent != null) state.baseIndent = baseIndent - return state - }, - - token: function(stream, state) { - if (!state.tagName && stream.sol()) - state.indented = stream.indentation(); - - if (stream.eatSpace()) return null; - type = null; - var style = state.tokenize(stream, state); - if ((style || type) && style != "comment") { - setStyle = null; - state.state = state.state(type || style, stream, state); - if (setStyle) - style = setStyle == "error" ? style + " error" : setStyle; - } - return style; - }, - - indent: function(state, textAfter, fullLine) { - var context = state.context; - // Indent multi-line strings (e.g. css). - if (state.tokenize.isInAttribute) { - if (state.tagStart == state.indented) - return state.stringStartCol + 1; - else - return state.indented + indentUnit; - } - if (context && context.noIndent) return CodeMirror.Pass; - if (state.tokenize != inTag && state.tokenize != inText) - return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; - // Indent the starts of attribute names. - if (state.tagName) { - if (config.multilineTagIndentPastTag !== false) - return state.tagStart + state.tagName.length + 2; - else - return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1); - } - if (config.alignCDATA && /$/, - blockCommentStart: "", - - configuration: config.htmlMode ? "html" : "xml", - helperType: config.htmlMode ? "html" : "xml", - - skipAttribute: function(state) { - if (state.state == attrValueState) - state.state = attrState - } - }; -}); - -CodeMirror.defineMIME("text/xml", "xml"); -CodeMirror.defineMIME("application/xml", "xml"); -if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) - CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); - -}); +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +var htmlConfig = { + 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, 'menuitem': 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: true, + caseFold: true +} + +var xmlConfig = { + autoSelfClosers: {}, + implicitlyClosed: {}, + contextGrabbers: {}, + doNotIndent: {}, + allowUnquoted: false, + allowMissing: false, + caseFold: false +} + +CodeMirror.defineMode("xml", function(editorConf, config_) { + var indentUnit = editorConf.indentUnit + var config = {} + var defaults = config_.htmlMode ? htmlConfig : xmlConfig + for (var prop in defaults) config[prop] = defaults[prop] + for (var prop in config_) config[prop] = config_[prop] + + // Return variables for tokenizers + var type, setStyle; + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var ch = stream.next(); + if (ch == "<") { + if (stream.eat("!")) { + if (stream.eat("[")) { + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); + else return null; + } else if (stream.match("--")) { + return chain(inBlock("comment", "-->")); + } else if (stream.match("DOCTYPE", true, true)) { + stream.eatWhile(/[\w\._\-]/); + return chain(doctype(1)); + } else { + return null; + } + } else if (stream.eat("?")) { + stream.eatWhile(/[\w\._\-]/); + state.tokenize = inBlock("meta", "?>"); + return "meta"; + } else { + type = stream.eat("/") ? "closeTag" : "openTag"; + state.tokenize = inTag; + return "tag bracket"; + } + } else if (ch == "&") { + var ok; + if (stream.eat("#")) { + if (stream.eat("x")) { + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); + } else { + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); + } + } else { + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); + } + return ok ? "atom" : "error"; + } else { + stream.eatWhile(/[^&<]/); + return null; + } + } + inText.isInText = true; + + function inTag(stream, state) { + var ch = stream.next(); + if (ch == ">" || (ch == "/" && stream.eat(">"))) { + state.tokenize = inText; + type = ch == ">" ? "endTag" : "selfcloseTag"; + return "tag bracket"; + } else if (ch == "=") { + type = "equals"; + return null; + } else if (ch == "<") { + state.tokenize = inText; + state.state = baseState; + state.tagName = state.tagStart = null; + var next = state.tokenize(stream, state); + return next ? next + " tag error" : "tag error"; + } else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + state.stringStartCol = stream.column(); + return state.tokenize(stream, state); + } else { + stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); + return "word"; + } + } + + function inAttribute(quote) { + var closure = function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inTag; + break; + } + } + return "string"; + }; + closure.isInAttribute = true; + return closure; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + return style; + }; + } + function doctype(depth) { + return function(stream, state) { + var ch; + while ((ch = stream.next()) != null) { + if (ch == "<") { + state.tokenize = doctype(depth + 1); + return state.tokenize(stream, state); + } else if (ch == ">") { + if (depth == 1) { + state.tokenize = inText; + break; + } else { + state.tokenize = doctype(depth - 1); + return state.tokenize(stream, state); + } + } + } + return "meta"; + }; + } + + function Context(state, tagName, startOfLine) { + this.prev = state.context; + this.tagName = tagName; + this.indent = state.indented; + this.startOfLine = startOfLine; + if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) + this.noIndent = true; + } + function popContext(state) { + if (state.context) state.context = state.context.prev; + } + function maybePopContext(state, nextTagName) { + var parentTagName; + while (true) { + if (!state.context) { + return; + } + parentTagName = state.context.tagName; + if (!config.contextGrabbers.hasOwnProperty(parentTagName) || + !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { + return; + } + popContext(state); + } + } + + function baseState(type, stream, state) { + if (type == "openTag") { + state.tagStart = stream.column(); + return tagNameState; + } else if (type == "closeTag") { + return closeTagNameState; + } else { + return baseState; + } + } + function tagNameState(type, stream, state) { + if (type == "word") { + state.tagName = stream.current(); + setStyle = "tag"; + return attrState; + } else { + setStyle = "error"; + return tagNameState; + } + } + function closeTagNameState(type, stream, state) { + if (type == "word") { + var tagName = stream.current(); + if (state.context && state.context.tagName != tagName && + config.implicitlyClosed.hasOwnProperty(state.context.tagName)) + popContext(state); + if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { + setStyle = "tag"; + return closeState; + } else { + setStyle = "tag error"; + return closeStateErr; + } + } else { + setStyle = "error"; + return closeStateErr; + } + } + + function closeState(type, _stream, state) { + if (type != "endTag") { + setStyle = "error"; + return closeState; + } + popContext(state); + return baseState; + } + function closeStateErr(type, stream, state) { + setStyle = "error"; + return closeState(type, stream, state); + } + + function attrState(type, _stream, state) { + if (type == "word") { + setStyle = "attribute"; + return attrEqState; + } else if (type == "endTag" || type == "selfcloseTag") { + var tagName = state.tagName, tagStart = state.tagStart; + state.tagName = state.tagStart = null; + if (type == "selfcloseTag" || + config.autoSelfClosers.hasOwnProperty(tagName)) { + maybePopContext(state, tagName); + } else { + maybePopContext(state, tagName); + state.context = new Context(state, tagName, tagStart == state.indented); + } + return baseState; + } + setStyle = "error"; + return attrState; + } + function attrEqState(type, stream, state) { + if (type == "equals") return attrValueState; + if (!config.allowMissing) setStyle = "error"; + return attrState(type, stream, state); + } + function attrValueState(type, stream, state) { + if (type == "string") return attrContinuedState; + if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;} + setStyle = "error"; + return attrState(type, stream, state); + } + function attrContinuedState(type, stream, state) { + if (type == "string") return attrContinuedState; + return attrState(type, stream, state); + } + + return { + startState: function(baseIndent) { + var state = {tokenize: inText, + state: baseState, + indented: baseIndent || 0, + tagName: null, tagStart: null, + context: null} + if (baseIndent != null) state.baseIndent = baseIndent + return state + }, + + token: function(stream, state) { + if (!state.tagName && stream.sol()) + state.indented = stream.indentation(); + + if (stream.eatSpace()) return null; + type = null; + var style = state.tokenize(stream, state); + if ((style || type) && style != "comment") { + setStyle = null; + state.state = state.state(type || style, stream, state); + if (setStyle) + style = setStyle == "error" ? style + " error" : setStyle; + } + return style; + }, + + indent: function(state, textAfter, fullLine) { + var context = state.context; + // Indent multi-line strings (e.g. css). + if (state.tokenize.isInAttribute) { + if (state.tagStart == state.indented) + return state.stringStartCol + 1; + else + return state.indented + indentUnit; + } + if (context && context.noIndent) return CodeMirror.Pass; + if (state.tokenize != inTag && state.tokenize != inText) + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; + // Indent the starts of attribute names. + if (state.tagName) { + if (config.multilineTagIndentPastTag !== false) + return state.tagStart + state.tagName.length + 2; + else + return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1); + } + if (config.alignCDATA && /$/, + blockCommentStart: "", + + configuration: config.htmlMode ? "html" : "xml", + helperType: config.htmlMode ? "html" : "xml", + + skipAttribute: function(state) { + if (state.state == attrValueState) + state.state = attrState + } + }; +}); + +CodeMirror.defineMIME("text/xml", "xml"); +CodeMirror.defineMIME("application/xml", "xml"); +if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); + +}); diff --git a/shared/codemirror/package.json b/shared/codemirror/package.json index ed6fa84..a57feb5 100644 --- a/shared/codemirror/package.json +++ b/shared/codemirror/package.json @@ -1,43 +1,43 @@ -{ - "dependencies": {}, - "description": "Full-featured in-browser code editor", - "directories": { - "lib": "./lib" - }, - "dist": { - "shasum": "5bd0aa57c2d1ee7cf3bef8b11bec100544b8b9ae", - "tarball": "https://registry.npmjs.org/codemirror/-/codemirror-5.14.2.tgz" - }, - "gitHead": "a25a29159346102591733d2474d6015e170cea06", - "homepage": "http://codemirror.net", - "jspm": { - "dependencies": {}, - "devDependencies": {}, - "directories": {} - }, - "keywords": [ - "JavaScript", - "CodeMirror", - "Editor" - ], - "license": "MIT", - "main": "lib/codemirror.js", - "maintainers": [ - { - "email": "marijnh@gmail.com", - "name": "marijn" - } - ], - "name": "codemirror", - "optionalDependencies": {}, - "readme": "ERROR: No README data found!", - "repository": { - "type": "git", - "url": "git+https://github.com/codemirror/CodeMirror.git" - }, - "scripts": { - "lint": "bin/lint", - "test": "node ./test/run.js" - }, - "version": "5.14.2" -} +{ + "dependencies": {}, + "description": "Full-featured in-browser code editor", + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "5bd0aa57c2d1ee7cf3bef8b11bec100544b8b9ae", + "tarball": "https://registry.npmjs.org/codemirror/-/codemirror-5.14.2.tgz" + }, + "gitHead": "a25a29159346102591733d2474d6015e170cea06", + "homepage": "http://codemirror.net", + "jspm": { + "dependencies": {}, + "devDependencies": {}, + "directories": {} + }, + "keywords": [ + "JavaScript", + "CodeMirror", + "Editor" + ], + "license": "MIT", + "main": "lib/codemirror.js", + "maintainers": [ + { + "email": "marijnh@gmail.com", + "name": "marijn" + } + ], + "name": "codemirror", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/codemirror/CodeMirror.git" + }, + "scripts": { + "lint": "bin/lint", + "test": "node ./test/run.js" + }, + "version": "5.14.2" +} diff --git a/shared/codemirror/theme/3024-day.css b/shared/codemirror/theme/3024-day.css index 7132655..5232267 100644 --- a/shared/codemirror/theme/3024-day.css +++ b/shared/codemirror/theme/3024-day.css @@ -1,41 +1,41 @@ -/* - - Name: 3024 day - Author: Jan T. Sott (http://github.com/idleberg) - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-3024-day.CodeMirror { background: #f7f7f7; color: #3a3432; } -.cm-s-3024-day div.CodeMirror-selected { background: #d6d5d4; } - -.cm-s-3024-day .CodeMirror-line::selection, .cm-s-3024-day .CodeMirror-line > span::selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d6d5d4; } -.cm-s-3024-day .CodeMirror-line::-moz-selection, .cm-s-3024-day .CodeMirror-line > span::-moz-selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d9d9d9; } - -.cm-s-3024-day .CodeMirror-gutters { background: #f7f7f7; border-right: 0px; } -.cm-s-3024-day .CodeMirror-guttermarker { color: #db2d20; } -.cm-s-3024-day .CodeMirror-guttermarker-subtle { color: #807d7c; } -.cm-s-3024-day .CodeMirror-linenumber { color: #807d7c; } - -.cm-s-3024-day .CodeMirror-cursor { border-left: 1px solid #5c5855; } - -.cm-s-3024-day span.cm-comment { color: #cdab53; } -.cm-s-3024-day span.cm-atom { color: #a16a94; } -.cm-s-3024-day span.cm-number { color: #a16a94; } - -.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute { color: #01a252; } -.cm-s-3024-day span.cm-keyword { color: #db2d20; } -.cm-s-3024-day span.cm-string { color: #fded02; } - -.cm-s-3024-day span.cm-variable { color: #01a252; } -.cm-s-3024-day span.cm-variable-2 { color: #01a0e4; } -.cm-s-3024-day span.cm-def { color: #e8bbd0; } -.cm-s-3024-day span.cm-bracket { color: #3a3432; } -.cm-s-3024-day span.cm-tag { color: #db2d20; } -.cm-s-3024-day span.cm-link { color: #a16a94; } -.cm-s-3024-day span.cm-error { background: #db2d20; color: #5c5855; } - -.cm-s-3024-day .CodeMirror-activeline-background { background: #e8f2ff; } -.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important; } +/* + + Name: 3024 day + Author: Jan T. Sott (http://github.com/idleberg) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-3024-day.CodeMirror { background: #f7f7f7; color: #3a3432; } +.cm-s-3024-day div.CodeMirror-selected { background: #d6d5d4; } + +.cm-s-3024-day .CodeMirror-line::selection, .cm-s-3024-day .CodeMirror-line > span::selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d6d5d4; } +.cm-s-3024-day .CodeMirror-line::-moz-selection, .cm-s-3024-day .CodeMirror-line > span::-moz-selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d9d9d9; } + +.cm-s-3024-day .CodeMirror-gutters { background: #f7f7f7; border-right: 0px; } +.cm-s-3024-day .CodeMirror-guttermarker { color: #db2d20; } +.cm-s-3024-day .CodeMirror-guttermarker-subtle { color: #807d7c; } +.cm-s-3024-day .CodeMirror-linenumber { color: #807d7c; } + +.cm-s-3024-day .CodeMirror-cursor { border-left: 1px solid #5c5855; } + +.cm-s-3024-day span.cm-comment { color: #cdab53; } +.cm-s-3024-day span.cm-atom { color: #a16a94; } +.cm-s-3024-day span.cm-number { color: #a16a94; } + +.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute { color: #01a252; } +.cm-s-3024-day span.cm-keyword { color: #db2d20; } +.cm-s-3024-day span.cm-string { color: #fded02; } + +.cm-s-3024-day span.cm-variable { color: #01a252; } +.cm-s-3024-day span.cm-variable-2 { color: #01a0e4; } +.cm-s-3024-day span.cm-def { color: #e8bbd0; } +.cm-s-3024-day span.cm-bracket { color: #3a3432; } +.cm-s-3024-day span.cm-tag { color: #db2d20; } +.cm-s-3024-day span.cm-link { color: #a16a94; } +.cm-s-3024-day span.cm-error { background: #db2d20; color: #5c5855; } + +.cm-s-3024-day .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important; } diff --git a/shared/codemirror/theme/3024-night.css b/shared/codemirror/theme/3024-night.css index adc5900..bd0b64d 100644 --- a/shared/codemirror/theme/3024-night.css +++ b/shared/codemirror/theme/3024-night.css @@ -1,39 +1,39 @@ -/* - - Name: 3024 night - Author: Jan T. Sott (http://github.com/idleberg) - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-3024-night.CodeMirror { background: #090300; color: #d6d5d4; } -.cm-s-3024-night div.CodeMirror-selected { background: #3a3432; } -.cm-s-3024-night .CodeMirror-line::selection, .cm-s-3024-night .CodeMirror-line > span::selection, .cm-s-3024-night .CodeMirror-line > span > span::selection { background: rgba(58, 52, 50, .99); } -.cm-s-3024-night .CodeMirror-line::-moz-selection, .cm-s-3024-night .CodeMirror-line > span::-moz-selection, .cm-s-3024-night .CodeMirror-line > span > span::-moz-selection { background: rgba(58, 52, 50, .99); } -.cm-s-3024-night .CodeMirror-gutters { background: #090300; border-right: 0px; } -.cm-s-3024-night .CodeMirror-guttermarker { color: #db2d20; } -.cm-s-3024-night .CodeMirror-guttermarker-subtle { color: #5c5855; } -.cm-s-3024-night .CodeMirror-linenumber { color: #5c5855; } - -.cm-s-3024-night .CodeMirror-cursor { border-left: 1px solid #807d7c; } - -.cm-s-3024-night span.cm-comment { color: #cdab53; } -.cm-s-3024-night span.cm-atom { color: #a16a94; } -.cm-s-3024-night span.cm-number { color: #a16a94; } - -.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute { color: #01a252; } -.cm-s-3024-night span.cm-keyword { color: #db2d20; } -.cm-s-3024-night span.cm-string { color: #fded02; } - -.cm-s-3024-night span.cm-variable { color: #01a252; } -.cm-s-3024-night span.cm-variable-2 { color: #01a0e4; } -.cm-s-3024-night span.cm-def { color: #e8bbd0; } -.cm-s-3024-night span.cm-bracket { color: #d6d5d4; } -.cm-s-3024-night span.cm-tag { color: #db2d20; } -.cm-s-3024-night span.cm-link { color: #a16a94; } -.cm-s-3024-night span.cm-error { background: #db2d20; color: #807d7c; } - -.cm-s-3024-night .CodeMirror-activeline-background { background: #2F2F2F; } -.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: 3024 night + Author: Jan T. Sott (http://github.com/idleberg) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-3024-night.CodeMirror { background: #090300; color: #d6d5d4; } +.cm-s-3024-night div.CodeMirror-selected { background: #3a3432; } +.cm-s-3024-night .CodeMirror-line::selection, .cm-s-3024-night .CodeMirror-line > span::selection, .cm-s-3024-night .CodeMirror-line > span > span::selection { background: rgba(58, 52, 50, .99); } +.cm-s-3024-night .CodeMirror-line::-moz-selection, .cm-s-3024-night .CodeMirror-line > span::-moz-selection, .cm-s-3024-night .CodeMirror-line > span > span::-moz-selection { background: rgba(58, 52, 50, .99); } +.cm-s-3024-night .CodeMirror-gutters { background: #090300; border-right: 0px; } +.cm-s-3024-night .CodeMirror-guttermarker { color: #db2d20; } +.cm-s-3024-night .CodeMirror-guttermarker-subtle { color: #5c5855; } +.cm-s-3024-night .CodeMirror-linenumber { color: #5c5855; } + +.cm-s-3024-night .CodeMirror-cursor { border-left: 1px solid #807d7c; } + +.cm-s-3024-night span.cm-comment { color: #cdab53; } +.cm-s-3024-night span.cm-atom { color: #a16a94; } +.cm-s-3024-night span.cm-number { color: #a16a94; } + +.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute { color: #01a252; } +.cm-s-3024-night span.cm-keyword { color: #db2d20; } +.cm-s-3024-night span.cm-string { color: #fded02; } + +.cm-s-3024-night span.cm-variable { color: #01a252; } +.cm-s-3024-night span.cm-variable-2 { color: #01a0e4; } +.cm-s-3024-night span.cm-def { color: #e8bbd0; } +.cm-s-3024-night span.cm-bracket { color: #d6d5d4; } +.cm-s-3024-night span.cm-tag { color: #db2d20; } +.cm-s-3024-night span.cm-link { color: #a16a94; } +.cm-s-3024-night span.cm-error { background: #db2d20; color: #807d7c; } + +.cm-s-3024-night .CodeMirror-activeline-background { background: #2F2F2F; } +.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/abcdef.css b/shared/codemirror/theme/abcdef.css index 7f9d788..67f289d 100644 --- a/shared/codemirror/theme/abcdef.css +++ b/shared/codemirror/theme/abcdef.css @@ -1,32 +1,32 @@ -.cm-s-abcdef.CodeMirror { background: #0f0f0f; color: #defdef; } -.cm-s-abcdef div.CodeMirror-selected { background: #515151; } -.cm-s-abcdef .CodeMirror-line::selection, .cm-s-abcdef .CodeMirror-line > span::selection, .cm-s-abcdef .CodeMirror-line > span > span::selection { background: rgba(56, 56, 56, 0.99); } -.cm-s-abcdef .CodeMirror-line::-moz-selection, .cm-s-abcdef .CodeMirror-line > span::-moz-selection, .cm-s-abcdef .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 56, 56, 0.99); } -.cm-s-abcdef .CodeMirror-gutters { background: #555; border-right: 2px solid #314151; } -.cm-s-abcdef .CodeMirror-guttermarker { color: #222; } -.cm-s-abcdef .CodeMirror-guttermarker-subtle { color: azure; } -.cm-s-abcdef .CodeMirror-linenumber { color: #FFFFFF; } -.cm-s-abcdef .CodeMirror-cursor { border-left: 1px solid #00FF00; } - -.cm-s-abcdef span.cm-keyword { color: darkgoldenrod; font-weight: bold; } -.cm-s-abcdef span.cm-atom { color: #77F; } -.cm-s-abcdef span.cm-number { color: violet; } -.cm-s-abcdef span.cm-def { color: #fffabc; } -.cm-s-abcdef span.cm-variable { color: #abcdef; } -.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; } -.cm-s-abcdef span.cm-variable-3 { color: #def; } -.cm-s-abcdef span.cm-property { color: #fedcba; } -.cm-s-abcdef span.cm-operator { color: #ff0; } -.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;} -.cm-s-abcdef span.cm-string { color: #2b4; } -.cm-s-abcdef span.cm-meta { color: #C9F; } -.cm-s-abcdef span.cm-qualifier { color: #FFF700; } -.cm-s-abcdef span.cm-builtin { color: #30aabc; } -.cm-s-abcdef span.cm-bracket { color: #8a8a8a; } -.cm-s-abcdef span.cm-tag { color: #FFDD44; } -.cm-s-abcdef span.cm-attribute { color: #DDFF00; } -.cm-s-abcdef span.cm-error { color: #FF0000; } -.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; } -.cm-s-abcdef span.cm-link { color: blueviolet; } - -.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; } +.cm-s-abcdef.CodeMirror { background: #0f0f0f; color: #defdef; } +.cm-s-abcdef div.CodeMirror-selected { background: #515151; } +.cm-s-abcdef .CodeMirror-line::selection, .cm-s-abcdef .CodeMirror-line > span::selection, .cm-s-abcdef .CodeMirror-line > span > span::selection { background: rgba(56, 56, 56, 0.99); } +.cm-s-abcdef .CodeMirror-line::-moz-selection, .cm-s-abcdef .CodeMirror-line > span::-moz-selection, .cm-s-abcdef .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 56, 56, 0.99); } +.cm-s-abcdef .CodeMirror-gutters { background: #555; border-right: 2px solid #314151; } +.cm-s-abcdef .CodeMirror-guttermarker { color: #222; } +.cm-s-abcdef .CodeMirror-guttermarker-subtle { color: azure; } +.cm-s-abcdef .CodeMirror-linenumber { color: #FFFFFF; } +.cm-s-abcdef .CodeMirror-cursor { border-left: 1px solid #00FF00; } + +.cm-s-abcdef span.cm-keyword { color: darkgoldenrod; font-weight: bold; } +.cm-s-abcdef span.cm-atom { color: #77F; } +.cm-s-abcdef span.cm-number { color: violet; } +.cm-s-abcdef span.cm-def { color: #fffabc; } +.cm-s-abcdef span.cm-variable { color: #abcdef; } +.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; } +.cm-s-abcdef span.cm-variable-3 { color: #def; } +.cm-s-abcdef span.cm-property { color: #fedcba; } +.cm-s-abcdef span.cm-operator { color: #ff0; } +.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;} +.cm-s-abcdef span.cm-string { color: #2b4; } +.cm-s-abcdef span.cm-meta { color: #C9F; } +.cm-s-abcdef span.cm-qualifier { color: #FFF700; } +.cm-s-abcdef span.cm-builtin { color: #30aabc; } +.cm-s-abcdef span.cm-bracket { color: #8a8a8a; } +.cm-s-abcdef span.cm-tag { color: #FFDD44; } +.cm-s-abcdef span.cm-attribute { color: #DDFF00; } +.cm-s-abcdef span.cm-error { color: #FF0000; } +.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; } +.cm-s-abcdef span.cm-link { color: blueviolet; } + +.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; } diff --git a/shared/codemirror/theme/ambiance-mobile.css b/shared/codemirror/theme/ambiance-mobile.css index 88d332e..374818a 100644 --- a/shared/codemirror/theme/ambiance-mobile.css +++ b/shared/codemirror/theme/ambiance-mobile.css @@ -1,5 +1,5 @@ -.cm-s-ambiance.CodeMirror { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} +.cm-s-ambiance.CodeMirror { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} diff --git a/shared/codemirror/theme/ambiance.css b/shared/codemirror/theme/ambiance.css index bce3446..3e5db26 100644 --- a/shared/codemirror/theme/ambiance.css +++ b/shared/codemirror/theme/ambiance.css @@ -1,74 +1,74 @@ -/* ambiance theme for codemirror */ - -/* Color scheme */ - -.cm-s-ambiance .cm-header { color: blue; } -.cm-s-ambiance .cm-quote { color: #24C2C7; } - -.cm-s-ambiance .cm-keyword { color: #cda869; } -.cm-s-ambiance .cm-atom { color: #CF7EA9; } -.cm-s-ambiance .cm-number { color: #78CF8A; } -.cm-s-ambiance .cm-def { color: #aac6e3; } -.cm-s-ambiance .cm-variable { color: #ffb795; } -.cm-s-ambiance .cm-variable-2 { color: #eed1b3; } -.cm-s-ambiance .cm-variable-3 { color: #faded3; } -.cm-s-ambiance .cm-property { color: #eed1b3; } -.cm-s-ambiance .cm-operator { color: #fa8d6a; } -.cm-s-ambiance .cm-comment { color: #555; font-style:italic; } -.cm-s-ambiance .cm-string { color: #8f9d6a; } -.cm-s-ambiance .cm-string-2 { color: #9d937c; } -.cm-s-ambiance .cm-meta { color: #D2A8A1; } -.cm-s-ambiance .cm-qualifier { color: yellow; } -.cm-s-ambiance .cm-builtin { color: #9999cc; } -.cm-s-ambiance .cm-bracket { color: #24C2C7; } -.cm-s-ambiance .cm-tag { color: #fee4ff; } -.cm-s-ambiance .cm-attribute { color: #9B859D; } -.cm-s-ambiance .cm-hr { color: pink; } -.cm-s-ambiance .cm-link { color: #F4C20B; } -.cm-s-ambiance .cm-special { color: #FF9D00; } -.cm-s-ambiance .cm-error { color: #AF2018; } - -.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; } -.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; } - -.cm-s-ambiance div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } -.cm-s-ambiance.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } -.cm-s-ambiance .CodeMirror-line::selection, .cm-s-ambiance .CodeMirror-line > span::selection, .cm-s-ambiance .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } -.cm-s-ambiance .CodeMirror-line::-moz-selection, .cm-s-ambiance .CodeMirror-line > span::-moz-selection, .cm-s-ambiance .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } - -/* Editor styling */ - -.cm-s-ambiance.CodeMirror { - line-height: 1.40em; - color: #E6E1DC; - background-color: #202020; - -webkit-box-shadow: inset 0 0 10px black; - -moz-box-shadow: inset 0 0 10px black; - box-shadow: inset 0 0 10px black; -} - -.cm-s-ambiance .CodeMirror-gutters { - background: #3D3D3D; - border-right: 1px solid #4D4D4D; - box-shadow: 0 10px 20px black; -} - -.cm-s-ambiance .CodeMirror-linenumber { - text-shadow: 0px 1px 1px #4d4d4d; - color: #111; - padding: 0 5px; -} - -.cm-s-ambiance .CodeMirror-guttermarker { color: #aaa; } -.cm-s-ambiance .CodeMirror-guttermarker-subtle { color: #111; } - -.cm-s-ambiance .CodeMirror-cursor { border-left: 1px solid #7991E8; } - -.cm-s-ambiance .CodeMirror-activeline-background { - background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031); -} - -.cm-s-ambiance.CodeMirror, -.cm-s-ambiance .CodeMirror-gutters { - background-image: url("data:image/png;base64,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"); -} +/* ambiance theme for codemirror */ + +/* Color scheme */ + +.cm-s-ambiance .cm-header { color: blue; } +.cm-s-ambiance .cm-quote { color: #24C2C7; } + +.cm-s-ambiance .cm-keyword { color: #cda869; } +.cm-s-ambiance .cm-atom { color: #CF7EA9; } +.cm-s-ambiance .cm-number { color: #78CF8A; } +.cm-s-ambiance .cm-def { color: #aac6e3; } +.cm-s-ambiance .cm-variable { color: #ffb795; } +.cm-s-ambiance .cm-variable-2 { color: #eed1b3; } +.cm-s-ambiance .cm-variable-3 { color: #faded3; } +.cm-s-ambiance .cm-property { color: #eed1b3; } +.cm-s-ambiance .cm-operator { color: #fa8d6a; } +.cm-s-ambiance .cm-comment { color: #555; font-style:italic; } +.cm-s-ambiance .cm-string { color: #8f9d6a; } +.cm-s-ambiance .cm-string-2 { color: #9d937c; } +.cm-s-ambiance .cm-meta { color: #D2A8A1; } +.cm-s-ambiance .cm-qualifier { color: yellow; } +.cm-s-ambiance .cm-builtin { color: #9999cc; } +.cm-s-ambiance .cm-bracket { color: #24C2C7; } +.cm-s-ambiance .cm-tag { color: #fee4ff; } +.cm-s-ambiance .cm-attribute { color: #9B859D; } +.cm-s-ambiance .cm-hr { color: pink; } +.cm-s-ambiance .cm-link { color: #F4C20B; } +.cm-s-ambiance .cm-special { color: #FF9D00; } +.cm-s-ambiance .cm-error { color: #AF2018; } + +.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; } +.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; } + +.cm-s-ambiance div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } +.cm-s-ambiance.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-ambiance .CodeMirror-line::selection, .cm-s-ambiance .CodeMirror-line > span::selection, .cm-s-ambiance .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-ambiance .CodeMirror-line::-moz-selection, .cm-s-ambiance .CodeMirror-line > span::-moz-selection, .cm-s-ambiance .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } + +/* Editor styling */ + +.cm-s-ambiance.CodeMirror { + line-height: 1.40em; + color: #E6E1DC; + background-color: #202020; + -webkit-box-shadow: inset 0 0 10px black; + -moz-box-shadow: inset 0 0 10px black; + box-shadow: inset 0 0 10px black; +} + +.cm-s-ambiance .CodeMirror-gutters { + background: #3D3D3D; + border-right: 1px solid #4D4D4D; + box-shadow: 0 10px 20px black; +} + +.cm-s-ambiance .CodeMirror-linenumber { + text-shadow: 0px 1px 1px #4d4d4d; + color: #111; + padding: 0 5px; +} + +.cm-s-ambiance .CodeMirror-guttermarker { color: #aaa; } +.cm-s-ambiance .CodeMirror-guttermarker-subtle { color: #111; } + +.cm-s-ambiance .CodeMirror-cursor { border-left: 1px solid #7991E8; } + +.cm-s-ambiance .CodeMirror-activeline-background { + background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031); +} + +.cm-s-ambiance.CodeMirror, +.cm-s-ambiance .CodeMirror-gutters { + background-image: url("data:image/png;base64,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"); +} diff --git a/shared/codemirror/theme/base16-dark.css b/shared/codemirror/theme/base16-dark.css index 026a816..c35a38d 100644 --- a/shared/codemirror/theme/base16-dark.css +++ b/shared/codemirror/theme/base16-dark.css @@ -1,38 +1,38 @@ -/* - - Name: Base16 Default Dark - Author: Chris Kempson (http://chriskempson.com) - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; } -.cm-s-base16-dark div.CodeMirror-selected { background: #303030; } -.cm-s-base16-dark .CodeMirror-line::selection, .cm-s-base16-dark .CodeMirror-line > span::selection, .cm-s-base16-dark .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); } -.cm-s-base16-dark .CodeMirror-line::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); } -.cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; } -.cm-s-base16-dark .CodeMirror-guttermarker { color: #ac4142; } -.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; } -.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; } -.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; } - -.cm-s-base16-dark span.cm-comment { color: #8f5536; } -.cm-s-base16-dark span.cm-atom { color: #aa759f; } -.cm-s-base16-dark span.cm-number { color: #aa759f; } - -.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; } -.cm-s-base16-dark span.cm-keyword { color: #ac4142; } -.cm-s-base16-dark span.cm-string { color: #f4bf75; } - -.cm-s-base16-dark span.cm-variable { color: #90a959; } -.cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; } -.cm-s-base16-dark span.cm-def { color: #d28445; } -.cm-s-base16-dark span.cm-bracket { color: #e0e0e0; } -.cm-s-base16-dark span.cm-tag { color: #ac4142; } -.cm-s-base16-dark span.cm-link { color: #aa759f; } -.cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; } - -.cm-s-base16-dark .CodeMirror-activeline-background { background: #202020; } -.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: Base16 Default Dark + Author: Chris Kempson (http://chriskempson.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; } +.cm-s-base16-dark div.CodeMirror-selected { background: #303030; } +.cm-s-base16-dark .CodeMirror-line::selection, .cm-s-base16-dark .CodeMirror-line > span::selection, .cm-s-base16-dark .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); } +.cm-s-base16-dark .CodeMirror-line::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); } +.cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; } +.cm-s-base16-dark .CodeMirror-guttermarker { color: #ac4142; } +.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; } +.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; } +.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; } + +.cm-s-base16-dark span.cm-comment { color: #8f5536; } +.cm-s-base16-dark span.cm-atom { color: #aa759f; } +.cm-s-base16-dark span.cm-number { color: #aa759f; } + +.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; } +.cm-s-base16-dark span.cm-keyword { color: #ac4142; } +.cm-s-base16-dark span.cm-string { color: #f4bf75; } + +.cm-s-base16-dark span.cm-variable { color: #90a959; } +.cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; } +.cm-s-base16-dark span.cm-def { color: #d28445; } +.cm-s-base16-dark span.cm-bracket { color: #e0e0e0; } +.cm-s-base16-dark span.cm-tag { color: #ac4142; } +.cm-s-base16-dark span.cm-link { color: #aa759f; } +.cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; } + +.cm-s-base16-dark .CodeMirror-activeline-background { background: #202020; } +.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/base16-light.css b/shared/codemirror/theme/base16-light.css index 474e0ca..5561f8c 100644 --- a/shared/codemirror/theme/base16-light.css +++ b/shared/codemirror/theme/base16-light.css @@ -1,38 +1,38 @@ -/* - - Name: Base16 Default Light - Author: Chris Kempson (http://chriskempson.com) - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; } -.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; } -.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; } -.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; } -.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; } -.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; } -.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; } -.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; } -.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; } - -.cm-s-base16-light span.cm-comment { color: #8f5536; } -.cm-s-base16-light span.cm-atom { color: #aa759f; } -.cm-s-base16-light span.cm-number { color: #aa759f; } - -.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; } -.cm-s-base16-light span.cm-keyword { color: #ac4142; } -.cm-s-base16-light span.cm-string { color: #f4bf75; } - -.cm-s-base16-light span.cm-variable { color: #90a959; } -.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; } -.cm-s-base16-light span.cm-def { color: #d28445; } -.cm-s-base16-light span.cm-bracket { color: #202020; } -.cm-s-base16-light span.cm-tag { color: #ac4142; } -.cm-s-base16-light span.cm-link { color: #aa759f; } -.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; } - -.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; } -.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: Base16 Default Light + Author: Chris Kempson (http://chriskempson.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; } +.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; } +.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; } +.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; } +.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; } +.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; } +.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; } +.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; } +.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; } + +.cm-s-base16-light span.cm-comment { color: #8f5536; } +.cm-s-base16-light span.cm-atom { color: #aa759f; } +.cm-s-base16-light span.cm-number { color: #aa759f; } + +.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; } +.cm-s-base16-light span.cm-keyword { color: #ac4142; } +.cm-s-base16-light span.cm-string { color: #f4bf75; } + +.cm-s-base16-light span.cm-variable { color: #90a959; } +.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; } +.cm-s-base16-light span.cm-def { color: #d28445; } +.cm-s-base16-light span.cm-bracket { color: #202020; } +.cm-s-base16-light span.cm-tag { color: #ac4142; } +.cm-s-base16-light span.cm-link { color: #aa759f; } +.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; } + +.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; } +.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/bespin.css b/shared/codemirror/theme/bespin.css index 60913ba..becfad9 100644 --- a/shared/codemirror/theme/bespin.css +++ b/shared/codemirror/theme/bespin.css @@ -1,34 +1,34 @@ -/* - - Name: Bespin - Author: Mozilla / Jan T. Sott - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;} -.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;} -.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;} -.cm-s-bespin .CodeMirror-linenumber {color: #666666;} -.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;} - -.cm-s-bespin span.cm-comment {color: #937121;} -.cm-s-bespin span.cm-atom {color: #9b859d;} -.cm-s-bespin span.cm-number {color: #9b859d;} - -.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;} -.cm-s-bespin span.cm-keyword {color: #cf6a4c;} -.cm-s-bespin span.cm-string {color: #f9ee98;} - -.cm-s-bespin span.cm-variable {color: #54be0d;} -.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;} -.cm-s-bespin span.cm-def {color: #cf7d34;} -.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;} -.cm-s-bespin span.cm-bracket {color: #9d9b97;} -.cm-s-bespin span.cm-tag {color: #cf6a4c;} -.cm-s-bespin span.cm-link {color: #9b859d;} - -.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} -.cm-s-bespin .CodeMirror-activeline-background { background: #404040; } +/* + + Name: Bespin + Author: Mozilla / Jan T. Sott + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;} +.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;} +.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;} +.cm-s-bespin .CodeMirror-linenumber {color: #666666;} +.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;} + +.cm-s-bespin span.cm-comment {color: #937121;} +.cm-s-bespin span.cm-atom {color: #9b859d;} +.cm-s-bespin span.cm-number {color: #9b859d;} + +.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;} +.cm-s-bespin span.cm-keyword {color: #cf6a4c;} +.cm-s-bespin span.cm-string {color: #f9ee98;} + +.cm-s-bespin span.cm-variable {color: #54be0d;} +.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;} +.cm-s-bespin span.cm-def {color: #cf7d34;} +.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;} +.cm-s-bespin span.cm-bracket {color: #9d9b97;} +.cm-s-bespin span.cm-tag {color: #cf6a4c;} +.cm-s-bespin span.cm-link {color: #9b859d;} + +.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-bespin .CodeMirror-activeline-background { background: #404040; } diff --git a/shared/codemirror/theme/blackboard.css b/shared/codemirror/theme/blackboard.css index b6eaedb..0fa55e7 100644 --- a/shared/codemirror/theme/blackboard.css +++ b/shared/codemirror/theme/blackboard.css @@ -1,32 +1,32 @@ -/* Port of TextMate's Blackboard theme */ - -.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; } -.cm-s-blackboard div.CodeMirror-selected { background: #253B76; } -.cm-s-blackboard .CodeMirror-line::selection, .cm-s-blackboard .CodeMirror-line > span::selection, .cm-s-blackboard .CodeMirror-line > span > span::selection { background: rgba(37, 59, 118, .99); } -.cm-s-blackboard .CodeMirror-line::-moz-selection, .cm-s-blackboard .CodeMirror-line > span::-moz-selection, .cm-s-blackboard .CodeMirror-line > span > span::-moz-selection { background: rgba(37, 59, 118, .99); } -.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; } -.cm-s-blackboard .CodeMirror-guttermarker { color: #FBDE2D; } -.cm-s-blackboard .CodeMirror-guttermarker-subtle { color: #888; } -.cm-s-blackboard .CodeMirror-linenumber { color: #888; } -.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7; } - -.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-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; } -.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; } - -.cm-s-blackboard .CodeMirror-activeline-background { background: #3C3636; } -.cm-s-blackboard .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; } +/* Port of TextMate's Blackboard theme */ + +.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; } +.cm-s-blackboard div.CodeMirror-selected { background: #253B76; } +.cm-s-blackboard .CodeMirror-line::selection, .cm-s-blackboard .CodeMirror-line > span::selection, .cm-s-blackboard .CodeMirror-line > span > span::selection { background: rgba(37, 59, 118, .99); } +.cm-s-blackboard .CodeMirror-line::-moz-selection, .cm-s-blackboard .CodeMirror-line > span::-moz-selection, .cm-s-blackboard .CodeMirror-line > span > span::-moz-selection { background: rgba(37, 59, 118, .99); } +.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; } +.cm-s-blackboard .CodeMirror-guttermarker { color: #FBDE2D; } +.cm-s-blackboard .CodeMirror-guttermarker-subtle { color: #888; } +.cm-s-blackboard .CodeMirror-linenumber { color: #888; } +.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7; } + +.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-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; } +.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; } + +.cm-s-blackboard .CodeMirror-activeline-background { background: #3C3636; } +.cm-s-blackboard .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; } diff --git a/shared/codemirror/theme/cobalt.css b/shared/codemirror/theme/cobalt.css index d88223e..5de2cb1 100644 --- a/shared/codemirror/theme/cobalt.css +++ b/shared/codemirror/theme/cobalt.css @@ -1,25 +1,25 @@ -.cm-s-cobalt.CodeMirror { background: #002240; color: white; } -.cm-s-cobalt div.CodeMirror-selected { background: #b36539; } -.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); } -.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); } -.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } -.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; } -.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; } -.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; } -.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; } - -.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-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; } -.cm-s-cobalt span.cm-error { color: #9d1e15; } - -.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; } -.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; } +.cm-s-cobalt.CodeMirror { background: #002240; color: white; } +.cm-s-cobalt div.CodeMirror-selected { background: #b36539; } +.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); } +.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); } +.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } +.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; } +.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; } + +.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-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; } +.cm-s-cobalt span.cm-error { color: #9d1e15; } + +.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; } +.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; } diff --git a/shared/codemirror/theme/colorforth.css b/shared/codemirror/theme/colorforth.css index 606899f..7be5e51 100644 --- a/shared/codemirror/theme/colorforth.css +++ b/shared/codemirror/theme/colorforth.css @@ -1,33 +1,33 @@ -.cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; } -.cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } -.cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; } -.cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; } -.cm-s-colorforth .CodeMirror-linenumber { color: #bababa; } -.cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; } - -.cm-s-colorforth span.cm-comment { color: #ededed; } -.cm-s-colorforth span.cm-def { color: #ff1c1c; font-weight:bold; } -.cm-s-colorforth span.cm-keyword { color: #ffd900; } -.cm-s-colorforth span.cm-builtin { color: #00d95a; } -.cm-s-colorforth span.cm-variable { color: #73ff00; } -.cm-s-colorforth span.cm-string { color: #007bff; } -.cm-s-colorforth span.cm-number { color: #00c4ff; } -.cm-s-colorforth span.cm-atom { color: #606060; } - -.cm-s-colorforth span.cm-variable-2 { color: #EEE; } -.cm-s-colorforth span.cm-variable-3 { color: #DDD; } -.cm-s-colorforth span.cm-property {} -.cm-s-colorforth span.cm-operator {} - -.cm-s-colorforth span.cm-meta { color: yellow; } -.cm-s-colorforth span.cm-qualifier { color: #FFF700; } -.cm-s-colorforth span.cm-bracket { color: #cc7; } -.cm-s-colorforth span.cm-tag { color: #FFBD40; } -.cm-s-colorforth span.cm-attribute { color: #FFF700; } -.cm-s-colorforth span.cm-error { color: #f00; } - -.cm-s-colorforth div.CodeMirror-selected { background: #333d53; } - -.cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); } - -.cm-s-colorforth .CodeMirror-activeline-background { background: #253540; } +.cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; } +.cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } +.cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; } +.cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; } +.cm-s-colorforth .CodeMirror-linenumber { color: #bababa; } +.cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-colorforth span.cm-comment { color: #ededed; } +.cm-s-colorforth span.cm-def { color: #ff1c1c; font-weight:bold; } +.cm-s-colorforth span.cm-keyword { color: #ffd900; } +.cm-s-colorforth span.cm-builtin { color: #00d95a; } +.cm-s-colorforth span.cm-variable { color: #73ff00; } +.cm-s-colorforth span.cm-string { color: #007bff; } +.cm-s-colorforth span.cm-number { color: #00c4ff; } +.cm-s-colorforth span.cm-atom { color: #606060; } + +.cm-s-colorforth span.cm-variable-2 { color: #EEE; } +.cm-s-colorforth span.cm-variable-3 { color: #DDD; } +.cm-s-colorforth span.cm-property {} +.cm-s-colorforth span.cm-operator {} + +.cm-s-colorforth span.cm-meta { color: yellow; } +.cm-s-colorforth span.cm-qualifier { color: #FFF700; } +.cm-s-colorforth span.cm-bracket { color: #cc7; } +.cm-s-colorforth span.cm-tag { color: #FFBD40; } +.cm-s-colorforth span.cm-attribute { color: #FFF700; } +.cm-s-colorforth span.cm-error { color: #f00; } + +.cm-s-colorforth div.CodeMirror-selected { background: #333d53; } + +.cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); } + +.cm-s-colorforth .CodeMirror-activeline-background { background: #253540; } diff --git a/shared/codemirror/theme/dracula.css b/shared/codemirror/theme/dracula.css index 57f979a..9f5ab28 100644 --- a/shared/codemirror/theme/dracula.css +++ b/shared/codemirror/theme/dracula.css @@ -1,41 +1,41 @@ -/* - - Name: dracula - Author: Michael Kaminsky (http://github.com/mkaminsky11) - - Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme) - -*/ - - -.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters { - background-color: #282a36 !important; - color: #f8f8f2 !important; - border: none; -} -.cm-s-dracula .CodeMirror-gutters { color: #282a36; } -.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; } -.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; } -.cm-s-dracula.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } -.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } -.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } -.cm-s-dracula span.cm-comment { color: #6272a4; } -.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; } -.cm-s-dracula span.cm-number { color: #bd93f9; } -.cm-s-dracula span.cm-variable { color: #50fa7b; } -.cm-s-dracula span.cm-variable-2 { color: white; } -.cm-s-dracula span.cm-def { color: #ffb86c; } -.cm-s-dracula span.cm-keyword { color: #ff79c6; } -.cm-s-dracula span.cm-operator { color: #ff79c6; } -.cm-s-dracula span.cm-keyword { color: #ff79c6; } -.cm-s-dracula span.cm-atom { color: #bd93f9; } -.cm-s-dracula span.cm-meta { color: #f8f8f2; } -.cm-s-dracula span.cm-tag { color: #ff79c6; } -.cm-s-dracula span.cm-attribute { color: #50fa7b; } -.cm-s-dracula span.cm-qualifier { color: #50fa7b; } -.cm-s-dracula span.cm-property { color: #66d9ef; } -.cm-s-dracula span.cm-builtin { color: #50fa7b; } -.cm-s-dracula span.cm-variable-3 { color: #50fa7b; } - -.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); } -.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: dracula + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme) + +*/ + + +.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters { + background-color: #282a36 !important; + color: #f8f8f2 !important; + border: none; +} +.cm-s-dracula .CodeMirror-gutters { color: #282a36; } +.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; } +.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; } +.cm-s-dracula.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-dracula span.cm-comment { color: #6272a4; } +.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; } +.cm-s-dracula span.cm-number { color: #bd93f9; } +.cm-s-dracula span.cm-variable { color: #50fa7b; } +.cm-s-dracula span.cm-variable-2 { color: white; } +.cm-s-dracula span.cm-def { color: #ffb86c; } +.cm-s-dracula span.cm-keyword { color: #ff79c6; } +.cm-s-dracula span.cm-operator { color: #ff79c6; } +.cm-s-dracula span.cm-keyword { color: #ff79c6; } +.cm-s-dracula span.cm-atom { color: #bd93f9; } +.cm-s-dracula span.cm-meta { color: #f8f8f2; } +.cm-s-dracula span.cm-tag { color: #ff79c6; } +.cm-s-dracula span.cm-attribute { color: #50fa7b; } +.cm-s-dracula span.cm-qualifier { color: #50fa7b; } +.cm-s-dracula span.cm-property { color: #66d9ef; } +.cm-s-dracula span.cm-builtin { color: #50fa7b; } +.cm-s-dracula span.cm-variable-3 { color: #50fa7b; } + +.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); } +.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/eclipse.css b/shared/codemirror/theme/eclipse.css index 1bde460..f8c3148 100644 --- a/shared/codemirror/theme/eclipse.css +++ b/shared/codemirror/theme/eclipse.css @@ -1,23 +1,23 @@ -.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-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 span.cm-error { color: #f00; } - -.cm-s-eclipse .CodeMirror-activeline-background { background: #e8f2ff; } -.cm-s-eclipse .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } +.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-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 span.cm-error { color: #f00; } + +.cm-s-eclipse .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-eclipse .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } diff --git a/shared/codemirror/theme/elegant.css b/shared/codemirror/theme/elegant.css index 45b3ea6..a5929c1 100644 --- a/shared/codemirror/theme/elegant.css +++ b/shared/codemirror/theme/elegant.css @@ -1,13 +1,13 @@ -.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-link { color: #762; } -.cm-s-elegant span.cm-error { background-color: #fdd; } - -.cm-s-elegant .CodeMirror-activeline-background { background: #e8f2ff; } -.cm-s-elegant .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } +.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-link { color: #762; } +.cm-s-elegant span.cm-error { background-color: #fdd; } + +.cm-s-elegant .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-elegant .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } diff --git a/shared/codemirror/theme/erlang-dark.css b/shared/codemirror/theme/erlang-dark.css index 65fe481..cf4a196 100644 --- a/shared/codemirror/theme/erlang-dark.css +++ b/shared/codemirror/theme/erlang-dark.css @@ -1,34 +1,34 @@ -.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; } -.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539; } -.cm-s-erlang-dark .CodeMirror-line::selection, .cm-s-erlang-dark .CodeMirror-line > span::selection, .cm-s-erlang-dark .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); } -.cm-s-erlang-dark .CodeMirror-line::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); } -.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } -.cm-s-erlang-dark .CodeMirror-guttermarker { color: white; } -.cm-s-erlang-dark .CodeMirror-guttermarker-subtle { color: #d0d0d0; } -.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; } -.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white; } - -.cm-s-erlang-dark span.cm-quote { color: #ccc; } -.cm-s-erlang-dark span.cm-atom { color: #f133f1; } -.cm-s-erlang-dark span.cm-attribute { color: #ff80e1; } -.cm-s-erlang-dark span.cm-bracket { color: #ff9d00; } -.cm-s-erlang-dark span.cm-builtin { color: #eaa; } -.cm-s-erlang-dark span.cm-comment { color: #77f; } -.cm-s-erlang-dark span.cm-def { color: #e7a; } -.cm-s-erlang-dark span.cm-keyword { color: #ffee80; } -.cm-s-erlang-dark span.cm-meta { color: #50fefe; } -.cm-s-erlang-dark span.cm-number { color: #ffd0d0; } -.cm-s-erlang-dark span.cm-operator { color: #d55; } -.cm-s-erlang-dark span.cm-property { color: #ccc; } -.cm-s-erlang-dark span.cm-qualifier { color: #ccc; } -.cm-s-erlang-dark span.cm-special { color: #ffbbbb; } -.cm-s-erlang-dark span.cm-string { color: #3ad900; } -.cm-s-erlang-dark span.cm-string-2 { color: #ccc; } -.cm-s-erlang-dark span.cm-tag { color: #9effff; } -.cm-s-erlang-dark span.cm-variable { color: #50fe50; } -.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; } -.cm-s-erlang-dark span.cm-variable-3 { color: #ccc; } -.cm-s-erlang-dark span.cm-error { color: #9d1e15; } - -.cm-s-erlang-dark .CodeMirror-activeline-background { background: #013461; } -.cm-s-erlang-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } +.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; } +.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539; } +.cm-s-erlang-dark .CodeMirror-line::selection, .cm-s-erlang-dark .CodeMirror-line > span::selection, .cm-s-erlang-dark .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); } +.cm-s-erlang-dark .CodeMirror-line::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); } +.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } +.cm-s-erlang-dark .CodeMirror-guttermarker { color: white; } +.cm-s-erlang-dark .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-erlang-dark span.cm-quote { color: #ccc; } +.cm-s-erlang-dark span.cm-atom { color: #f133f1; } +.cm-s-erlang-dark span.cm-attribute { color: #ff80e1; } +.cm-s-erlang-dark span.cm-bracket { color: #ff9d00; } +.cm-s-erlang-dark span.cm-builtin { color: #eaa; } +.cm-s-erlang-dark span.cm-comment { color: #77f; } +.cm-s-erlang-dark span.cm-def { color: #e7a; } +.cm-s-erlang-dark span.cm-keyword { color: #ffee80; } +.cm-s-erlang-dark span.cm-meta { color: #50fefe; } +.cm-s-erlang-dark span.cm-number { color: #ffd0d0; } +.cm-s-erlang-dark span.cm-operator { color: #d55; } +.cm-s-erlang-dark span.cm-property { color: #ccc; } +.cm-s-erlang-dark span.cm-qualifier { color: #ccc; } +.cm-s-erlang-dark span.cm-special { color: #ffbbbb; } +.cm-s-erlang-dark span.cm-string { color: #3ad900; } +.cm-s-erlang-dark span.cm-string-2 { color: #ccc; } +.cm-s-erlang-dark span.cm-tag { color: #9effff; } +.cm-s-erlang-dark span.cm-variable { color: #50fe50; } +.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; } +.cm-s-erlang-dark span.cm-variable-3 { color: #ccc; } +.cm-s-erlang-dark span.cm-error { color: #9d1e15; } + +.cm-s-erlang-dark .CodeMirror-activeline-background { background: #013461; } +.cm-s-erlang-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/shared/codemirror/theme/hopscotch.css b/shared/codemirror/theme/hopscotch.css index 7d05431..c40094d 100644 --- a/shared/codemirror/theme/hopscotch.css +++ b/shared/codemirror/theme/hopscotch.css @@ -1,34 +1,34 @@ -/* - - Name: Hopscotch - Author: Jan T. Sott - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;} -.cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;} -.cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;} -.cm-s-hopscotch .CodeMirror-linenumber {color: #797379;} -.cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;} - -.cm-s-hopscotch span.cm-comment {color: #b33508;} -.cm-s-hopscotch span.cm-atom {color: #c85e7c;} -.cm-s-hopscotch span.cm-number {color: #c85e7c;} - -.cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;} -.cm-s-hopscotch span.cm-keyword {color: #dd464c;} -.cm-s-hopscotch span.cm-string {color: #fdcc59;} - -.cm-s-hopscotch span.cm-variable {color: #8fc13e;} -.cm-s-hopscotch span.cm-variable-2 {color: #1290bf;} -.cm-s-hopscotch span.cm-def {color: #fd8b19;} -.cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;} -.cm-s-hopscotch span.cm-bracket {color: #d5d3d5;} -.cm-s-hopscotch span.cm-tag {color: #dd464c;} -.cm-s-hopscotch span.cm-link {color: #c85e7c;} - -.cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} -.cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; } +/* + + Name: Hopscotch + Author: Jan T. Sott + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;} +.cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;} +.cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;} +.cm-s-hopscotch .CodeMirror-linenumber {color: #797379;} +.cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;} + +.cm-s-hopscotch span.cm-comment {color: #b33508;} +.cm-s-hopscotch span.cm-atom {color: #c85e7c;} +.cm-s-hopscotch span.cm-number {color: #c85e7c;} + +.cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;} +.cm-s-hopscotch span.cm-keyword {color: #dd464c;} +.cm-s-hopscotch span.cm-string {color: #fdcc59;} + +.cm-s-hopscotch span.cm-variable {color: #8fc13e;} +.cm-s-hopscotch span.cm-variable-2 {color: #1290bf;} +.cm-s-hopscotch span.cm-def {color: #fd8b19;} +.cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;} +.cm-s-hopscotch span.cm-bracket {color: #d5d3d5;} +.cm-s-hopscotch span.cm-tag {color: #dd464c;} +.cm-s-hopscotch span.cm-link {color: #c85e7c;} + +.cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; } diff --git a/shared/codemirror/theme/icecoder.css b/shared/codemirror/theme/icecoder.css index ffebaf2..fe21749 100644 --- a/shared/codemirror/theme/icecoder.css +++ b/shared/codemirror/theme/icecoder.css @@ -1,43 +1,43 @@ -/* -ICEcoder default theme by Matt Pass, used in code editor available at https://icecoder.net -*/ - -.cm-s-icecoder { color: #666; background: #1d1d1b; } - -.cm-s-icecoder span.cm-keyword { color: #eee; font-weight:bold; } /* off-white 1 */ -.cm-s-icecoder span.cm-atom { color: #e1c76e; } /* yellow */ -.cm-s-icecoder span.cm-number { color: #6cb5d9; } /* blue */ -.cm-s-icecoder span.cm-def { color: #b9ca4a; } /* green */ - -.cm-s-icecoder span.cm-variable { color: #6cb5d9; } /* blue */ -.cm-s-icecoder span.cm-variable-2 { color: #cc1e5c; } /* pink */ -.cm-s-icecoder span.cm-variable-3 { color: #f9602c; } /* orange */ - -.cm-s-icecoder span.cm-property { color: #eee; } /* off-white 1 */ -.cm-s-icecoder span.cm-operator { color: #9179bb; } /* purple */ -.cm-s-icecoder span.cm-comment { color: #97a3aa; } /* grey-blue */ - -.cm-s-icecoder span.cm-string { color: #b9ca4a; } /* green */ -.cm-s-icecoder span.cm-string-2 { color: #6cb5d9; } /* blue */ - -.cm-s-icecoder span.cm-meta { color: #555; } /* grey */ - -.cm-s-icecoder span.cm-qualifier { color: #555; } /* grey */ -.cm-s-icecoder span.cm-builtin { color: #214e7b; } /* bright blue */ -.cm-s-icecoder span.cm-bracket { color: #cc7; } /* grey-yellow */ - -.cm-s-icecoder span.cm-tag { color: #e8e8e8; } /* off-white 2 */ -.cm-s-icecoder span.cm-attribute { color: #099; } /* teal */ - -.cm-s-icecoder span.cm-header { color: #6a0d6a; } /* purple-pink */ -.cm-s-icecoder span.cm-quote { color: #186718; } /* dark green */ -.cm-s-icecoder span.cm-hr { color: #888; } /* mid-grey */ -.cm-s-icecoder span.cm-link { color: #e1c76e; } /* yellow */ -.cm-s-icecoder span.cm-error { color: #d00; } /* red */ - -.cm-s-icecoder .CodeMirror-cursor { border-left: 1px solid white; } -.cm-s-icecoder div.CodeMirror-selected { color: #fff; background: #037; } -.cm-s-icecoder .CodeMirror-gutters { background: #1d1d1b; min-width: 41px; border-right: 0; } -.cm-s-icecoder .CodeMirror-linenumber { color: #555; cursor: default; } -.cm-s-icecoder .CodeMirror-matchingbracket { color: #fff !important; background: #555 !important; } -.cm-s-icecoder .CodeMirror-activeline-background { background: #000; } +/* +ICEcoder default theme by Matt Pass, used in code editor available at https://icecoder.net +*/ + +.cm-s-icecoder { color: #666; background: #1d1d1b; } + +.cm-s-icecoder span.cm-keyword { color: #eee; font-weight:bold; } /* off-white 1 */ +.cm-s-icecoder span.cm-atom { color: #e1c76e; } /* yellow */ +.cm-s-icecoder span.cm-number { color: #6cb5d9; } /* blue */ +.cm-s-icecoder span.cm-def { color: #b9ca4a; } /* green */ + +.cm-s-icecoder span.cm-variable { color: #6cb5d9; } /* blue */ +.cm-s-icecoder span.cm-variable-2 { color: #cc1e5c; } /* pink */ +.cm-s-icecoder span.cm-variable-3 { color: #f9602c; } /* orange */ + +.cm-s-icecoder span.cm-property { color: #eee; } /* off-white 1 */ +.cm-s-icecoder span.cm-operator { color: #9179bb; } /* purple */ +.cm-s-icecoder span.cm-comment { color: #97a3aa; } /* grey-blue */ + +.cm-s-icecoder span.cm-string { color: #b9ca4a; } /* green */ +.cm-s-icecoder span.cm-string-2 { color: #6cb5d9; } /* blue */ + +.cm-s-icecoder span.cm-meta { color: #555; } /* grey */ + +.cm-s-icecoder span.cm-qualifier { color: #555; } /* grey */ +.cm-s-icecoder span.cm-builtin { color: #214e7b; } /* bright blue */ +.cm-s-icecoder span.cm-bracket { color: #cc7; } /* grey-yellow */ + +.cm-s-icecoder span.cm-tag { color: #e8e8e8; } /* off-white 2 */ +.cm-s-icecoder span.cm-attribute { color: #099; } /* teal */ + +.cm-s-icecoder span.cm-header { color: #6a0d6a; } /* purple-pink */ +.cm-s-icecoder span.cm-quote { color: #186718; } /* dark green */ +.cm-s-icecoder span.cm-hr { color: #888; } /* mid-grey */ +.cm-s-icecoder span.cm-link { color: #e1c76e; } /* yellow */ +.cm-s-icecoder span.cm-error { color: #d00; } /* red */ + +.cm-s-icecoder .CodeMirror-cursor { border-left: 1px solid white; } +.cm-s-icecoder div.CodeMirror-selected { color: #fff; background: #037; } +.cm-s-icecoder .CodeMirror-gutters { background: #1d1d1b; min-width: 41px; border-right: 0; } +.cm-s-icecoder .CodeMirror-linenumber { color: #555; cursor: default; } +.cm-s-icecoder .CodeMirror-matchingbracket { color: #fff !important; background: #555 !important; } +.cm-s-icecoder .CodeMirror-activeline-background { background: #000; } diff --git a/shared/codemirror/theme/isotope.css b/shared/codemirror/theme/isotope.css index d0d6263..a9642ac 100644 --- a/shared/codemirror/theme/isotope.css +++ b/shared/codemirror/theme/isotope.css @@ -1,34 +1,34 @@ -/* - - Name: Isotope - Author: David Desandro / Jan T. Sott - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;} -.cm-s-isotope div.CodeMirror-selected {background: #404040 !important;} -.cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;} -.cm-s-isotope .CodeMirror-linenumber {color: #808080;} -.cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;} - -.cm-s-isotope span.cm-comment {color: #3300ff;} -.cm-s-isotope span.cm-atom {color: #cc00ff;} -.cm-s-isotope span.cm-number {color: #cc00ff;} - -.cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;} -.cm-s-isotope span.cm-keyword {color: #ff0000;} -.cm-s-isotope span.cm-string {color: #ff0099;} - -.cm-s-isotope span.cm-variable {color: #33ff00;} -.cm-s-isotope span.cm-variable-2 {color: #0066ff;} -.cm-s-isotope span.cm-def {color: #ff9900;} -.cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;} -.cm-s-isotope span.cm-bracket {color: #e0e0e0;} -.cm-s-isotope span.cm-tag {color: #ff0000;} -.cm-s-isotope span.cm-link {color: #cc00ff;} - -.cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} -.cm-s-isotope .CodeMirror-activeline-background { background: #202020; } +/* + + Name: Isotope + Author: David Desandro / Jan T. Sott + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;} +.cm-s-isotope div.CodeMirror-selected {background: #404040 !important;} +.cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;} +.cm-s-isotope .CodeMirror-linenumber {color: #808080;} +.cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;} + +.cm-s-isotope span.cm-comment {color: #3300ff;} +.cm-s-isotope span.cm-atom {color: #cc00ff;} +.cm-s-isotope span.cm-number {color: #cc00ff;} + +.cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;} +.cm-s-isotope span.cm-keyword {color: #ff0000;} +.cm-s-isotope span.cm-string {color: #ff0099;} + +.cm-s-isotope span.cm-variable {color: #33ff00;} +.cm-s-isotope span.cm-variable-2 {color: #0066ff;} +.cm-s-isotope span.cm-def {color: #ff9900;} +.cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;} +.cm-s-isotope span.cm-bracket {color: #e0e0e0;} +.cm-s-isotope span.cm-tag {color: #ff0000;} +.cm-s-isotope span.cm-link {color: #cc00ff;} + +.cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-isotope .CodeMirror-activeline-background { background: #202020; } diff --git a/shared/codemirror/theme/lesser-dark.css b/shared/codemirror/theme/lesser-dark.css index 690c183..14771ca 100644 --- a/shared/codemirror/theme/lesser-dark.css +++ b/shared/codemirror/theme/lesser-dark.css @@ -1,47 +1,47 @@ -/* -http://lesscss.org/ dark theme -Ported to CodeMirror by Peter Kroon -*/ -.cm-s-lesser-dark { - line-height: 1.3em; -} -.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; } -.cm-s-lesser-dark div.CodeMirror-selected { background: #45443B; } /* 33322B*/ -.cm-s-lesser-dark .CodeMirror-line::selection, .cm-s-lesser-dark .CodeMirror-line > span::selection, .cm-s-lesser-dark .CodeMirror-line > span > span::selection { background: rgba(69, 68, 59, .99); } -.cm-s-lesser-dark .CodeMirror-line::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(69, 68, 59, .99); } -.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white; } -.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/ - -.cm-s-lesser-dark.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/ - -.cm-s-lesser-dark .CodeMirror-gutters { background: #262626; border-right:1px solid #aaa; } -.cm-s-lesser-dark .CodeMirror-guttermarker { color: #599eff; } -.cm-s-lesser-dark .CodeMirror-guttermarker-subtle { color: #777; } -.cm-s-lesser-dark .CodeMirror-linenumber { color: #777; } - -.cm-s-lesser-dark span.cm-header { color: #a0a; } -.cm-s-lesser-dark span.cm-quote { color: #090; } -.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-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-hr { color: #999; } -.cm-s-lesser-dark span.cm-link { color: #00c; } -.cm-s-lesser-dark span.cm-error { color: #9d1e15; } - -.cm-s-lesser-dark .CodeMirror-activeline-background { background: #3C3A3A; } -.cm-s-lesser-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } +/* +http://lesscss.org/ dark theme +Ported to CodeMirror by Peter Kroon +*/ +.cm-s-lesser-dark { + line-height: 1.3em; +} +.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; } +.cm-s-lesser-dark div.CodeMirror-selected { background: #45443B; } /* 33322B*/ +.cm-s-lesser-dark .CodeMirror-line::selection, .cm-s-lesser-dark .CodeMirror-line > span::selection, .cm-s-lesser-dark .CodeMirror-line > span > span::selection { background: rgba(69, 68, 59, .99); } +.cm-s-lesser-dark .CodeMirror-line::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(69, 68, 59, .99); } +.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white; } +.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/ + +.cm-s-lesser-dark.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/ + +.cm-s-lesser-dark .CodeMirror-gutters { background: #262626; border-right:1px solid #aaa; } +.cm-s-lesser-dark .CodeMirror-guttermarker { color: #599eff; } +.cm-s-lesser-dark .CodeMirror-guttermarker-subtle { color: #777; } +.cm-s-lesser-dark .CodeMirror-linenumber { color: #777; } + +.cm-s-lesser-dark span.cm-header { color: #a0a; } +.cm-s-lesser-dark span.cm-quote { color: #090; } +.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-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-hr { color: #999; } +.cm-s-lesser-dark span.cm-link { color: #00c; } +.cm-s-lesser-dark span.cm-error { color: #9d1e15; } + +.cm-s-lesser-dark .CodeMirror-activeline-background { background: #3C3A3A; } +.cm-s-lesser-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/shared/codemirror/theme/liquibyte.css b/shared/codemirror/theme/liquibyte.css index 9db8bde..377257e 100644 --- a/shared/codemirror/theme/liquibyte.css +++ b/shared/codemirror/theme/liquibyte.css @@ -1,95 +1,95 @@ -.cm-s-liquibyte.CodeMirror { - background-color: #000; - color: #fff; - line-height: 1.2em; - font-size: 1em; -} -.cm-s-liquibyte .CodeMirror-focused .cm-matchhighlight { - text-decoration: underline; - text-decoration-color: #0f0; - text-decoration-style: wavy; -} -.cm-s-liquibyte .cm-trailingspace { - text-decoration: line-through; - text-decoration-color: #f00; - text-decoration-style: dotted; -} -.cm-s-liquibyte .cm-tab { - text-decoration: line-through; - text-decoration-color: #404040; - text-decoration-style: dotted; -} -.cm-s-liquibyte .CodeMirror-gutters { background-color: #262626; border-right: 1px solid #505050; padding-right: 0.8em; } -.cm-s-liquibyte .CodeMirror-gutter-elt div { font-size: 1.2em; } -.cm-s-liquibyte .CodeMirror-guttermarker { } -.cm-s-liquibyte .CodeMirror-guttermarker-subtle { } -.cm-s-liquibyte .CodeMirror-linenumber { color: #606060; padding-left: 0; } -.cm-s-liquibyte .CodeMirror-cursor { border-left: 1px solid #eee; } - -.cm-s-liquibyte span.cm-comment { color: #008000; } -.cm-s-liquibyte span.cm-def { color: #ffaf40; font-weight: bold; } -.cm-s-liquibyte span.cm-keyword { color: #c080ff; font-weight: bold; } -.cm-s-liquibyte span.cm-builtin { color: #ffaf40; font-weight: bold; } -.cm-s-liquibyte span.cm-variable { color: #5967ff; font-weight: bold; } -.cm-s-liquibyte span.cm-string { color: #ff8000; } -.cm-s-liquibyte span.cm-number { color: #0f0; font-weight: bold; } -.cm-s-liquibyte span.cm-atom { color: #bf3030; font-weight: bold; } - -.cm-s-liquibyte span.cm-variable-2 { color: #007f7f; font-weight: bold; } -.cm-s-liquibyte span.cm-variable-3 { color: #c080ff; font-weight: bold; } -.cm-s-liquibyte span.cm-property { color: #999; font-weight: bold; } -.cm-s-liquibyte span.cm-operator { color: #fff; } - -.cm-s-liquibyte span.cm-meta { color: #0f0; } -.cm-s-liquibyte span.cm-qualifier { color: #fff700; font-weight: bold; } -.cm-s-liquibyte span.cm-bracket { color: #cc7; } -.cm-s-liquibyte span.cm-tag { color: #ff0; font-weight: bold; } -.cm-s-liquibyte span.cm-attribute { color: #c080ff; font-weight: bold; } -.cm-s-liquibyte span.cm-error { color: #f00; } - -.cm-s-liquibyte div.CodeMirror-selected { background-color: rgba(255, 0, 0, 0.25); } - -.cm-s-liquibyte span.cm-compilation { background-color: rgba(255, 255, 255, 0.12); } - -.cm-s-liquibyte .CodeMirror-activeline-background { background-color: rgba(0, 255, 0, 0.15); } - -/* Default styles for common addons */ -.cm-s-liquibyte .CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; } -.cm-s-liquibyte .CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; } -.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); } -/* Scrollbars */ -/* Simple */ -.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, div.CodeMirror-simplescroll-vertical div:hover { - background-color: rgba(80, 80, 80, .7); -} -.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, div.CodeMirror-simplescroll-vertical div { - background-color: rgba(80, 80, 80, .3); - border: 1px solid #404040; - border-radius: 5px; -} -.cm-s-liquibyte div.CodeMirror-simplescroll-vertical div { - border-top: 1px solid #404040; - border-bottom: 1px solid #404040; -} -.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div { - border-left: 1px solid #404040; - border-right: 1px solid #404040; -} -.cm-s-liquibyte div.CodeMirror-simplescroll-vertical { - background-color: #262626; -} -.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal { - background-color: #262626; - border-top: 1px solid #404040; -} -/* Overlay */ -.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div { - background-color: #404040; - border-radius: 5px; -} -.cm-s-liquibyte div.CodeMirror-overlayscroll-vertical div { - border: 1px solid #404040; -} -.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div { - border: 1px solid #404040; -} +.cm-s-liquibyte.CodeMirror { + background-color: #000; + color: #fff; + line-height: 1.2em; + font-size: 1em; +} +.cm-s-liquibyte .CodeMirror-focused .cm-matchhighlight { + text-decoration: underline; + text-decoration-color: #0f0; + text-decoration-style: wavy; +} +.cm-s-liquibyte .cm-trailingspace { + text-decoration: line-through; + text-decoration-color: #f00; + text-decoration-style: dotted; +} +.cm-s-liquibyte .cm-tab { + text-decoration: line-through; + text-decoration-color: #404040; + text-decoration-style: dotted; +} +.cm-s-liquibyte .CodeMirror-gutters { background-color: #262626; border-right: 1px solid #505050; padding-right: 0.8em; } +.cm-s-liquibyte .CodeMirror-gutter-elt div { font-size: 1.2em; } +.cm-s-liquibyte .CodeMirror-guttermarker { } +.cm-s-liquibyte .CodeMirror-guttermarker-subtle { } +.cm-s-liquibyte .CodeMirror-linenumber { color: #606060; padding-left: 0; } +.cm-s-liquibyte .CodeMirror-cursor { border-left: 1px solid #eee; } + +.cm-s-liquibyte span.cm-comment { color: #008000; } +.cm-s-liquibyte span.cm-def { color: #ffaf40; font-weight: bold; } +.cm-s-liquibyte span.cm-keyword { color: #c080ff; font-weight: bold; } +.cm-s-liquibyte span.cm-builtin { color: #ffaf40; font-weight: bold; } +.cm-s-liquibyte span.cm-variable { color: #5967ff; font-weight: bold; } +.cm-s-liquibyte span.cm-string { color: #ff8000; } +.cm-s-liquibyte span.cm-number { color: #0f0; font-weight: bold; } +.cm-s-liquibyte span.cm-atom { color: #bf3030; font-weight: bold; } + +.cm-s-liquibyte span.cm-variable-2 { color: #007f7f; font-weight: bold; } +.cm-s-liquibyte span.cm-variable-3 { color: #c080ff; font-weight: bold; } +.cm-s-liquibyte span.cm-property { color: #999; font-weight: bold; } +.cm-s-liquibyte span.cm-operator { color: #fff; } + +.cm-s-liquibyte span.cm-meta { color: #0f0; } +.cm-s-liquibyte span.cm-qualifier { color: #fff700; font-weight: bold; } +.cm-s-liquibyte span.cm-bracket { color: #cc7; } +.cm-s-liquibyte span.cm-tag { color: #ff0; font-weight: bold; } +.cm-s-liquibyte span.cm-attribute { color: #c080ff; font-weight: bold; } +.cm-s-liquibyte span.cm-error { color: #f00; } + +.cm-s-liquibyte div.CodeMirror-selected { background-color: rgba(255, 0, 0, 0.25); } + +.cm-s-liquibyte span.cm-compilation { background-color: rgba(255, 255, 255, 0.12); } + +.cm-s-liquibyte .CodeMirror-activeline-background { background-color: rgba(0, 255, 0, 0.15); } + +/* Default styles for common addons */ +.cm-s-liquibyte .CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; } +.cm-s-liquibyte .CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; } +.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); } +/* Scrollbars */ +/* Simple */ +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, div.CodeMirror-simplescroll-vertical div:hover { + background-color: rgba(80, 80, 80, .7); +} +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, div.CodeMirror-simplescroll-vertical div { + background-color: rgba(80, 80, 80, .3); + border: 1px solid #404040; + border-radius: 5px; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-vertical div { + border-top: 1px solid #404040; + border-bottom: 1px solid #404040; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div { + border-left: 1px solid #404040; + border-right: 1px solid #404040; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-vertical { + background-color: #262626; +} +.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal { + background-color: #262626; + border-top: 1px solid #404040; +} +/* Overlay */ +.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div { + background-color: #404040; + border-radius: 5px; +} +.cm-s-liquibyte div.CodeMirror-overlayscroll-vertical div { + border: 1px solid #404040; +} +.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div { + border: 1px solid #404040; +} diff --git a/shared/codemirror/theme/material.css b/shared/codemirror/theme/material.css index 91ed6ce..f4eefa8 100644 --- a/shared/codemirror/theme/material.css +++ b/shared/codemirror/theme/material.css @@ -1,53 +1,53 @@ -/* - - Name: material - Author: Michael Kaminsky (http://github.com/mkaminsky11) - - Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme) - -*/ - -.cm-s-material { - background-color: #263238; - color: rgba(233, 237, 237, 1); -} -.cm-s-material .CodeMirror-gutters { - background: #263238; - color: rgb(83,127,126); - border: none; -} -.cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); } -.cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } -.cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } -.cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } -.cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } -.cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } - -.cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); } -.cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); } -.cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); } -.cm-s-material .cm-variable-2 { color: #80CBC4; } -.cm-s-material .cm-variable-3 { color: #82B1FF; } -.cm-s-material .cm-builtin { color: #DECB6B; } -.cm-s-material .cm-atom { color: #F77669; } -.cm-s-material .cm-number { color: #F77669; } -.cm-s-material .cm-def { color: rgba(233, 237, 237, 1); } -.cm-s-material .cm-string { color: #C3E88D; } -.cm-s-material .cm-string-2 { color: #80CBC4; } -.cm-s-material .cm-comment { color: #546E7A; } -.cm-s-material .cm-variable { color: #82B1FF; } -.cm-s-material .cm-tag { color: #80CBC4; } -.cm-s-material .cm-meta { color: #80CBC4; } -.cm-s-material .cm-attribute { color: #FFCB6B; } -.cm-s-material .cm-property { color: #80CBAE; } -.cm-s-material .cm-qualifier { color: #DECB6B; } -.cm-s-material .cm-variable-3 { color: #DECB6B; } -.cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); } -.cm-s-material .cm-error { - color: rgba(255, 255, 255, 1.0); - background-color: #EC5F67; -} -.cm-s-material .CodeMirror-matchingbracket { - text-decoration: underline; - color: white !important; -} +/* + + Name: material + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme) + +*/ + +.cm-s-material { + background-color: #263238; + color: rgba(233, 237, 237, 1); +} +.cm-s-material .CodeMirror-gutters { + background: #263238; + color: rgb(83,127,126); + border: none; +} +.cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); } +.cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } +.cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); } +.cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } + +.cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); } +.cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); } +.cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); } +.cm-s-material .cm-variable-2 { color: #80CBC4; } +.cm-s-material .cm-variable-3 { color: #82B1FF; } +.cm-s-material .cm-builtin { color: #DECB6B; } +.cm-s-material .cm-atom { color: #F77669; } +.cm-s-material .cm-number { color: #F77669; } +.cm-s-material .cm-def { color: rgba(233, 237, 237, 1); } +.cm-s-material .cm-string { color: #C3E88D; } +.cm-s-material .cm-string-2 { color: #80CBC4; } +.cm-s-material .cm-comment { color: #546E7A; } +.cm-s-material .cm-variable { color: #82B1FF; } +.cm-s-material .cm-tag { color: #80CBC4; } +.cm-s-material .cm-meta { color: #80CBC4; } +.cm-s-material .cm-attribute { color: #FFCB6B; } +.cm-s-material .cm-property { color: #80CBAE; } +.cm-s-material .cm-qualifier { color: #DECB6B; } +.cm-s-material .cm-variable-3 { color: #DECB6B; } +.cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); } +.cm-s-material .cm-error { + color: rgba(255, 255, 255, 1.0); + background-color: #EC5F67; +} +.cm-s-material .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/shared/codemirror/theme/mbo.css b/shared/codemirror/theme/mbo.css index e164fcf..a64c0fd 100644 --- a/shared/codemirror/theme/mbo.css +++ b/shared/codemirror/theme/mbo.css @@ -1,37 +1,37 @@ -/****************************************************************/ -/* Based on mbonaci's Brackets mbo theme */ -/* https://github.com/mbonaci/global/blob/master/Mbo.tmTheme */ -/* Create your own: http://tmtheme-editor.herokuapp.com */ -/****************************************************************/ - -.cm-s-mbo.CodeMirror { background: #2c2c2c; color: #ffffec; } -.cm-s-mbo div.CodeMirror-selected { background: #716C62; } -.cm-s-mbo .CodeMirror-line::selection, .cm-s-mbo .CodeMirror-line > span::selection, .cm-s-mbo .CodeMirror-line > span > span::selection { background: rgba(113, 108, 98, .99); } -.cm-s-mbo .CodeMirror-line::-moz-selection, .cm-s-mbo .CodeMirror-line > span::-moz-selection, .cm-s-mbo .CodeMirror-line > span > span::-moz-selection { background: rgba(113, 108, 98, .99); } -.cm-s-mbo .CodeMirror-gutters { background: #4e4e4e; border-right: 0px; } -.cm-s-mbo .CodeMirror-guttermarker { color: white; } -.cm-s-mbo .CodeMirror-guttermarker-subtle { color: grey; } -.cm-s-mbo .CodeMirror-linenumber { color: #dadada; } -.cm-s-mbo .CodeMirror-cursor { border-left: 1px solid #ffffec; } - -.cm-s-mbo span.cm-comment { color: #95958a; } -.cm-s-mbo span.cm-atom { color: #00a8c6; } -.cm-s-mbo span.cm-number { color: #00a8c6; } - -.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute { color: #9ddfe9; } -.cm-s-mbo span.cm-keyword { color: #ffb928; } -.cm-s-mbo span.cm-string { color: #ffcf6c; } -.cm-s-mbo span.cm-string.cm-property { color: #ffffec; } - -.cm-s-mbo span.cm-variable { color: #ffffec; } -.cm-s-mbo span.cm-variable-2 { color: #00a8c6; } -.cm-s-mbo span.cm-def { color: #ffffec; } -.cm-s-mbo span.cm-bracket { color: #fffffc; font-weight: bold; } -.cm-s-mbo span.cm-tag { color: #9ddfe9; } -.cm-s-mbo span.cm-link { color: #f54b07; } -.cm-s-mbo span.cm-error { border-bottom: #636363; color: #ffffec; } -.cm-s-mbo span.cm-qualifier { color: #ffffec; } - -.cm-s-mbo .CodeMirror-activeline-background { background: #494b41; } -.cm-s-mbo .CodeMirror-matchingbracket { color: #ffb928 !important; } -.cm-s-mbo .CodeMirror-matchingtag { background: rgba(255, 255, 255, .37); } +/****************************************************************/ +/* Based on mbonaci's Brackets mbo theme */ +/* https://github.com/mbonaci/global/blob/master/Mbo.tmTheme */ +/* Create your own: http://tmtheme-editor.herokuapp.com */ +/****************************************************************/ + +.cm-s-mbo.CodeMirror { background: #2c2c2c; color: #ffffec; } +.cm-s-mbo div.CodeMirror-selected { background: #716C62; } +.cm-s-mbo .CodeMirror-line::selection, .cm-s-mbo .CodeMirror-line > span::selection, .cm-s-mbo .CodeMirror-line > span > span::selection { background: rgba(113, 108, 98, .99); } +.cm-s-mbo .CodeMirror-line::-moz-selection, .cm-s-mbo .CodeMirror-line > span::-moz-selection, .cm-s-mbo .CodeMirror-line > span > span::-moz-selection { background: rgba(113, 108, 98, .99); } +.cm-s-mbo .CodeMirror-gutters { background: #4e4e4e; border-right: 0px; } +.cm-s-mbo .CodeMirror-guttermarker { color: white; } +.cm-s-mbo .CodeMirror-guttermarker-subtle { color: grey; } +.cm-s-mbo .CodeMirror-linenumber { color: #dadada; } +.cm-s-mbo .CodeMirror-cursor { border-left: 1px solid #ffffec; } + +.cm-s-mbo span.cm-comment { color: #95958a; } +.cm-s-mbo span.cm-atom { color: #00a8c6; } +.cm-s-mbo span.cm-number { color: #00a8c6; } + +.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute { color: #9ddfe9; } +.cm-s-mbo span.cm-keyword { color: #ffb928; } +.cm-s-mbo span.cm-string { color: #ffcf6c; } +.cm-s-mbo span.cm-string.cm-property { color: #ffffec; } + +.cm-s-mbo span.cm-variable { color: #ffffec; } +.cm-s-mbo span.cm-variable-2 { color: #00a8c6; } +.cm-s-mbo span.cm-def { color: #ffffec; } +.cm-s-mbo span.cm-bracket { color: #fffffc; font-weight: bold; } +.cm-s-mbo span.cm-tag { color: #9ddfe9; } +.cm-s-mbo span.cm-link { color: #f54b07; } +.cm-s-mbo span.cm-error { border-bottom: #636363; color: #ffffec; } +.cm-s-mbo span.cm-qualifier { color: #ffffec; } + +.cm-s-mbo .CodeMirror-activeline-background { background: #494b41; } +.cm-s-mbo .CodeMirror-matchingbracket { color: #ffb928 !important; } +.cm-s-mbo .CodeMirror-matchingtag { background: rgba(255, 255, 255, .37); } diff --git a/shared/codemirror/theme/mdn-like.css b/shared/codemirror/theme/mdn-like.css index f325d45..cc4aa15 100644 --- a/shared/codemirror/theme/mdn-like.css +++ b/shared/codemirror/theme/mdn-like.css @@ -1,46 +1,46 @@ -/* - MDN-LIKE Theme - Mozilla - Ported to CodeMirror by Peter Kroon - Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues - GitHub: @peterkroon - - The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation - -*/ -.cm-s-mdn-like.CodeMirror { color: #999; background-color: #fff; } -.cm-s-mdn-like div.CodeMirror-selected { background: #cfc; } -.cm-s-mdn-like .CodeMirror-line::selection, .cm-s-mdn-like .CodeMirror-line > span::selection, .cm-s-mdn-like .CodeMirror-line > span > span::selection { background: #cfc; } -.cm-s-mdn-like .CodeMirror-line::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span > span::-moz-selection { background: #cfc; } - -.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; } -.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; } -.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; } - -.cm-s-mdn-like .cm-keyword { color: #6262FF; } -.cm-s-mdn-like .cm-atom { color: #F90; } -.cm-s-mdn-like .cm-number { color: #ca7841; } -.cm-s-mdn-like .cm-def { color: #8DA6CE; } -.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; } -.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; } - -.cm-s-mdn-like .cm-variable { color: #07a; } -.cm-s-mdn-like .cm-property { color: #905; } -.cm-s-mdn-like .cm-qualifier { color: #690; } - -.cm-s-mdn-like .cm-operator { color: #cda869; } -.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; } -.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; } -.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/ -.cm-s-mdn-like .cm-meta { color: #000; } /*?*/ -.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/ -.cm-s-mdn-like .cm-tag { color: #997643; } -.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/ -.cm-s-mdn-like .cm-header { color: #FF6400; } -.cm-s-mdn-like .cm-hr { color: #AEAEAE; } -.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } -.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; } - -div.cm-s-mdn-like .CodeMirror-activeline-background { background: #efefff; } -div.cm-s-mdn-like span.CodeMirror-matchingbracket { outline:1px solid grey; color: inherit; } - -.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,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); } +/* + MDN-LIKE Theme - Mozilla + Ported to CodeMirror by Peter Kroon + Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues + GitHub: @peterkroon + + The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation + +*/ +.cm-s-mdn-like.CodeMirror { color: #999; background-color: #fff; } +.cm-s-mdn-like div.CodeMirror-selected { background: #cfc; } +.cm-s-mdn-like .CodeMirror-line::selection, .cm-s-mdn-like .CodeMirror-line > span::selection, .cm-s-mdn-like .CodeMirror-line > span > span::selection { background: #cfc; } +.cm-s-mdn-like .CodeMirror-line::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span > span::-moz-selection { background: #cfc; } + +.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; } +.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; } +.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; } + +.cm-s-mdn-like .cm-keyword { color: #6262FF; } +.cm-s-mdn-like .cm-atom { color: #F90; } +.cm-s-mdn-like .cm-number { color: #ca7841; } +.cm-s-mdn-like .cm-def { color: #8DA6CE; } +.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; } +.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; } + +.cm-s-mdn-like .cm-variable { color: #07a; } +.cm-s-mdn-like .cm-property { color: #905; } +.cm-s-mdn-like .cm-qualifier { color: #690; } + +.cm-s-mdn-like .cm-operator { color: #cda869; } +.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; } +.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; } +.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/ +.cm-s-mdn-like .cm-meta { color: #000; } /*?*/ +.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/ +.cm-s-mdn-like .cm-tag { color: #997643; } +.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/ +.cm-s-mdn-like .cm-header { color: #FF6400; } +.cm-s-mdn-like .cm-hr { color: #AEAEAE; } +.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } +.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; } + +div.cm-s-mdn-like .CodeMirror-activeline-background { background: #efefff; } +div.cm-s-mdn-like span.CodeMirror-matchingbracket { outline:1px solid grey; color: inherit; } + +.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,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); } diff --git a/shared/codemirror/theme/midnight.css b/shared/codemirror/theme/midnight.css index e41f105..77fa82a 100644 --- a/shared/codemirror/theme/midnight.css +++ b/shared/codemirror/theme/midnight.css @@ -1,45 +1,45 @@ -/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */ - -/**/ -.cm-s-midnight span.CodeMirror-matchhighlight { background: #494949; } -.cm-s-midnight.CodeMirror-focused span.CodeMirror-matchhighlight { background: #314D67 !important; } - -/**/ -.cm-s-midnight .CodeMirror-activeline-background { background: #253540; } - -.cm-s-midnight.CodeMirror { - background: #0F192A; - color: #D1EDFF; -} - -.cm-s-midnight.CodeMirror { border-top: 1px solid black; border-bottom: 1px solid black; } - -.cm-s-midnight div.CodeMirror-selected { background: #314D67; } -.cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); } -.cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); } -.cm-s-midnight .CodeMirror-gutters { background: #0F192A; border-right: 1px solid; } -.cm-s-midnight .CodeMirror-guttermarker { color: white; } -.cm-s-midnight .CodeMirror-guttermarker-subtle { color: #d0d0d0; } -.cm-s-midnight .CodeMirror-linenumber { color: #D0D0D0; } -.cm-s-midnight .CodeMirror-cursor { border-left: 1px solid #F8F8F0; } - -.cm-s-midnight span.cm-comment { color: #428BDD; } -.cm-s-midnight span.cm-atom { color: #AE81FF; } -.cm-s-midnight span.cm-number { color: #D1EDFF; } - -.cm-s-midnight span.cm-property, .cm-s-midnight span.cm-attribute { color: #A6E22E; } -.cm-s-midnight span.cm-keyword { color: #E83737; } -.cm-s-midnight span.cm-string { color: #1DC116; } - -.cm-s-midnight span.cm-variable { color: #FFAA3E; } -.cm-s-midnight span.cm-variable-2 { color: #FFAA3E; } -.cm-s-midnight span.cm-def { color: #4DD; } -.cm-s-midnight span.cm-bracket { color: #D1EDFF; } -.cm-s-midnight span.cm-tag { color: #449; } -.cm-s-midnight span.cm-link { color: #AE81FF; } -.cm-s-midnight span.cm-error { background: #F92672; color: #F8F8F0; } - -.cm-s-midnight .CodeMirror-matchingbracket { - text-decoration: underline; - color: white !important; -} +/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */ + +/**/ +.cm-s-midnight span.CodeMirror-matchhighlight { background: #494949; } +.cm-s-midnight.CodeMirror-focused span.CodeMirror-matchhighlight { background: #314D67 !important; } + +/**/ +.cm-s-midnight .CodeMirror-activeline-background { background: #253540; } + +.cm-s-midnight.CodeMirror { + background: #0F192A; + color: #D1EDFF; +} + +.cm-s-midnight.CodeMirror { border-top: 1px solid black; border-bottom: 1px solid black; } + +.cm-s-midnight div.CodeMirror-selected { background: #314D67; } +.cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); } +.cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); } +.cm-s-midnight .CodeMirror-gutters { background: #0F192A; border-right: 1px solid; } +.cm-s-midnight .CodeMirror-guttermarker { color: white; } +.cm-s-midnight .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-midnight .CodeMirror-linenumber { color: #D0D0D0; } +.cm-s-midnight .CodeMirror-cursor { border-left: 1px solid #F8F8F0; } + +.cm-s-midnight span.cm-comment { color: #428BDD; } +.cm-s-midnight span.cm-atom { color: #AE81FF; } +.cm-s-midnight span.cm-number { color: #D1EDFF; } + +.cm-s-midnight span.cm-property, .cm-s-midnight span.cm-attribute { color: #A6E22E; } +.cm-s-midnight span.cm-keyword { color: #E83737; } +.cm-s-midnight span.cm-string { color: #1DC116; } + +.cm-s-midnight span.cm-variable { color: #FFAA3E; } +.cm-s-midnight span.cm-variable-2 { color: #FFAA3E; } +.cm-s-midnight span.cm-def { color: #4DD; } +.cm-s-midnight span.cm-bracket { color: #D1EDFF; } +.cm-s-midnight span.cm-tag { color: #449; } +.cm-s-midnight span.cm-link { color: #AE81FF; } +.cm-s-midnight span.cm-error { background: #F92672; color: #F8F8F0; } + +.cm-s-midnight .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/shared/codemirror/theme/monokai.css b/shared/codemirror/theme/monokai.css index 7c8a4c5..75cc321 100644 --- a/shared/codemirror/theme/monokai.css +++ b/shared/codemirror/theme/monokai.css @@ -1,36 +1,36 @@ -/* Based on Sublime Text's Monokai theme */ - -.cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } -.cm-s-monokai div.CodeMirror-selected { background: #49483E; } -.cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } -.cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } -.cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } -.cm-s-monokai .CodeMirror-guttermarker { color: white; } -.cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } -.cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; } -.cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } - -.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-builtin { color: #66d9ef; } -.cm-s-monokai span.cm-string { color: #e6db74; } - -.cm-s-monokai span.cm-variable { color: #f8f8f2; } -.cm-s-monokai span.cm-variable-2 { color: #9effff; } -.cm-s-monokai span.cm-variable-3 { color: #66d9ef; } -.cm-s-monokai span.cm-def { color: #fd971f; } -.cm-s-monokai span.cm-bracket { color: #f8f8f2; } -.cm-s-monokai span.cm-tag { color: #f92672; } -.cm-s-monokai span.cm-header { color: #ae81ff; } -.cm-s-monokai span.cm-link { color: #ae81ff; } -.cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } - -.cm-s-monokai .CodeMirror-activeline-background { background: #373831; } -.cm-s-monokai .CodeMirror-matchingbracket { - text-decoration: underline; - color: white !important; -} +/* Based on Sublime Text's Monokai theme */ + +.cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } +.cm-s-monokai div.CodeMirror-selected { background: #49483E; } +.cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } +.cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } +.cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } +.cm-s-monokai .CodeMirror-guttermarker { color: white; } +.cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } + +.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-builtin { color: #66d9ef; } +.cm-s-monokai span.cm-string { color: #e6db74; } + +.cm-s-monokai span.cm-variable { color: #f8f8f2; } +.cm-s-monokai span.cm-variable-2 { color: #9effff; } +.cm-s-monokai span.cm-variable-3 { color: #66d9ef; } +.cm-s-monokai span.cm-def { color: #fd971f; } +.cm-s-monokai span.cm-bracket { color: #f8f8f2; } +.cm-s-monokai span.cm-tag { color: #f92672; } +.cm-s-monokai span.cm-header { color: #ae81ff; } +.cm-s-monokai span.cm-link { color: #ae81ff; } +.cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } + +.cm-s-monokai .CodeMirror-activeline-background { background: #373831; } +.cm-s-monokai .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/shared/codemirror/theme/neat.css b/shared/codemirror/theme/neat.css index 4267b1a..d454fbb 100644 --- a/shared/codemirror/theme/neat.css +++ b/shared/codemirror/theme/neat.css @@ -1,12 +1,12 @@ -.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; } - -.cm-s-neat .CodeMirror-activeline-background { background: #e8f2ff; } -.cm-s-neat .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } +.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; } + +.cm-s-neat .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-neat .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; } diff --git a/shared/codemirror/theme/neo.css b/shared/codemirror/theme/neo.css index b28d5c6..42a0a49 100644 --- a/shared/codemirror/theme/neo.css +++ b/shared/codemirror/theme/neo.css @@ -1,43 +1,43 @@ -/* neo theme for codemirror */ - -/* Color scheme */ - -.cm-s-neo.CodeMirror { - background-color:#ffffff; - color:#2e383c; - line-height:1.4375; -} -.cm-s-neo .cm-comment { color:#75787b; } -.cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; } -.cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; } -.cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; } -.cm-s-neo .cm-string { color:#b35e14; } -.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; } - - -/* Editor styling */ - -.cm-s-neo pre { - padding:0; -} - -.cm-s-neo .CodeMirror-gutters { - border:none; - border-right:10px solid transparent; - background-color:transparent; -} - -.cm-s-neo .CodeMirror-linenumber { - padding:0; - color:#e0e2e5; -} - -.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; } -.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; } - -.cm-s-neo .CodeMirror-cursor { - width: auto; - border: 0; - background: rgba(155,157,162,0.37); - z-index: 1; -} +/* neo theme for codemirror */ + +/* Color scheme */ + +.cm-s-neo.CodeMirror { + background-color:#ffffff; + color:#2e383c; + line-height:1.4375; +} +.cm-s-neo .cm-comment { color:#75787b; } +.cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; } +.cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; } +.cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; } +.cm-s-neo .cm-string { color:#b35e14; } +.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; } + + +/* Editor styling */ + +.cm-s-neo pre { + padding:0; +} + +.cm-s-neo .CodeMirror-gutters { + border:none; + border-right:10px solid transparent; + background-color:transparent; +} + +.cm-s-neo .CodeMirror-linenumber { + padding:0; + color:#e0e2e5; +} + +.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; } +.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; } + +.cm-s-neo .CodeMirror-cursor { + width: auto; + border: 0; + background: rgba(155,157,162,0.37); + z-index: 1; +} diff --git a/shared/codemirror/theme/night.css b/shared/codemirror/theme/night.css index fd4e561..6ffa4d8 100644 --- a/shared/codemirror/theme/night.css +++ b/shared/codemirror/theme/night.css @@ -1,27 +1,27 @@ -/* Loosely based on the Midnight Textmate theme */ - -.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; } -.cm-s-night div.CodeMirror-selected { background: #447; } -.cm-s-night .CodeMirror-line::selection, .cm-s-night .CodeMirror-line > span::selection, .cm-s-night .CodeMirror-line > span > span::selection { background: rgba(68, 68, 119, .99); } -.cm-s-night .CodeMirror-line::-moz-selection, .cm-s-night .CodeMirror-line > span::-moz-selection, .cm-s-night .CodeMirror-line > span > span::-moz-selection { background: rgba(68, 68, 119, .99); } -.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } -.cm-s-night .CodeMirror-guttermarker { color: white; } -.cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; } -.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; } -.cm-s-night .CodeMirror-cursor { border-left: 1px solid white; } - -.cm-s-night span.cm-comment { color: #8900d1; } -.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-bracket { color: #8da6ce; } -.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; } -.cm-s-night span.cm-link { color: #845dc4; } -.cm-s-night span.cm-error { color: #9d1e15; } - -.cm-s-night .CodeMirror-activeline-background { background: #1C005A; } -.cm-s-night .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } +/* Loosely based on the Midnight Textmate theme */ + +.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; } +.cm-s-night div.CodeMirror-selected { background: #447; } +.cm-s-night .CodeMirror-line::selection, .cm-s-night .CodeMirror-line > span::selection, .cm-s-night .CodeMirror-line > span > span::selection { background: rgba(68, 68, 119, .99); } +.cm-s-night .CodeMirror-line::-moz-selection, .cm-s-night .CodeMirror-line > span::-moz-selection, .cm-s-night .CodeMirror-line > span > span::-moz-selection { background: rgba(68, 68, 119, .99); } +.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } +.cm-s-night .CodeMirror-guttermarker { color: white; } +.cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; } +.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; } +.cm-s-night .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-night span.cm-comment { color: #8900d1; } +.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-bracket { color: #8da6ce; } +.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; } +.cm-s-night span.cm-link { color: #845dc4; } +.cm-s-night span.cm-error { color: #9d1e15; } + +.cm-s-night .CodeMirror-activeline-background { background: #1C005A; } +.cm-s-night .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/shared/codemirror/theme/paraiso-dark.css b/shared/codemirror/theme/paraiso-dark.css index aa9d207..25eb926 100644 --- a/shared/codemirror/theme/paraiso-dark.css +++ b/shared/codemirror/theme/paraiso-dark.css @@ -1,38 +1,38 @@ -/* - - Name: Paraíso (Dark) - Author: Jan T. Sott - - Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror) - Inspired by the art of Rubens LP (http://www.rubenslp.com.br) - -*/ - -.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; } -.cm-s-paraiso-dark div.CodeMirror-selected { background: #41323f; } -.cm-s-paraiso-dark .CodeMirror-line::selection, .cm-s-paraiso-dark .CodeMirror-line > span::selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::selection { background: rgba(65, 50, 63, .99); } -.cm-s-paraiso-dark .CodeMirror-line::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(65, 50, 63, .99); } -.cm-s-paraiso-dark .CodeMirror-gutters { background: #2f1e2e; border-right: 0px; } -.cm-s-paraiso-dark .CodeMirror-guttermarker { color: #ef6155; } -.cm-s-paraiso-dark .CodeMirror-guttermarker-subtle { color: #776e71; } -.cm-s-paraiso-dark .CodeMirror-linenumber { color: #776e71; } -.cm-s-paraiso-dark .CodeMirror-cursor { border-left: 1px solid #8d8687; } - -.cm-s-paraiso-dark span.cm-comment { color: #e96ba8; } -.cm-s-paraiso-dark span.cm-atom { color: #815ba4; } -.cm-s-paraiso-dark span.cm-number { color: #815ba4; } - -.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute { color: #48b685; } -.cm-s-paraiso-dark span.cm-keyword { color: #ef6155; } -.cm-s-paraiso-dark span.cm-string { color: #fec418; } - -.cm-s-paraiso-dark span.cm-variable { color: #48b685; } -.cm-s-paraiso-dark span.cm-variable-2 { color: #06b6ef; } -.cm-s-paraiso-dark span.cm-def { color: #f99b15; } -.cm-s-paraiso-dark span.cm-bracket { color: #b9b6b0; } -.cm-s-paraiso-dark span.cm-tag { color: #ef6155; } -.cm-s-paraiso-dark span.cm-link { color: #815ba4; } -.cm-s-paraiso-dark span.cm-error { background: #ef6155; color: #8d8687; } - -.cm-s-paraiso-dark .CodeMirror-activeline-background { background: #4D344A; } -.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: Paraíso (Dark) + Author: Jan T. Sott + + Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror) + Inspired by the art of Rubens LP (http://www.rubenslp.com.br) + +*/ + +.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; } +.cm-s-paraiso-dark div.CodeMirror-selected { background: #41323f; } +.cm-s-paraiso-dark .CodeMirror-line::selection, .cm-s-paraiso-dark .CodeMirror-line > span::selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::selection { background: rgba(65, 50, 63, .99); } +.cm-s-paraiso-dark .CodeMirror-line::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(65, 50, 63, .99); } +.cm-s-paraiso-dark .CodeMirror-gutters { background: #2f1e2e; border-right: 0px; } +.cm-s-paraiso-dark .CodeMirror-guttermarker { color: #ef6155; } +.cm-s-paraiso-dark .CodeMirror-guttermarker-subtle { color: #776e71; } +.cm-s-paraiso-dark .CodeMirror-linenumber { color: #776e71; } +.cm-s-paraiso-dark .CodeMirror-cursor { border-left: 1px solid #8d8687; } + +.cm-s-paraiso-dark span.cm-comment { color: #e96ba8; } +.cm-s-paraiso-dark span.cm-atom { color: #815ba4; } +.cm-s-paraiso-dark span.cm-number { color: #815ba4; } + +.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute { color: #48b685; } +.cm-s-paraiso-dark span.cm-keyword { color: #ef6155; } +.cm-s-paraiso-dark span.cm-string { color: #fec418; } + +.cm-s-paraiso-dark span.cm-variable { color: #48b685; } +.cm-s-paraiso-dark span.cm-variable-2 { color: #06b6ef; } +.cm-s-paraiso-dark span.cm-def { color: #f99b15; } +.cm-s-paraiso-dark span.cm-bracket { color: #b9b6b0; } +.cm-s-paraiso-dark span.cm-tag { color: #ef6155; } +.cm-s-paraiso-dark span.cm-link { color: #815ba4; } +.cm-s-paraiso-dark span.cm-error { background: #ef6155; color: #8d8687; } + +.cm-s-paraiso-dark .CodeMirror-activeline-background { background: #4D344A; } +.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/paraiso-light.css b/shared/codemirror/theme/paraiso-light.css index ae0c755..479792e 100644 --- a/shared/codemirror/theme/paraiso-light.css +++ b/shared/codemirror/theme/paraiso-light.css @@ -1,38 +1,38 @@ -/* - - Name: Paraíso (Light) - Author: Jan T. Sott - - Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror) - Inspired by the art of Rubens LP (http://www.rubenslp.com.br) - -*/ - -.cm-s-paraiso-light.CodeMirror { background: #e7e9db; color: #41323f; } -.cm-s-paraiso-light div.CodeMirror-selected { background: #b9b6b0; } -.cm-s-paraiso-light .CodeMirror-line::selection, .cm-s-paraiso-light .CodeMirror-line > span::selection, .cm-s-paraiso-light .CodeMirror-line > span > span::selection { background: #b9b6b0; } -.cm-s-paraiso-light .CodeMirror-line::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span > span::-moz-selection { background: #b9b6b0; } -.cm-s-paraiso-light .CodeMirror-gutters { background: #e7e9db; border-right: 0px; } -.cm-s-paraiso-light .CodeMirror-guttermarker { color: black; } -.cm-s-paraiso-light .CodeMirror-guttermarker-subtle { color: #8d8687; } -.cm-s-paraiso-light .CodeMirror-linenumber { color: #8d8687; } -.cm-s-paraiso-light .CodeMirror-cursor { border-left: 1px solid #776e71; } - -.cm-s-paraiso-light span.cm-comment { color: #e96ba8; } -.cm-s-paraiso-light span.cm-atom { color: #815ba4; } -.cm-s-paraiso-light span.cm-number { color: #815ba4; } - -.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute { color: #48b685; } -.cm-s-paraiso-light span.cm-keyword { color: #ef6155; } -.cm-s-paraiso-light span.cm-string { color: #fec418; } - -.cm-s-paraiso-light span.cm-variable { color: #48b685; } -.cm-s-paraiso-light span.cm-variable-2 { color: #06b6ef; } -.cm-s-paraiso-light span.cm-def { color: #f99b15; } -.cm-s-paraiso-light span.cm-bracket { color: #41323f; } -.cm-s-paraiso-light span.cm-tag { color: #ef6155; } -.cm-s-paraiso-light span.cm-link { color: #815ba4; } -.cm-s-paraiso-light span.cm-error { background: #ef6155; color: #776e71; } - -.cm-s-paraiso-light .CodeMirror-activeline-background { background: #CFD1C4; } -.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: Paraíso (Light) + Author: Jan T. Sott + + Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror) + Inspired by the art of Rubens LP (http://www.rubenslp.com.br) + +*/ + +.cm-s-paraiso-light.CodeMirror { background: #e7e9db; color: #41323f; } +.cm-s-paraiso-light div.CodeMirror-selected { background: #b9b6b0; } +.cm-s-paraiso-light .CodeMirror-line::selection, .cm-s-paraiso-light .CodeMirror-line > span::selection, .cm-s-paraiso-light .CodeMirror-line > span > span::selection { background: #b9b6b0; } +.cm-s-paraiso-light .CodeMirror-line::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span > span::-moz-selection { background: #b9b6b0; } +.cm-s-paraiso-light .CodeMirror-gutters { background: #e7e9db; border-right: 0px; } +.cm-s-paraiso-light .CodeMirror-guttermarker { color: black; } +.cm-s-paraiso-light .CodeMirror-guttermarker-subtle { color: #8d8687; } +.cm-s-paraiso-light .CodeMirror-linenumber { color: #8d8687; } +.cm-s-paraiso-light .CodeMirror-cursor { border-left: 1px solid #776e71; } + +.cm-s-paraiso-light span.cm-comment { color: #e96ba8; } +.cm-s-paraiso-light span.cm-atom { color: #815ba4; } +.cm-s-paraiso-light span.cm-number { color: #815ba4; } + +.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute { color: #48b685; } +.cm-s-paraiso-light span.cm-keyword { color: #ef6155; } +.cm-s-paraiso-light span.cm-string { color: #fec418; } + +.cm-s-paraiso-light span.cm-variable { color: #48b685; } +.cm-s-paraiso-light span.cm-variable-2 { color: #06b6ef; } +.cm-s-paraiso-light span.cm-def { color: #f99b15; } +.cm-s-paraiso-light span.cm-bracket { color: #41323f; } +.cm-s-paraiso-light span.cm-tag { color: #ef6155; } +.cm-s-paraiso-light span.cm-link { color: #815ba4; } +.cm-s-paraiso-light span.cm-error { background: #ef6155; color: #776e71; } + +.cm-s-paraiso-light .CodeMirror-activeline-background { background: #CFD1C4; } +.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/pastel-on-dark.css b/shared/codemirror/theme/pastel-on-dark.css index 7197509..c9d2bc0 100644 --- a/shared/codemirror/theme/pastel-on-dark.css +++ b/shared/codemirror/theme/pastel-on-dark.css @@ -1,53 +1,53 @@ -/** - * Pastel On Dark theme ported from ACE editor - * @license MIT - * @copyright AtomicPages LLC 2014 - * @author Dennis Thompson, AtomicPages LLC - * @version 1.1 - * @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme - */ - -.cm-s-pastel-on-dark.CodeMirror { - background: #2c2827; - color: #8F938F; - line-height: 1.5; - font-size: 14px; -} -.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); } -.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); } -.cm-s-pastel-on-dark .CodeMirror-line::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(221,240,255,0.2); } - -.cm-s-pastel-on-dark .CodeMirror-gutters { - background: #34302f; - border-right: 0px; - padding: 0 3px; -} -.cm-s-pastel-on-dark .CodeMirror-guttermarker { color: white; } -.cm-s-pastel-on-dark .CodeMirror-guttermarker-subtle { color: #8F938F; } -.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; } -.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7; } -.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; } -.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; } -.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; } -.cm-s-pastel-on-dark span.cm-property { color: #8F938F; } -.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; } -.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; } -.cm-s-pastel-on-dark span.cm-string { color: #66A968; } -.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; } -.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; } -.cm-s-pastel-on-dark span.cm-variable-3 { color: #DE8E30; } -.cm-s-pastel-on-dark span.cm-def { color: #757aD8; } -.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; } -.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; } -.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; } -.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; } -.cm-s-pastel-on-dark span.cm-error { - background: #757aD8; - color: #f8f8f0; -} -.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031); } -.cm-s-pastel-on-dark .CodeMirror-matchingbracket { - border: 1px solid rgba(255,255,255,0.25); - color: #8F938F !important; - margin: -1px -1px 0 -1px; -} +/** + * Pastel On Dark theme ported from ACE editor + * @license MIT + * @copyright AtomicPages LLC 2014 + * @author Dennis Thompson, AtomicPages LLC + * @version 1.1 + * @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme + */ + +.cm-s-pastel-on-dark.CodeMirror { + background: #2c2827; + color: #8F938F; + line-height: 1.5; + font-size: 14px; +} +.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); } +.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); } +.cm-s-pastel-on-dark .CodeMirror-line::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(221,240,255,0.2); } + +.cm-s-pastel-on-dark .CodeMirror-gutters { + background: #34302f; + border-right: 0px; + padding: 0 3px; +} +.cm-s-pastel-on-dark .CodeMirror-guttermarker { color: white; } +.cm-s-pastel-on-dark .CodeMirror-guttermarker-subtle { color: #8F938F; } +.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; } +.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7; } +.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; } +.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; } +.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; } +.cm-s-pastel-on-dark span.cm-property { color: #8F938F; } +.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; } +.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; } +.cm-s-pastel-on-dark span.cm-string { color: #66A968; } +.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; } +.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; } +.cm-s-pastel-on-dark span.cm-variable-3 { color: #DE8E30; } +.cm-s-pastel-on-dark span.cm-def { color: #757aD8; } +.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; } +.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; } +.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; } +.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; } +.cm-s-pastel-on-dark span.cm-error { + background: #757aD8; + color: #f8f8f0; +} +.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031); } +.cm-s-pastel-on-dark .CodeMirror-matchingbracket { + border: 1px solid rgba(255,255,255,0.25); + color: #8F938F !important; + margin: -1px -1px 0 -1px; +} diff --git a/shared/codemirror/theme/railscasts.css b/shared/codemirror/theme/railscasts.css index aeff044..2336e7c 100644 --- a/shared/codemirror/theme/railscasts.css +++ b/shared/codemirror/theme/railscasts.css @@ -1,34 +1,34 @@ -/* - - Name: Railscasts - Author: Ryan Bates (http://railscasts.com) - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;} -.cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;} -.cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;} -.cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;} -.cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;} - -.cm-s-railscasts span.cm-comment {color: #bc9458;} -.cm-s-railscasts span.cm-atom {color: #b6b3eb;} -.cm-s-railscasts span.cm-number {color: #b6b3eb;} - -.cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;} -.cm-s-railscasts span.cm-keyword {color: #da4939;} -.cm-s-railscasts span.cm-string {color: #ffc66d;} - -.cm-s-railscasts span.cm-variable {color: #a5c261;} -.cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;} -.cm-s-railscasts span.cm-def {color: #cc7833;} -.cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;} -.cm-s-railscasts span.cm-bracket {color: #f4f1ed;} -.cm-s-railscasts span.cm-tag {color: #da4939;} -.cm-s-railscasts span.cm-link {color: #b6b3eb;} - -.cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} -.cm-s-railscasts .CodeMirror-activeline-background { background: #303040; } +/* + + Name: Railscasts + Author: Ryan Bates (http://railscasts.com) + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;} +.cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;} +.cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;} +.cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;} +.cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;} + +.cm-s-railscasts span.cm-comment {color: #bc9458;} +.cm-s-railscasts span.cm-atom {color: #b6b3eb;} +.cm-s-railscasts span.cm-number {color: #b6b3eb;} + +.cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;} +.cm-s-railscasts span.cm-keyword {color: #da4939;} +.cm-s-railscasts span.cm-string {color: #ffc66d;} + +.cm-s-railscasts span.cm-variable {color: #a5c261;} +.cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;} +.cm-s-railscasts span.cm-def {color: #cc7833;} +.cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;} +.cm-s-railscasts span.cm-bracket {color: #f4f1ed;} +.cm-s-railscasts span.cm-tag {color: #da4939;} +.cm-s-railscasts span.cm-link {color: #b6b3eb;} + +.cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;} +.cm-s-railscasts .CodeMirror-activeline-background { background: #303040; } diff --git a/shared/codemirror/theme/rubyblue.css b/shared/codemirror/theme/rubyblue.css index 76d33e7..5d3024a 100644 --- a/shared/codemirror/theme/rubyblue.css +++ b/shared/codemirror/theme/rubyblue.css @@ -1,25 +1,25 @@ -.cm-s-rubyblue.CodeMirror { background: #112435; color: white; } -.cm-s-rubyblue div.CodeMirror-selected { background: #38566F; } -.cm-s-rubyblue .CodeMirror-line::selection, .cm-s-rubyblue .CodeMirror-line > span::selection, .cm-s-rubyblue .CodeMirror-line > span > span::selection { background: rgba(56, 86, 111, 0.99); } -.cm-s-rubyblue .CodeMirror-line::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 86, 111, 0.99); } -.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; } -.cm-s-rubyblue .CodeMirror-guttermarker { color: white; } -.cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; } -.cm-s-rubyblue .CodeMirror-linenumber { color: white; } -.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white; } - -.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-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; } -.cm-s-rubyblue span.cm-error { color: #AF2018; } - -.cm-s-rubyblue .CodeMirror-activeline-background { background: #173047; } +.cm-s-rubyblue.CodeMirror { background: #112435; color: white; } +.cm-s-rubyblue div.CodeMirror-selected { background: #38566F; } +.cm-s-rubyblue .CodeMirror-line::selection, .cm-s-rubyblue .CodeMirror-line > span::selection, .cm-s-rubyblue .CodeMirror-line > span > span::selection { background: rgba(56, 86, 111, 0.99); } +.cm-s-rubyblue .CodeMirror-line::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 86, 111, 0.99); } +.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; } +.cm-s-rubyblue .CodeMirror-guttermarker { color: white; } +.cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; } +.cm-s-rubyblue .CodeMirror-linenumber { color: white; } +.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white; } + +.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-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; } +.cm-s-rubyblue span.cm-error { color: #AF2018; } + +.cm-s-rubyblue .CodeMirror-activeline-background { background: #173047; } diff --git a/shared/codemirror/theme/seti.css b/shared/codemirror/theme/seti.css index 6632d3f..7848649 100644 --- a/shared/codemirror/theme/seti.css +++ b/shared/codemirror/theme/seti.css @@ -1,44 +1,44 @@ -/* - - Name: seti - Author: Michael Kaminsky (http://github.com/mkaminsky11) - - Original seti color scheme by Jesse Weed (https://github.com/jesseweed/seti-syntax) - -*/ - - -.cm-s-seti.CodeMirror { - background-color: #151718 !important; - color: #CFD2D1 !important; - border: none; -} -.cm-s-seti .CodeMirror-gutters { - color: #404b53; - background-color: #0E1112; - border: none; -} -.cm-s-seti .CodeMirror-cursor { border-left: solid thin #f8f8f0; } -.cm-s-seti .CodeMirror-linenumber { color: #6D8A88; } -.cm-s-seti.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } -.cm-s-seti .CodeMirror-line::selection, .cm-s-seti .CodeMirror-line > span::selection, .cm-s-seti .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } -.cm-s-seti .CodeMirror-line::-moz-selection, .cm-s-seti .CodeMirror-line > span::-moz-selection, .cm-s-seti .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } -.cm-s-seti span.cm-comment { color: #41535b; } -.cm-s-seti span.cm-string, .cm-s-seti span.cm-string-2 { color: #55b5db; } -.cm-s-seti span.cm-number { color: #cd3f45; } -.cm-s-seti span.cm-variable { color: #55b5db; } -.cm-s-seti span.cm-variable-2 { color: #a074c4; } -.cm-s-seti span.cm-def { color: #55b5db; } -.cm-s-seti span.cm-keyword { color: #ff79c6; } -.cm-s-seti span.cm-operator { color: #9fca56; } -.cm-s-seti span.cm-keyword { color: #e6cd69; } -.cm-s-seti span.cm-atom { color: #cd3f45; } -.cm-s-seti span.cm-meta { color: #55b5db; } -.cm-s-seti span.cm-tag { color: #55b5db; } -.cm-s-seti span.cm-attribute { color: #9fca56; } -.cm-s-seti span.cm-qualifier { color: #9fca56; } -.cm-s-seti span.cm-property { color: #a074c4; } -.cm-s-seti span.cm-variable-3 { color: #9fca56; } -.cm-s-seti span.cm-builtin { color: #9fca56; } -.cm-s-seti .CodeMirror-activeline-background { background: #101213; } -.cm-s-seti .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: seti + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original seti color scheme by Jesse Weed (https://github.com/jesseweed/seti-syntax) + +*/ + + +.cm-s-seti.CodeMirror { + background-color: #151718 !important; + color: #CFD2D1 !important; + border: none; +} +.cm-s-seti .CodeMirror-gutters { + color: #404b53; + background-color: #0E1112; + border: none; +} +.cm-s-seti .CodeMirror-cursor { border-left: solid thin #f8f8f0; } +.cm-s-seti .CodeMirror-linenumber { color: #6D8A88; } +.cm-s-seti.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); } +.cm-s-seti .CodeMirror-line::selection, .cm-s-seti .CodeMirror-line > span::selection, .cm-s-seti .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-seti .CodeMirror-line::-moz-selection, .cm-s-seti .CodeMirror-line > span::-moz-selection, .cm-s-seti .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); } +.cm-s-seti span.cm-comment { color: #41535b; } +.cm-s-seti span.cm-string, .cm-s-seti span.cm-string-2 { color: #55b5db; } +.cm-s-seti span.cm-number { color: #cd3f45; } +.cm-s-seti span.cm-variable { color: #55b5db; } +.cm-s-seti span.cm-variable-2 { color: #a074c4; } +.cm-s-seti span.cm-def { color: #55b5db; } +.cm-s-seti span.cm-keyword { color: #ff79c6; } +.cm-s-seti span.cm-operator { color: #9fca56; } +.cm-s-seti span.cm-keyword { color: #e6cd69; } +.cm-s-seti span.cm-atom { color: #cd3f45; } +.cm-s-seti span.cm-meta { color: #55b5db; } +.cm-s-seti span.cm-tag { color: #55b5db; } +.cm-s-seti span.cm-attribute { color: #9fca56; } +.cm-s-seti span.cm-qualifier { color: #9fca56; } +.cm-s-seti span.cm-property { color: #a074c4; } +.cm-s-seti span.cm-variable-3 { color: #9fca56; } +.cm-s-seti span.cm-builtin { color: #9fca56; } +.cm-s-seti .CodeMirror-activeline-background { background: #101213; } +.cm-s-seti .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/solarized.css b/shared/codemirror/theme/solarized.css index 7882c93..0a4f98b 100644 --- a/shared/codemirror/theme/solarized.css +++ b/shared/codemirror/theme/solarized.css @@ -1,163 +1,163 @@ -/* -Solarized theme for code-mirror -http://ethanschoonover.com/solarized -*/ - -/* -Solarized color pallet -http://ethanschoonover.com/solarized/img/solarized-palette.png -*/ - -.solarized.base03 { color: #002b36; } -.solarized.base02 { color: #073642; } -.solarized.base01 { color: #586e75; } -.solarized.base00 { color: #657b83; } -.solarized.base0 { color: #839496; } -.solarized.base1 { color: #93a1a1; } -.solarized.base2 { color: #eee8d5; } -.solarized.base3 { color: #fdf6e3; } -.solarized.solar-yellow { color: #b58900; } -.solarized.solar-orange { color: #cb4b16; } -.solarized.solar-red { color: #dc322f; } -.solarized.solar-magenta { color: #d33682; } -.solarized.solar-violet { color: #6c71c4; } -.solarized.solar-blue { color: #268bd2; } -.solarized.solar-cyan { color: #2aa198; } -.solarized.solar-green { color: #859900; } - -/* Color scheme for code-mirror */ - -.cm-s-solarized { - line-height: 1.45em; - color-profile: sRGB; - rendering-intent: auto; -} -.cm-s-solarized.cm-s-dark { - color: #839496; - background-color: #002b36; - text-shadow: #002b36 0 1px; -} -.cm-s-solarized.cm-s-light { - background-color: #fdf6e3; - color: #657b83; - text-shadow: #eee8d5 0 1px; -} - -.cm-s-solarized .CodeMirror-widget { - text-shadow: none; -} - -.cm-s-solarized .cm-header { color: #586e75; } -.cm-s-solarized .cm-quote { color: #93a1a1; } - -.cm-s-solarized .cm-keyword { color: #cb4b16; } -.cm-s-solarized .cm-atom { color: #d33682; } -.cm-s-solarized .cm-number { color: #d33682; } -.cm-s-solarized .cm-def { color: #2aa198; } - -.cm-s-solarized .cm-variable { color: #839496; } -.cm-s-solarized .cm-variable-2 { color: #b58900; } -.cm-s-solarized .cm-variable-3 { color: #6c71c4; } - -.cm-s-solarized .cm-property { color: #2aa198; } -.cm-s-solarized .cm-operator { color: #6c71c4; } - -.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; } - -.cm-s-solarized .cm-string { color: #859900; } -.cm-s-solarized .cm-string-2 { color: #b58900; } - -.cm-s-solarized .cm-meta { color: #859900; } -.cm-s-solarized .cm-qualifier { color: #b58900; } -.cm-s-solarized .cm-builtin { color: #d33682; } -.cm-s-solarized .cm-bracket { color: #cb4b16; } -.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; } -.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; } -.cm-s-solarized .cm-tag { color: #93a1a1; } -.cm-s-solarized .cm-attribute { color: #2aa198; } -.cm-s-solarized .cm-hr { - color: transparent; - border-top: 1px solid #586e75; - display: block; -} -.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; } -.cm-s-solarized .cm-special { color: #6c71c4; } -.cm-s-solarized .cm-em { - color: #999; - text-decoration: underline; - text-decoration-style: dotted; -} -.cm-s-solarized .cm-strong { color: #eee; } -.cm-s-solarized .cm-error, -.cm-s-solarized .cm-invalidchar { - color: #586e75; - border-bottom: 1px dotted #dc322f; -} - -.cm-s-solarized.cm-s-dark div.CodeMirror-selected { background: #073642; } -.cm-s-solarized.cm-s-dark.CodeMirror ::selection { background: rgba(7, 54, 66, 0.99); } -.cm-s-solarized.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(7, 54, 66, 0.99); } - -.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; } -.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; } -.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-ligh .CodeMirror-line > span::-moz-selection, .cm-s-ligh .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; } - -/* Editor styling */ - - - -/* Little shadow on the view-port of the buffer view */ -.cm-s-solarized.CodeMirror { - -moz-box-shadow: inset 7px 0 12px -6px #000; - -webkit-box-shadow: inset 7px 0 12px -6px #000; - box-shadow: inset 7px 0 12px -6px #000; -} - -/* Gutter border and some shadow from it */ -.cm-s-solarized .CodeMirror-gutters { - border-right: 1px solid; -} - -/* Gutter colors and line number styling based of color scheme (dark / light) */ - -/* Dark */ -.cm-s-solarized.cm-s-dark .CodeMirror-gutters { - background-color: #002b36; - border-color: #00232c; -} - -.cm-s-solarized.cm-s-dark .CodeMirror-linenumber { - text-shadow: #021014 0 -1px; -} - -/* Light */ -.cm-s-solarized.cm-s-light .CodeMirror-gutters { - background-color: #fdf6e3; - border-color: #eee8d5; -} - -/* Common */ -.cm-s-solarized .CodeMirror-linenumber { - color: #586e75; - padding: 0 5px; -} -.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; } -.cm-s-solarized.cm-s-dark .CodeMirror-guttermarker { color: #ddd; } -.cm-s-solarized.cm-s-light .CodeMirror-guttermarker { color: #cb4b16; } - -.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text { - color: #586e75; -} - -.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; } - -/* -Active line. Negative margin compensates left padding of the text in the -view-port -*/ -.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background { - background: rgba(255, 255, 255, 0.10); -} -.cm-s-solarized.cm-s-light .CodeMirror-activeline-background { - background: rgba(0, 0, 0, 0.10); -} +/* +Solarized theme for code-mirror +http://ethanschoonover.com/solarized +*/ + +/* +Solarized color pallet +http://ethanschoonover.com/solarized/img/solarized-palette.png +*/ + +.solarized.base03 { color: #002b36; } +.solarized.base02 { color: #073642; } +.solarized.base01 { color: #586e75; } +.solarized.base00 { color: #657b83; } +.solarized.base0 { color: #839496; } +.solarized.base1 { color: #93a1a1; } +.solarized.base2 { color: #eee8d5; } +.solarized.base3 { color: #fdf6e3; } +.solarized.solar-yellow { color: #b58900; } +.solarized.solar-orange { color: #cb4b16; } +.solarized.solar-red { color: #dc322f; } +.solarized.solar-magenta { color: #d33682; } +.solarized.solar-violet { color: #6c71c4; } +.solarized.solar-blue { color: #268bd2; } +.solarized.solar-cyan { color: #2aa198; } +.solarized.solar-green { color: #859900; } + +/* Color scheme for code-mirror */ + +.cm-s-solarized { + line-height: 1.45em; + color-profile: sRGB; + rendering-intent: auto; +} +.cm-s-solarized.cm-s-dark { + color: #839496; + background-color: #002b36; + text-shadow: #002b36 0 1px; +} +.cm-s-solarized.cm-s-light { + background-color: #fdf6e3; + color: #657b83; + text-shadow: #eee8d5 0 1px; +} + +.cm-s-solarized .CodeMirror-widget { + text-shadow: none; +} + +.cm-s-solarized .cm-header { color: #586e75; } +.cm-s-solarized .cm-quote { color: #93a1a1; } + +.cm-s-solarized .cm-keyword { color: #cb4b16; } +.cm-s-solarized .cm-atom { color: #d33682; } +.cm-s-solarized .cm-number { color: #d33682; } +.cm-s-solarized .cm-def { color: #2aa198; } + +.cm-s-solarized .cm-variable { color: #839496; } +.cm-s-solarized .cm-variable-2 { color: #b58900; } +.cm-s-solarized .cm-variable-3 { color: #6c71c4; } + +.cm-s-solarized .cm-property { color: #2aa198; } +.cm-s-solarized .cm-operator { color: #6c71c4; } + +.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; } + +.cm-s-solarized .cm-string { color: #859900; } +.cm-s-solarized .cm-string-2 { color: #b58900; } + +.cm-s-solarized .cm-meta { color: #859900; } +.cm-s-solarized .cm-qualifier { color: #b58900; } +.cm-s-solarized .cm-builtin { color: #d33682; } +.cm-s-solarized .cm-bracket { color: #cb4b16; } +.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; } +.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; } +.cm-s-solarized .cm-tag { color: #93a1a1; } +.cm-s-solarized .cm-attribute { color: #2aa198; } +.cm-s-solarized .cm-hr { + color: transparent; + border-top: 1px solid #586e75; + display: block; +} +.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; } +.cm-s-solarized .cm-special { color: #6c71c4; } +.cm-s-solarized .cm-em { + color: #999; + text-decoration: underline; + text-decoration-style: dotted; +} +.cm-s-solarized .cm-strong { color: #eee; } +.cm-s-solarized .cm-error, +.cm-s-solarized .cm-invalidchar { + color: #586e75; + border-bottom: 1px dotted #dc322f; +} + +.cm-s-solarized.cm-s-dark div.CodeMirror-selected { background: #073642; } +.cm-s-solarized.cm-s-dark.CodeMirror ::selection { background: rgba(7, 54, 66, 0.99); } +.cm-s-solarized.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(7, 54, 66, 0.99); } + +.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; } +.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; } +.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-ligh .CodeMirror-line > span::-moz-selection, .cm-s-ligh .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; } + +/* Editor styling */ + + + +/* Little shadow on the view-port of the buffer view */ +.cm-s-solarized.CodeMirror { + -moz-box-shadow: inset 7px 0 12px -6px #000; + -webkit-box-shadow: inset 7px 0 12px -6px #000; + box-shadow: inset 7px 0 12px -6px #000; +} + +/* Gutter border and some shadow from it */ +.cm-s-solarized .CodeMirror-gutters { + border-right: 1px solid; +} + +/* Gutter colors and line number styling based of color scheme (dark / light) */ + +/* Dark */ +.cm-s-solarized.cm-s-dark .CodeMirror-gutters { + background-color: #002b36; + border-color: #00232c; +} + +.cm-s-solarized.cm-s-dark .CodeMirror-linenumber { + text-shadow: #021014 0 -1px; +} + +/* Light */ +.cm-s-solarized.cm-s-light .CodeMirror-gutters { + background-color: #fdf6e3; + border-color: #eee8d5; +} + +/* Common */ +.cm-s-solarized .CodeMirror-linenumber { + color: #586e75; + padding: 0 5px; +} +.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; } +.cm-s-solarized.cm-s-dark .CodeMirror-guttermarker { color: #ddd; } +.cm-s-solarized.cm-s-light .CodeMirror-guttermarker { color: #cb4b16; } + +.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text { + color: #586e75; +} + +.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; } + +/* +Active line. Negative margin compensates left padding of the text in the +view-port +*/ +.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background { + background: rgba(255, 255, 255, 0.10); +} +.cm-s-solarized.cm-s-light .CodeMirror-activeline-background { + background: rgba(0, 0, 0, 0.10); +} diff --git a/shared/codemirror/theme/the-matrix.css b/shared/codemirror/theme/the-matrix.css index 3912a8d..14326c5 100644 --- a/shared/codemirror/theme/the-matrix.css +++ b/shared/codemirror/theme/the-matrix.css @@ -1,30 +1,30 @@ -.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; } -.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D; } -.cm-s-the-matrix .CodeMirror-line::selection, .cm-s-the-matrix .CodeMirror-line > span::selection, .cm-s-the-matrix .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); } -.cm-s-the-matrix .CodeMirror-line::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); } -.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; } -.cm-s-the-matrix .CodeMirror-guttermarker { color: #0f0; } -.cm-s-the-matrix .CodeMirror-guttermarker-subtle { color: white; } -.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; } -.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00; } - -.cm-s-the-matrix span.cm-keyword { color: #008803; font-weight: bold; } -.cm-s-the-matrix span.cm-atom { color: #3FF; } -.cm-s-the-matrix span.cm-number { color: #FFB94F; } -.cm-s-the-matrix span.cm-def { color: #99C; } -.cm-s-the-matrix span.cm-variable { color: #F6C; } -.cm-s-the-matrix span.cm-variable-2 { color: #C6F; } -.cm-s-the-matrix span.cm-variable-3 { color: #96F; } -.cm-s-the-matrix span.cm-property { color: #62FFA0; } -.cm-s-the-matrix span.cm-operator { color: #999; } -.cm-s-the-matrix span.cm-comment { color: #CCCCCC; } -.cm-s-the-matrix span.cm-string { color: #39C; } -.cm-s-the-matrix span.cm-meta { color: #C9F; } -.cm-s-the-matrix span.cm-qualifier { color: #FFF700; } -.cm-s-the-matrix span.cm-builtin { color: #30a; } -.cm-s-the-matrix span.cm-bracket { color: #cc7; } -.cm-s-the-matrix span.cm-tag { color: #FFBD40; } -.cm-s-the-matrix span.cm-attribute { color: #FFF700; } -.cm-s-the-matrix span.cm-error { color: #FF0000; } - -.cm-s-the-matrix .CodeMirror-activeline-background { background: #040; } +.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; } +.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D; } +.cm-s-the-matrix .CodeMirror-line::selection, .cm-s-the-matrix .CodeMirror-line > span::selection, .cm-s-the-matrix .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-the-matrix .CodeMirror-line::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; } +.cm-s-the-matrix .CodeMirror-guttermarker { color: #0f0; } +.cm-s-the-matrix .CodeMirror-guttermarker-subtle { color: white; } +.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; } +.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00; } + +.cm-s-the-matrix span.cm-keyword { color: #008803; font-weight: bold; } +.cm-s-the-matrix span.cm-atom { color: #3FF; } +.cm-s-the-matrix span.cm-number { color: #FFB94F; } +.cm-s-the-matrix span.cm-def { color: #99C; } +.cm-s-the-matrix span.cm-variable { color: #F6C; } +.cm-s-the-matrix span.cm-variable-2 { color: #C6F; } +.cm-s-the-matrix span.cm-variable-3 { color: #96F; } +.cm-s-the-matrix span.cm-property { color: #62FFA0; } +.cm-s-the-matrix span.cm-operator { color: #999; } +.cm-s-the-matrix span.cm-comment { color: #CCCCCC; } +.cm-s-the-matrix span.cm-string { color: #39C; } +.cm-s-the-matrix span.cm-meta { color: #C9F; } +.cm-s-the-matrix span.cm-qualifier { color: #FFF700; } +.cm-s-the-matrix span.cm-builtin { color: #30a; } +.cm-s-the-matrix span.cm-bracket { color: #cc7; } +.cm-s-the-matrix span.cm-tag { color: #FFBD40; } +.cm-s-the-matrix span.cm-attribute { color: #FFF700; } +.cm-s-the-matrix span.cm-error { color: #FF0000; } + +.cm-s-the-matrix .CodeMirror-activeline-background { background: #040; } diff --git a/shared/codemirror/theme/tomorrow-night-bright.css b/shared/codemirror/theme/tomorrow-night-bright.css index b6dd4a9..5d567c7 100644 --- a/shared/codemirror/theme/tomorrow-night-bright.css +++ b/shared/codemirror/theme/tomorrow-night-bright.css @@ -1,35 +1,35 @@ -/* - - Name: Tomorrow Night - Bright - Author: Chris Kempson - - Port done by Gerard Braad - -*/ - -.cm-s-tomorrow-night-bright.CodeMirror { background: #000000; color: #eaeaea; } -.cm-s-tomorrow-night-bright div.CodeMirror-selected { background: #424242; } -.cm-s-tomorrow-night-bright .CodeMirror-gutters { background: #000000; border-right: 0px; } -.cm-s-tomorrow-night-bright .CodeMirror-guttermarker { color: #e78c45; } -.cm-s-tomorrow-night-bright .CodeMirror-guttermarker-subtle { color: #777; } -.cm-s-tomorrow-night-bright .CodeMirror-linenumber { color: #424242; } -.cm-s-tomorrow-night-bright .CodeMirror-cursor { border-left: 1px solid #6A6A6A; } - -.cm-s-tomorrow-night-bright span.cm-comment { color: #d27b53; } -.cm-s-tomorrow-night-bright span.cm-atom { color: #a16a94; } -.cm-s-tomorrow-night-bright span.cm-number { color: #a16a94; } - -.cm-s-tomorrow-night-bright span.cm-property, .cm-s-tomorrow-night-bright span.cm-attribute { color: #99cc99; } -.cm-s-tomorrow-night-bright span.cm-keyword { color: #d54e53; } -.cm-s-tomorrow-night-bright span.cm-string { color: #e7c547; } - -.cm-s-tomorrow-night-bright span.cm-variable { color: #b9ca4a; } -.cm-s-tomorrow-night-bright span.cm-variable-2 { color: #7aa6da; } -.cm-s-tomorrow-night-bright span.cm-def { color: #e78c45; } -.cm-s-tomorrow-night-bright span.cm-bracket { color: #eaeaea; } -.cm-s-tomorrow-night-bright span.cm-tag { color: #d54e53; } -.cm-s-tomorrow-night-bright span.cm-link { color: #a16a94; } -.cm-s-tomorrow-night-bright span.cm-error { background: #d54e53; color: #6A6A6A; } - -.cm-s-tomorrow-night-bright .CodeMirror-activeline-background { background: #2a2a2a; } -.cm-s-tomorrow-night-bright .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: Tomorrow Night - Bright + Author: Chris Kempson + + Port done by Gerard Braad + +*/ + +.cm-s-tomorrow-night-bright.CodeMirror { background: #000000; color: #eaeaea; } +.cm-s-tomorrow-night-bright div.CodeMirror-selected { background: #424242; } +.cm-s-tomorrow-night-bright .CodeMirror-gutters { background: #000000; border-right: 0px; } +.cm-s-tomorrow-night-bright .CodeMirror-guttermarker { color: #e78c45; } +.cm-s-tomorrow-night-bright .CodeMirror-guttermarker-subtle { color: #777; } +.cm-s-tomorrow-night-bright .CodeMirror-linenumber { color: #424242; } +.cm-s-tomorrow-night-bright .CodeMirror-cursor { border-left: 1px solid #6A6A6A; } + +.cm-s-tomorrow-night-bright span.cm-comment { color: #d27b53; } +.cm-s-tomorrow-night-bright span.cm-atom { color: #a16a94; } +.cm-s-tomorrow-night-bright span.cm-number { color: #a16a94; } + +.cm-s-tomorrow-night-bright span.cm-property, .cm-s-tomorrow-night-bright span.cm-attribute { color: #99cc99; } +.cm-s-tomorrow-night-bright span.cm-keyword { color: #d54e53; } +.cm-s-tomorrow-night-bright span.cm-string { color: #e7c547; } + +.cm-s-tomorrow-night-bright span.cm-variable { color: #b9ca4a; } +.cm-s-tomorrow-night-bright span.cm-variable-2 { color: #7aa6da; } +.cm-s-tomorrow-night-bright span.cm-def { color: #e78c45; } +.cm-s-tomorrow-night-bright span.cm-bracket { color: #eaeaea; } +.cm-s-tomorrow-night-bright span.cm-tag { color: #d54e53; } +.cm-s-tomorrow-night-bright span.cm-link { color: #a16a94; } +.cm-s-tomorrow-night-bright span.cm-error { background: #d54e53; color: #6A6A6A; } + +.cm-s-tomorrow-night-bright .CodeMirror-activeline-background { background: #2a2a2a; } +.cm-s-tomorrow-night-bright .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/tomorrow-night-eighties.css b/shared/codemirror/theme/tomorrow-night-eighties.css index 2a9debc..0eef9fe 100644 --- a/shared/codemirror/theme/tomorrow-night-eighties.css +++ b/shared/codemirror/theme/tomorrow-night-eighties.css @@ -1,38 +1,38 @@ -/* - - Name: Tomorrow Night - Eighties - Author: Chris Kempson - - CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) - Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) - -*/ - -.cm-s-tomorrow-night-eighties.CodeMirror { background: #000000; color: #CCCCCC; } -.cm-s-tomorrow-night-eighties div.CodeMirror-selected { background: #2D2D2D; } -.cm-s-tomorrow-night-eighties .CodeMirror-line::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); } -.cm-s-tomorrow-night-eighties .CodeMirror-line::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); } -.cm-s-tomorrow-night-eighties .CodeMirror-gutters { background: #000000; border-right: 0px; } -.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker { color: #f2777a; } -.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker-subtle { color: #777; } -.cm-s-tomorrow-night-eighties .CodeMirror-linenumber { color: #515151; } -.cm-s-tomorrow-night-eighties .CodeMirror-cursor { border-left: 1px solid #6A6A6A; } - -.cm-s-tomorrow-night-eighties span.cm-comment { color: #d27b53; } -.cm-s-tomorrow-night-eighties span.cm-atom { color: #a16a94; } -.cm-s-tomorrow-night-eighties span.cm-number { color: #a16a94; } - -.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute { color: #99cc99; } -.cm-s-tomorrow-night-eighties span.cm-keyword { color: #f2777a; } -.cm-s-tomorrow-night-eighties span.cm-string { color: #ffcc66; } - -.cm-s-tomorrow-night-eighties span.cm-variable { color: #99cc99; } -.cm-s-tomorrow-night-eighties span.cm-variable-2 { color: #6699cc; } -.cm-s-tomorrow-night-eighties span.cm-def { color: #f99157; } -.cm-s-tomorrow-night-eighties span.cm-bracket { color: #CCCCCC; } -.cm-s-tomorrow-night-eighties span.cm-tag { color: #f2777a; } -.cm-s-tomorrow-night-eighties span.cm-link { color: #a16a94; } -.cm-s-tomorrow-night-eighties span.cm-error { background: #f2777a; color: #6A6A6A; } - -.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background { background: #343600; } -.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } +/* + + Name: Tomorrow Night - Eighties + Author: Chris Kempson + + CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) + Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) + +*/ + +.cm-s-tomorrow-night-eighties.CodeMirror { background: #000000; color: #CCCCCC; } +.cm-s-tomorrow-night-eighties div.CodeMirror-selected { background: #2D2D2D; } +.cm-s-tomorrow-night-eighties .CodeMirror-line::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-tomorrow-night-eighties .CodeMirror-line::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); } +.cm-s-tomorrow-night-eighties .CodeMirror-gutters { background: #000000; border-right: 0px; } +.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker { color: #f2777a; } +.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker-subtle { color: #777; } +.cm-s-tomorrow-night-eighties .CodeMirror-linenumber { color: #515151; } +.cm-s-tomorrow-night-eighties .CodeMirror-cursor { border-left: 1px solid #6A6A6A; } + +.cm-s-tomorrow-night-eighties span.cm-comment { color: #d27b53; } +.cm-s-tomorrow-night-eighties span.cm-atom { color: #a16a94; } +.cm-s-tomorrow-night-eighties span.cm-number { color: #a16a94; } + +.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute { color: #99cc99; } +.cm-s-tomorrow-night-eighties span.cm-keyword { color: #f2777a; } +.cm-s-tomorrow-night-eighties span.cm-string { color: #ffcc66; } + +.cm-s-tomorrow-night-eighties span.cm-variable { color: #99cc99; } +.cm-s-tomorrow-night-eighties span.cm-variable-2 { color: #6699cc; } +.cm-s-tomorrow-night-eighties span.cm-def { color: #f99157; } +.cm-s-tomorrow-night-eighties span.cm-bracket { color: #CCCCCC; } +.cm-s-tomorrow-night-eighties span.cm-tag { color: #f2777a; } +.cm-s-tomorrow-night-eighties span.cm-link { color: #a16a94; } +.cm-s-tomorrow-night-eighties span.cm-error { background: #f2777a; color: #6A6A6A; } + +.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background { background: #343600; } +.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; } diff --git a/shared/codemirror/theme/ttcn.css b/shared/codemirror/theme/ttcn.css index b3d4656..9401469 100644 --- a/shared/codemirror/theme/ttcn.css +++ b/shared/codemirror/theme/ttcn.css @@ -1,64 +1,64 @@ -.cm-s-ttcn .cm-quote { color: #090; } -.cm-s-ttcn .cm-negative { color: #d44; } -.cm-s-ttcn .cm-positive { color: #292; } -.cm-s-ttcn .cm-header, .cm-strong { font-weight: bold; } -.cm-s-ttcn .cm-em { font-style: italic; } -.cm-s-ttcn .cm-link { text-decoration: underline; } -.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; } -.cm-s-ttcn .cm-header { color: #00f; font-weight: bold; } - -.cm-s-ttcn .cm-atom { color: #219; } -.cm-s-ttcn .cm-attribute { color: #00c; } -.cm-s-ttcn .cm-bracket { color: #997; } -.cm-s-ttcn .cm-comment { color: #333333; } -.cm-s-ttcn .cm-def { color: #00f; } -.cm-s-ttcn .cm-em { font-style: italic; } -.cm-s-ttcn .cm-error { color: #f00; } -.cm-s-ttcn .cm-hr { color: #999; } -.cm-s-ttcn .cm-invalidchar { color: #f00; } -.cm-s-ttcn .cm-keyword { font-weight:bold; } -.cm-s-ttcn .cm-link { color: #00c; text-decoration: underline; } -.cm-s-ttcn .cm-meta { color: #555; } -.cm-s-ttcn .cm-negative { color: #d44; } -.cm-s-ttcn .cm-positive { color: #292; } -.cm-s-ttcn .cm-qualifier { color: #555; } -.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; } -.cm-s-ttcn .cm-string { color: #006400; } -.cm-s-ttcn .cm-string-2 { color: #f50; } -.cm-s-ttcn .cm-strong { font-weight: bold; } -.cm-s-ttcn .cm-tag { color: #170; } -.cm-s-ttcn .cm-variable { color: #8B2252; } -.cm-s-ttcn .cm-variable-2 { color: #05a; } -.cm-s-ttcn .cm-variable-3 { color: #085; } - -.cm-s-ttcn .cm-invalidchar { color: #f00; } - -/* ASN */ -.cm-s-ttcn .cm-accessTypes, -.cm-s-ttcn .cm-compareTypes { color: #27408B; } -.cm-s-ttcn .cm-cmipVerbs { color: #8B2252; } -.cm-s-ttcn .cm-modifier { color:#D2691E; } -.cm-s-ttcn .cm-status { color:#8B4545; } -.cm-s-ttcn .cm-storage { color:#A020F0; } -.cm-s-ttcn .cm-tags { color:#006400; } - -/* CFG */ -.cm-s-ttcn .cm-externalCommands { color: #8B4545; font-weight:bold; } -.cm-s-ttcn .cm-fileNCtrlMaskOptions, -.cm-s-ttcn .cm-sectionTitle { color: #2E8B57; font-weight:bold; } - -/* TTCN */ -.cm-s-ttcn .cm-booleanConsts, -.cm-s-ttcn .cm-otherConsts, -.cm-s-ttcn .cm-verdictConsts { color: #006400; } -.cm-s-ttcn .cm-configOps, -.cm-s-ttcn .cm-functionOps, -.cm-s-ttcn .cm-portOps, -.cm-s-ttcn .cm-sutOps, -.cm-s-ttcn .cm-timerOps, -.cm-s-ttcn .cm-verdictOps { color: #0000FF; } -.cm-s-ttcn .cm-preprocessor, -.cm-s-ttcn .cm-templateMatch, -.cm-s-ttcn .cm-ttcn3Macros { color: #27408B; } -.cm-s-ttcn .cm-types { color: #A52A2A; font-weight:bold; } -.cm-s-ttcn .cm-visibilityModifiers { font-weight:bold; } +.cm-s-ttcn .cm-quote { color: #090; } +.cm-s-ttcn .cm-negative { color: #d44; } +.cm-s-ttcn .cm-positive { color: #292; } +.cm-s-ttcn .cm-header, .cm-strong { font-weight: bold; } +.cm-s-ttcn .cm-em { font-style: italic; } +.cm-s-ttcn .cm-link { text-decoration: underline; } +.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; } +.cm-s-ttcn .cm-header { color: #00f; font-weight: bold; } + +.cm-s-ttcn .cm-atom { color: #219; } +.cm-s-ttcn .cm-attribute { color: #00c; } +.cm-s-ttcn .cm-bracket { color: #997; } +.cm-s-ttcn .cm-comment { color: #333333; } +.cm-s-ttcn .cm-def { color: #00f; } +.cm-s-ttcn .cm-em { font-style: italic; } +.cm-s-ttcn .cm-error { color: #f00; } +.cm-s-ttcn .cm-hr { color: #999; } +.cm-s-ttcn .cm-invalidchar { color: #f00; } +.cm-s-ttcn .cm-keyword { font-weight:bold; } +.cm-s-ttcn .cm-link { color: #00c; text-decoration: underline; } +.cm-s-ttcn .cm-meta { color: #555; } +.cm-s-ttcn .cm-negative { color: #d44; } +.cm-s-ttcn .cm-positive { color: #292; } +.cm-s-ttcn .cm-qualifier { color: #555; } +.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; } +.cm-s-ttcn .cm-string { color: #006400; } +.cm-s-ttcn .cm-string-2 { color: #f50; } +.cm-s-ttcn .cm-strong { font-weight: bold; } +.cm-s-ttcn .cm-tag { color: #170; } +.cm-s-ttcn .cm-variable { color: #8B2252; } +.cm-s-ttcn .cm-variable-2 { color: #05a; } +.cm-s-ttcn .cm-variable-3 { color: #085; } + +.cm-s-ttcn .cm-invalidchar { color: #f00; } + +/* ASN */ +.cm-s-ttcn .cm-accessTypes, +.cm-s-ttcn .cm-compareTypes { color: #27408B; } +.cm-s-ttcn .cm-cmipVerbs { color: #8B2252; } +.cm-s-ttcn .cm-modifier { color:#D2691E; } +.cm-s-ttcn .cm-status { color:#8B4545; } +.cm-s-ttcn .cm-storage { color:#A020F0; } +.cm-s-ttcn .cm-tags { color:#006400; } + +/* CFG */ +.cm-s-ttcn .cm-externalCommands { color: #8B4545; font-weight:bold; } +.cm-s-ttcn .cm-fileNCtrlMaskOptions, +.cm-s-ttcn .cm-sectionTitle { color: #2E8B57; font-weight:bold; } + +/* TTCN */ +.cm-s-ttcn .cm-booleanConsts, +.cm-s-ttcn .cm-otherConsts, +.cm-s-ttcn .cm-verdictConsts { color: #006400; } +.cm-s-ttcn .cm-configOps, +.cm-s-ttcn .cm-functionOps, +.cm-s-ttcn .cm-portOps, +.cm-s-ttcn .cm-sutOps, +.cm-s-ttcn .cm-timerOps, +.cm-s-ttcn .cm-verdictOps { color: #0000FF; } +.cm-s-ttcn .cm-preprocessor, +.cm-s-ttcn .cm-templateMatch, +.cm-s-ttcn .cm-ttcn3Macros { color: #27408B; } +.cm-s-ttcn .cm-types { color: #A52A2A; font-weight:bold; } +.cm-s-ttcn .cm-visibilityModifiers { font-weight:bold; } diff --git a/shared/codemirror/theme/twilight.css b/shared/codemirror/theme/twilight.css index d342b89..b062564 100644 --- a/shared/codemirror/theme/twilight.css +++ b/shared/codemirror/theme/twilight.css @@ -1,32 +1,32 @@ -.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/ -.cm-s-twilight div.CodeMirror-selected { background: #323232; } /**/ -.cm-s-twilight .CodeMirror-line::selection, .cm-s-twilight .CodeMirror-line > span::selection, .cm-s-twilight .CodeMirror-line > span > span::selection { background: rgba(50, 50, 50, 0.99); } -.cm-s-twilight .CodeMirror-line::-moz-selection, .cm-s-twilight .CodeMirror-line > span::-moz-selection, .cm-s-twilight .CodeMirror-line > span > span::-moz-selection { background: rgba(50, 50, 50, 0.99); } - -.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; } -.cm-s-twilight .CodeMirror-guttermarker { color: white; } -.cm-s-twilight .CodeMirror-guttermarker-subtle { color: #aaa; } -.cm-s-twilight .CodeMirror-linenumber { color: #aaa; } -.cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white; } - -.cm-s-twilight .cm-keyword { color: #f9ee98; } /**/ -.cm-s-twilight .cm-atom { color: #FC0; } -.cm-s-twilight .cm-number { color: #ca7841; } /**/ -.cm-s-twilight .cm-def { color: #8DA6CE; } -.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/ -.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def { color: #607392; } /**/ -.cm-s-twilight .cm-operator { color: #cda869; } /**/ -.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/ -.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/ -.cm-s-twilight .cm-string-2 { color:#bd6b18; } /*?*/ -.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/ -.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/ -.cm-s-twilight .cm-tag { color: #997643; } /**/ -.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/ -.cm-s-twilight .cm-header { color: #FF6400; } -.cm-s-twilight .cm-hr { color: #AEAEAE; } -.cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/ -.cm-s-twilight .cm-error { border-bottom: 1px solid red; } - -.cm-s-twilight .CodeMirror-activeline-background { background: #27282E; } -.cm-s-twilight .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } +.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/ +.cm-s-twilight div.CodeMirror-selected { background: #323232; } /**/ +.cm-s-twilight .CodeMirror-line::selection, .cm-s-twilight .CodeMirror-line > span::selection, .cm-s-twilight .CodeMirror-line > span > span::selection { background: rgba(50, 50, 50, 0.99); } +.cm-s-twilight .CodeMirror-line::-moz-selection, .cm-s-twilight .CodeMirror-line > span::-moz-selection, .cm-s-twilight .CodeMirror-line > span > span::-moz-selection { background: rgba(50, 50, 50, 0.99); } + +.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; } +.cm-s-twilight .CodeMirror-guttermarker { color: white; } +.cm-s-twilight .CodeMirror-guttermarker-subtle { color: #aaa; } +.cm-s-twilight .CodeMirror-linenumber { color: #aaa; } +.cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-twilight .cm-keyword { color: #f9ee98; } /**/ +.cm-s-twilight .cm-atom { color: #FC0; } +.cm-s-twilight .cm-number { color: #ca7841; } /**/ +.cm-s-twilight .cm-def { color: #8DA6CE; } +.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/ +.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def { color: #607392; } /**/ +.cm-s-twilight .cm-operator { color: #cda869; } /**/ +.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/ +.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/ +.cm-s-twilight .cm-string-2 { color:#bd6b18; } /*?*/ +.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/ +.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/ +.cm-s-twilight .cm-tag { color: #997643; } /**/ +.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/ +.cm-s-twilight .cm-header { color: #FF6400; } +.cm-s-twilight .cm-hr { color: #AEAEAE; } +.cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/ +.cm-s-twilight .cm-error { border-bottom: 1px solid red; } + +.cm-s-twilight .CodeMirror-activeline-background { background: #27282E; } +.cm-s-twilight .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/shared/codemirror/theme/vibrant-ink.css b/shared/codemirror/theme/vibrant-ink.css index ac4ec6d..f1a8e86 100644 --- a/shared/codemirror/theme/vibrant-ink.css +++ b/shared/codemirror/theme/vibrant-ink.css @@ -1,34 +1,34 @@ -/* Taken from the popular Visual Studio Vibrant Ink Schema */ - -.cm-s-vibrant-ink.CodeMirror { background: black; color: white; } -.cm-s-vibrant-ink div.CodeMirror-selected { background: #35493c; } -.cm-s-vibrant-ink .CodeMirror-line::selection, .cm-s-vibrant-ink .CodeMirror-line > span::selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::selection { background: rgba(53, 73, 60, 0.99); } -.cm-s-vibrant-ink .CodeMirror-line::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::-moz-selection { background: rgba(53, 73, 60, 0.99); } - -.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } -.cm-s-vibrant-ink .CodeMirror-guttermarker { color: white; } -.cm-s-vibrant-ink .CodeMirror-guttermarker-subtle { color: #d0d0d0; } -.cm-s-vibrant-ink .CodeMirror-linenumber { color: #d0d0d0; } -.cm-s-vibrant-ink .CodeMirror-cursor { border-left: 1px solid white; } - -.cm-s-vibrant-ink .cm-keyword { color: #CC7832; } -.cm-s-vibrant-ink .cm-atom { color: #FC0; } -.cm-s-vibrant-ink .cm-number { color: #FFEE98; } -.cm-s-vibrant-ink .cm-def { color: #8DA6CE; } -.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D; } -.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def { color: #FFC66D; } -.cm-s-vibrant-ink .cm-operator { color: #888; } -.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; } -.cm-s-vibrant-ink .cm-string { color: #A5C25C; } -.cm-s-vibrant-ink .cm-string-2 { color: red; } -.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; } -.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; } -.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; } -.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; } -.cm-s-vibrant-ink .cm-header { color: #FF6400; } -.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; } -.cm-s-vibrant-ink .cm-link { color: blue; } -.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; } - -.cm-s-vibrant-ink .CodeMirror-activeline-background { background: #27282E; } -.cm-s-vibrant-ink .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } +/* Taken from the popular Visual Studio Vibrant Ink Schema */ + +.cm-s-vibrant-ink.CodeMirror { background: black; color: white; } +.cm-s-vibrant-ink div.CodeMirror-selected { background: #35493c; } +.cm-s-vibrant-ink .CodeMirror-line::selection, .cm-s-vibrant-ink .CodeMirror-line > span::selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::selection { background: rgba(53, 73, 60, 0.99); } +.cm-s-vibrant-ink .CodeMirror-line::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::-moz-selection { background: rgba(53, 73, 60, 0.99); } + +.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; } +.cm-s-vibrant-ink .CodeMirror-guttermarker { color: white; } +.cm-s-vibrant-ink .CodeMirror-guttermarker-subtle { color: #d0d0d0; } +.cm-s-vibrant-ink .CodeMirror-linenumber { color: #d0d0d0; } +.cm-s-vibrant-ink .CodeMirror-cursor { border-left: 1px solid white; } + +.cm-s-vibrant-ink .cm-keyword { color: #CC7832; } +.cm-s-vibrant-ink .cm-atom { color: #FC0; } +.cm-s-vibrant-ink .cm-number { color: #FFEE98; } +.cm-s-vibrant-ink .cm-def { color: #8DA6CE; } +.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D; } +.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def { color: #FFC66D; } +.cm-s-vibrant-ink .cm-operator { color: #888; } +.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; } +.cm-s-vibrant-ink .cm-string { color: #A5C25C; } +.cm-s-vibrant-ink .cm-string-2 { color: red; } +.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; } +.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; } +.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; } +.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; } +.cm-s-vibrant-ink .cm-header { color: #FF6400; } +.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; } +.cm-s-vibrant-ink .cm-link { color: blue; } +.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; } + +.cm-s-vibrant-ink .CodeMirror-activeline-background { background: #27282E; } +.cm-s-vibrant-ink .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/shared/codemirror/theme/xq-dark.css b/shared/codemirror/theme/xq-dark.css index e3bd960..41ab75c 100644 --- a/shared/codemirror/theme/xq-dark.css +++ b/shared/codemirror/theme/xq-dark.css @@ -1,53 +1,53 @@ -/* -Copyright (C) 2011 by MarkLogic Corporation -Author: Mike Brevoort - -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.CodeMirror { background: #0a001f; color: #f8f8f8; } -.cm-s-xq-dark div.CodeMirror-selected { background: #27007A; } -.cm-s-xq-dark .CodeMirror-line::selection, .cm-s-xq-dark .CodeMirror-line > span::selection, .cm-s-xq-dark .CodeMirror-line > span > span::selection { background: rgba(39, 0, 122, 0.99); } -.cm-s-xq-dark .CodeMirror-line::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 0, 122, 0.99); } -.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } -.cm-s-xq-dark .CodeMirror-guttermarker { color: #FFBD40; } -.cm-s-xq-dark .CodeMirror-guttermarker-subtle { color: #f8f8f8; } -.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; } -.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white; } - -.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-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; } -.cm-s-xq-dark span.cm-error { color: #f00; } - -.cm-s-xq-dark .CodeMirror-activeline-background { background: #27282E; } -.cm-s-xq-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } +/* +Copyright (C) 2011 by MarkLogic Corporation +Author: Mike Brevoort + +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.CodeMirror { background: #0a001f; color: #f8f8f8; } +.cm-s-xq-dark div.CodeMirror-selected { background: #27007A; } +.cm-s-xq-dark .CodeMirror-line::selection, .cm-s-xq-dark .CodeMirror-line > span::selection, .cm-s-xq-dark .CodeMirror-line > span > span::selection { background: rgba(39, 0, 122, 0.99); } +.cm-s-xq-dark .CodeMirror-line::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 0, 122, 0.99); } +.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; } +.cm-s-xq-dark .CodeMirror-guttermarker { color: #FFBD40; } +.cm-s-xq-dark .CodeMirror-guttermarker-subtle { color: #f8f8f8; } +.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; } +.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white; } + +.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-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; } +.cm-s-xq-dark span.cm-error { color: #f00; } + +.cm-s-xq-dark .CodeMirror-activeline-background { background: #27282E; } +.cm-s-xq-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; } diff --git a/shared/codemirror/theme/xq-light.css b/shared/codemirror/theme/xq-light.css index 8d2fcb6..b6c7cb9 100644 --- a/shared/codemirror/theme/xq-light.css +++ b/shared/codemirror/theme/xq-light.css @@ -1,43 +1,43 @@ -/* -Copyright (C) 2011 by MarkLogic Corporation -Author: Mike Brevoort - -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-light span.cm-keyword { line-height: 1em; font-weight: bold; color: #5A5CAD; } -.cm-s-xq-light span.cm-atom { color: #6C8CD5; } -.cm-s-xq-light span.cm-number { color: #164; } -.cm-s-xq-light span.cm-def { text-decoration:underline; } -.cm-s-xq-light span.cm-variable { color: black; } -.cm-s-xq-light span.cm-variable-2 { color:black; } -.cm-s-xq-light span.cm-variable-3 { color: black; } -.cm-s-xq-light span.cm-property {} -.cm-s-xq-light span.cm-operator {} -.cm-s-xq-light span.cm-comment { color: #0080FF; font-style: italic; } -.cm-s-xq-light span.cm-string { color: red; } -.cm-s-xq-light span.cm-meta { color: yellow; } -.cm-s-xq-light span.cm-qualifier { color: grey; } -.cm-s-xq-light span.cm-builtin { color: #7EA656; } -.cm-s-xq-light span.cm-bracket { color: #cc7; } -.cm-s-xq-light span.cm-tag { color: #3F7F7F; } -.cm-s-xq-light span.cm-attribute { color: #7F007F; } -.cm-s-xq-light span.cm-error { color: #f00; } - -.cm-s-xq-light .CodeMirror-activeline-background { background: #e8f2ff; } -.cm-s-xq-light .CodeMirror-matchingbracket { outline:1px solid grey;color:black !important;background:yellow; } +/* +Copyright (C) 2011 by MarkLogic Corporation +Author: Mike Brevoort + +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-light span.cm-keyword { line-height: 1em; font-weight: bold; color: #5A5CAD; } +.cm-s-xq-light span.cm-atom { color: #6C8CD5; } +.cm-s-xq-light span.cm-number { color: #164; } +.cm-s-xq-light span.cm-def { text-decoration:underline; } +.cm-s-xq-light span.cm-variable { color: black; } +.cm-s-xq-light span.cm-variable-2 { color:black; } +.cm-s-xq-light span.cm-variable-3 { color: black; } +.cm-s-xq-light span.cm-property {} +.cm-s-xq-light span.cm-operator {} +.cm-s-xq-light span.cm-comment { color: #0080FF; font-style: italic; } +.cm-s-xq-light span.cm-string { color: red; } +.cm-s-xq-light span.cm-meta { color: yellow; } +.cm-s-xq-light span.cm-qualifier { color: grey; } +.cm-s-xq-light span.cm-builtin { color: #7EA656; } +.cm-s-xq-light span.cm-bracket { color: #cc7; } +.cm-s-xq-light span.cm-tag { color: #3F7F7F; } +.cm-s-xq-light span.cm-attribute { color: #7F007F; } +.cm-s-xq-light span.cm-error { color: #f00; } + +.cm-s-xq-light .CodeMirror-activeline-background { background: #e8f2ff; } +.cm-s-xq-light .CodeMirror-matchingbracket { outline:1px solid grey;color:black !important;background:yellow; } diff --git a/shared/codemirror/theme/yeti.css b/shared/codemirror/theme/yeti.css index c70d4d2..05c5ede 100644 --- a/shared/codemirror/theme/yeti.css +++ b/shared/codemirror/theme/yeti.css @@ -1,44 +1,44 @@ -/* - - Name: yeti - Author: Michael Kaminsky (http://github.com/mkaminsky11) - - Original yeti color scheme by Jesse Weed (https://github.com/jesseweed/yeti-syntax) - -*/ - - -.cm-s-yeti.CodeMirror { - background-color: #ECEAE8 !important; - color: #d1c9c0 !important; - border: none; -} - -.cm-s-yeti .CodeMirror-gutters { - color: #adaba6; - background-color: #E5E1DB; - border: none; -} -.cm-s-yeti .CodeMirror-cursor { border-left: solid thin #d1c9c0; } -.cm-s-yeti .CodeMirror-linenumber { color: #adaba6; } -.cm-s-yeti.CodeMirror-focused div.CodeMirror-selected { background: #DCD8D2; } -.cm-s-yeti .CodeMirror-line::selection, .cm-s-yeti .CodeMirror-line > span::selection, .cm-s-yeti .CodeMirror-line > span > span::selection { background: #DCD8D2; } -.cm-s-yeti .CodeMirror-line::-moz-selection, .cm-s-yeti .CodeMirror-line > span::-moz-selection, .cm-s-yeti .CodeMirror-line > span > span::-moz-selection { background: #DCD8D2; } -.cm-s-yeti span.cm-comment { color: #d4c8be; } -.cm-s-yeti span.cm-string, .cm-s-yeti span.cm-string-2 { color: #96c0d8; } -.cm-s-yeti span.cm-number { color: #a074c4; } -.cm-s-yeti span.cm-variable { color: #55b5db; } -.cm-s-yeti span.cm-variable-2 { color: #a074c4; } -.cm-s-yeti span.cm-def { color: #55b5db; } -.cm-s-yeti span.cm-operator { color: #9fb96e; } -.cm-s-yeti span.cm-keyword { color: #9fb96e; } -.cm-s-yeti span.cm-atom { color: #a074c4; } -.cm-s-yeti span.cm-meta { color: #96c0d8; } -.cm-s-yeti span.cm-tag { color: #96c0d8; } -.cm-s-yeti span.cm-attribute { color: #9fb96e; } -.cm-s-yeti span.cm-qualifier { color: #96c0d8; } -.cm-s-yeti span.cm-property { color: #a074c4; } -.cm-s-yeti span.cm-builtin { color: #a074c4; } -.cm-s-yeti span.cm-variable-3 { color: #96c0d8; } -.cm-s-yeti .CodeMirror-activeline-background { background: #E7E4E0; } -.cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline; } +/* + + Name: yeti + Author: Michael Kaminsky (http://github.com/mkaminsky11) + + Original yeti color scheme by Jesse Weed (https://github.com/jesseweed/yeti-syntax) + +*/ + + +.cm-s-yeti.CodeMirror { + background-color: #ECEAE8 !important; + color: #d1c9c0 !important; + border: none; +} + +.cm-s-yeti .CodeMirror-gutters { + color: #adaba6; + background-color: #E5E1DB; + border: none; +} +.cm-s-yeti .CodeMirror-cursor { border-left: solid thin #d1c9c0; } +.cm-s-yeti .CodeMirror-linenumber { color: #adaba6; } +.cm-s-yeti.CodeMirror-focused div.CodeMirror-selected { background: #DCD8D2; } +.cm-s-yeti .CodeMirror-line::selection, .cm-s-yeti .CodeMirror-line > span::selection, .cm-s-yeti .CodeMirror-line > span > span::selection { background: #DCD8D2; } +.cm-s-yeti .CodeMirror-line::-moz-selection, .cm-s-yeti .CodeMirror-line > span::-moz-selection, .cm-s-yeti .CodeMirror-line > span > span::-moz-selection { background: #DCD8D2; } +.cm-s-yeti span.cm-comment { color: #d4c8be; } +.cm-s-yeti span.cm-string, .cm-s-yeti span.cm-string-2 { color: #96c0d8; } +.cm-s-yeti span.cm-number { color: #a074c4; } +.cm-s-yeti span.cm-variable { color: #55b5db; } +.cm-s-yeti span.cm-variable-2 { color: #a074c4; } +.cm-s-yeti span.cm-def { color: #55b5db; } +.cm-s-yeti span.cm-operator { color: #9fb96e; } +.cm-s-yeti span.cm-keyword { color: #9fb96e; } +.cm-s-yeti span.cm-atom { color: #a074c4; } +.cm-s-yeti span.cm-meta { color: #96c0d8; } +.cm-s-yeti span.cm-tag { color: #96c0d8; } +.cm-s-yeti span.cm-attribute { color: #9fb96e; } +.cm-s-yeti span.cm-qualifier { color: #96c0d8; } +.cm-s-yeti span.cm-property { color: #a074c4; } +.cm-s-yeti span.cm-builtin { color: #a074c4; } +.cm-s-yeti span.cm-variable-3 { color: #96c0d8; } +.cm-s-yeti .CodeMirror-activeline-background { background: #E7E4E0; } +.cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline; } diff --git a/shared/codemirror/theme/zenburn.css b/shared/codemirror/theme/zenburn.css index 781c40a..69cecea 100644 --- a/shared/codemirror/theme/zenburn.css +++ b/shared/codemirror/theme/zenburn.css @@ -1,37 +1,37 @@ -/** - * " - * Using Zenburn color palette from the Emacs Zenburn Theme - * https://github.com/bbatsov/zenburn-emacs/blob/master/zenburn-theme.el - * - * Also using parts of https://github.com/xavi/coderay-lighttable-theme - * " - * From: https://github.com/wisenomad/zenburn-lighttable-theme/blob/master/zenburn.css - */ - -.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; } -.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; } -.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; } -.cm-s-zenburn { background-color: #3f3f3f; color: #dcdccc; } -.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; } -.cm-s-zenburn span.cm-comment { color: #7f9f7f; } -.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; } -.cm-s-zenburn span.cm-atom { color: #bfebbf; } -.cm-s-zenburn span.cm-def { color: #dcdccc; } -.cm-s-zenburn span.cm-variable { color: #dfaf8f; } -.cm-s-zenburn span.cm-variable-2 { color: #dcdccc; } -.cm-s-zenburn span.cm-string { color: #cc9393; } -.cm-s-zenburn span.cm-string-2 { color: #cc9393; } -.cm-s-zenburn span.cm-number { color: #dcdccc; } -.cm-s-zenburn span.cm-tag { color: #93e0e3; } -.cm-s-zenburn span.cm-property { color: #dfaf8f; } -.cm-s-zenburn span.cm-attribute { color: #dfaf8f; } -.cm-s-zenburn span.cm-qualifier { color: #7cb8bb; } -.cm-s-zenburn span.cm-meta { color: #f0dfaf; } -.cm-s-zenburn span.cm-header { color: #f0efd0; } -.cm-s-zenburn span.cm-operator { color: #f0efd0; } -.cm-s-zenburn span.CodeMirror-matchingbracket { box-sizing: border-box; background: transparent; border-bottom: 1px solid; } -.cm-s-zenburn span.CodeMirror-nonmatchingbracket { border-bottom: 1px solid; background: none; } -.cm-s-zenburn .CodeMirror-activeline { background: #000000; } -.cm-s-zenburn .CodeMirror-activeline-background { background: #000000; } -.cm-s-zenburn div.CodeMirror-selected { background: #545454; } -.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected { background: #4f4f4f; } +/** + * " + * Using Zenburn color palette from the Emacs Zenburn Theme + * https://github.com/bbatsov/zenburn-emacs/blob/master/zenburn-theme.el + * + * Also using parts of https://github.com/xavi/coderay-lighttable-theme + * " + * From: https://github.com/wisenomad/zenburn-lighttable-theme/blob/master/zenburn.css + */ + +.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; } +.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; } +.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; } +.cm-s-zenburn { background-color: #3f3f3f; color: #dcdccc; } +.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; } +.cm-s-zenburn span.cm-comment { color: #7f9f7f; } +.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; } +.cm-s-zenburn span.cm-atom { color: #bfebbf; } +.cm-s-zenburn span.cm-def { color: #dcdccc; } +.cm-s-zenburn span.cm-variable { color: #dfaf8f; } +.cm-s-zenburn span.cm-variable-2 { color: #dcdccc; } +.cm-s-zenburn span.cm-string { color: #cc9393; } +.cm-s-zenburn span.cm-string-2 { color: #cc9393; } +.cm-s-zenburn span.cm-number { color: #dcdccc; } +.cm-s-zenburn span.cm-tag { color: #93e0e3; } +.cm-s-zenburn span.cm-property { color: #dfaf8f; } +.cm-s-zenburn span.cm-attribute { color: #dfaf8f; } +.cm-s-zenburn span.cm-qualifier { color: #7cb8bb; } +.cm-s-zenburn span.cm-meta { color: #f0dfaf; } +.cm-s-zenburn span.cm-header { color: #f0efd0; } +.cm-s-zenburn span.cm-operator { color: #f0efd0; } +.cm-s-zenburn span.CodeMirror-matchingbracket { box-sizing: border-box; background: transparent; border-bottom: 1px solid; } +.cm-s-zenburn span.CodeMirror-nonmatchingbracket { border-bottom: 1px solid; background: none; } +.cm-s-zenburn .CodeMirror-activeline { background: #000000; } +.cm-s-zenburn .CodeMirror-activeline-background { background: #000000; } +.cm-s-zenburn div.CodeMirror-selected { background: #545454; } +.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected { background: #4f4f4f; } diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 305e5cc..c090757 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -1,73 +1,73 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); - - -var CodeMirror; -if(typeof navigator !== 'undefined'){ - var CodeMirror = require('codemirror'); - - //Language Modes - require('codemirror/mode/gfm/gfm.js'); //Github flavoured markdown - require('codemirror/mode/javascript/javascript.js'); -} - - -var CodeEditor = React.createClass({ - getDefaultProps: function() { - return { - language : '', - value : '', - wrap : false, - onChange : function(){}, - onCursorActivity : function(){}, - }; - }, - - componentDidMount: function() { - this.codeMirror = CodeMirror(this.refs.editor,{ - value : this.props.value, - lineNumbers: true, - lineWrapping : this.props.wrap, - mode : this.props.language - }); - - this.codeMirror.on('change', this.handleChange); - this.codeMirror.on('cursorActivity', this.handleCursorActivity); - this.updateSize(); - }, - - componentWillReceiveProps: function(nextProps){ - if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) { - this.codeMirror.setValue(nextProps.value); - } - }, - - shouldComponentUpdate: function(nextProps, nextState) { - return false; - }, - - setCursorPosition : function(line, char){ - setTimeout(()=>{ - this.codeMirror.focus(); - this.codeMirror.doc.setCursor(line, char); - }, 10); - }, - - updateSize : function(){ - this.codeMirror.refresh(); - }, - - handleChange : function(editor){ - this.props.onChange(editor.getValue()); - }, - handleCursorActivity : function(){ - this.props.onCursorActivity(this.codeMirror.doc.getCursor()); - }, - - render : function(){ - return
- } -}); - -module.exports = CodeEditor; +var React = require('react'); +var _ = require('lodash'); +var cx = require('classnames'); + + +var CodeMirror; +if(typeof navigator !== 'undefined'){ + var CodeMirror = require('codemirror'); + + //Language Modes + require('codemirror/mode/gfm/gfm.js'); //Github flavoured markdown + require('codemirror/mode/javascript/javascript.js'); +} + + +var CodeEditor = React.createClass({ + getDefaultProps: function() { + return { + language : '', + value : '', + wrap : false, + onChange : function(){}, + onCursorActivity : function(){}, + }; + }, + + componentDidMount: function() { + this.codeMirror = CodeMirror(this.refs.editor,{ + value : this.props.value, + lineNumbers: true, + lineWrapping : this.props.wrap, + mode : this.props.language + }); + + this.codeMirror.on('change', this.handleChange); + this.codeMirror.on('cursorActivity', this.handleCursorActivity); + this.updateSize(); + }, + + componentWillReceiveProps: function(nextProps){ + if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) { + this.codeMirror.setValue(nextProps.value); + } + }, + + shouldComponentUpdate: function(nextProps, nextState) { + return false; + }, + + setCursorPosition : function(line, char){ + setTimeout(()=>{ + this.codeMirror.focus(); + this.codeMirror.doc.setCursor(line, char); + }, 10); + }, + + updateSize : function(){ + this.codeMirror.refresh(); + }, + + handleChange : function(editor){ + this.props.onChange(editor.getValue()); + }, + handleCursorActivity : function(){ + this.props.onCursorActivity(this.codeMirror.doc.getCursor()); + }, + + render : function(){ + return
+ } +}); + +module.exports = CodeEditor; diff --git a/shared/naturalcrit/codeEditor/codeEditor.less b/shared/naturalcrit/codeEditor/codeEditor.less index aa8eca6..7daa0c4 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.less +++ b/shared/naturalcrit/codeEditor/codeEditor.less @@ -1,5 +1,5 @@ -@import (less) 'codemirror/lib/codemirror.css'; - -.codeEditor{ - +@import (less) 'codemirror/lib/codemirror.css'; + +.codeEditor{ + } \ No newline at end of file diff --git a/shared/naturalcrit/combat/combat.actions.js b/shared/naturalcrit/combat/combat.actions.js index a48b34c..cecb836 100644 --- a/shared/naturalcrit/combat/combat.actions.js +++ b/shared/naturalcrit/combat/combat.actions.js @@ -1,23 +1,23 @@ -var dispatch = require('pico-flux').dispatch; - -module.exports = { - updateMonsterManual : function(json){ - dispatch('UDPATE_MONSTER_MANUAL', json); - }, - addEncounter : function(){ - dispatch('ADD_ENCOUNTER'); - }, - updateEncounter : function(index, json){ - dispatch('UPDATE_ENCOUNTER', index, json); - }, - removeEncounter : function(index){ - dispatch('REMOVE_ENCOUNTER', index); - }, - updatePlayers : function(text){ - dispatch('UPDATE_PLAYERS', text); - }, - selectEncounter : function(index){ - dispatch('SELECT_ENCOUNTER', index); - }, - +var dispatch = require('pico-flux').dispatch; + +module.exports = { + updateMonsterManual : function(json){ + dispatch('UDPATE_MONSTER_MANUAL', json); + }, + addEncounter : function(){ + dispatch('ADD_ENCOUNTER'); + }, + updateEncounter : function(index, json){ + dispatch('UPDATE_ENCOUNTER', index, json); + }, + removeEncounter : function(index){ + dispatch('REMOVE_ENCOUNTER', index); + }, + updatePlayers : function(text){ + dispatch('UPDATE_PLAYERS', text); + }, + selectEncounter : function(index){ + dispatch('SELECT_ENCOUNTER', index); + }, + } \ No newline at end of file diff --git a/shared/naturalcrit/combat/combat.store.js b/shared/naturalcrit/combat/combat.store.js index cfe997b..d6a07ba 100644 --- a/shared/naturalcrit/combat/combat.store.js +++ b/shared/naturalcrit/combat/combat.store.js @@ -1,69 +1,69 @@ -var flux = require('pico-flux'); -var _ = require('lodash'); - -var defaultMonsterManual = require('naturalcrit/defaultMonsterManual.js'); -var GetRandomEncounter = require('naturalcrit/randomEncounter.js'); - -var Store = { - selectedEncounterIndex : 0, - encounters : JSON.parse(localStorage.getItem('encounters')) || [GetRandomEncounter()], - monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || defaultMonsterManual, - players : localStorage.getItem('players') || 'jasper 13\nzatch 19', -}; - - -module.exports = flux.createStore({ - UDPATE_MONSTER_MANUAL : function(json){ - Store.monsterManual = json; - return true; - }, - ADD_ENCOUNTER : function(){ - Store.encounters.push(GetRandomEncounter()); - return true; - }, - UPDATE_ENCOUNTER : function(index, json){ - Store.encounters[index] = json; - return true; - }, - REMOVE_ENCOUNTER : function(index){ - Store.encounters.splice(index, 1); - return true; - }, - UPDATE_PLAYERS : function(text){ - Store.players = text; - return true; - }, - SELECT_ENCOUNTER : function(index){ - Store.selectedEncounterIndex = index; - return true; - }, - -},{ - getMonsterManual : function(){ - return Store.monsterManual; - }, - getSelectedEncounterIndex : function(){ - return Store.selectedEncounterIndex; - }, - getSelectedEncounter : function(){ - return Store.encounters[Store.selectedEncounterIndex]; - }, - getEncounter : function(index){ - return Store.encounters[index]; - }, - getEncounters : function(index){ - return Store.encounters; - }, - getPlayersText : function(){ - return Store.players; - }, - getPlayers : function(){ - return _.reduce(Store.players.split('\n'), function(r, line){ - var idx = line.lastIndexOf(' '); - if(idx !== -1){ - r[line.substring(0, idx)] = line.substring(idx)*1; - } - return r; - }, {}) - }, +var flux = require('pico-flux'); +var _ = require('lodash'); + +var defaultMonsterManual = require('naturalcrit/defaultMonsterManual.js'); +var GetRandomEncounter = require('naturalcrit/randomEncounter.js'); + +var Store = { + selectedEncounterIndex : 0, + encounters : JSON.parse(localStorage.getItem('encounters')) || [GetRandomEncounter()], + monsterManual : JSON.parse(localStorage.getItem('monsterManual')) || defaultMonsterManual, + players : localStorage.getItem('players') || 'jasper 13\nzatch 19', +}; + + +module.exports = flux.createStore({ + UDPATE_MONSTER_MANUAL : function(json){ + Store.monsterManual = json; + return true; + }, + ADD_ENCOUNTER : function(){ + Store.encounters.push(GetRandomEncounter()); + return true; + }, + UPDATE_ENCOUNTER : function(index, json){ + Store.encounters[index] = json; + return true; + }, + REMOVE_ENCOUNTER : function(index){ + Store.encounters.splice(index, 1); + return true; + }, + UPDATE_PLAYERS : function(text){ + Store.players = text; + return true; + }, + SELECT_ENCOUNTER : function(index){ + Store.selectedEncounterIndex = index; + return true; + }, + +},{ + getMonsterManual : function(){ + return Store.monsterManual; + }, + getSelectedEncounterIndex : function(){ + return Store.selectedEncounterIndex; + }, + getSelectedEncounter : function(){ + return Store.encounters[Store.selectedEncounterIndex]; + }, + getEncounter : function(index){ + return Store.encounters[index]; + }, + getEncounters : function(index){ + return Store.encounters; + }, + getPlayersText : function(){ + return Store.players; + }, + getPlayers : function(){ + return _.reduce(Store.players.split('\n'), function(r, line){ + var idx = line.lastIndexOf(' '); + if(idx !== -1){ + r[line.substring(0, idx)] = line.substring(idx)*1; + } + return r; + }, {}) + }, }) \ No newline at end of file diff --git a/shared/naturalcrit/combat/defaultMonsterManual.js b/shared/naturalcrit/combat/defaultMonsterManual.js index 433fbdd..9e9ea7e 100644 --- a/shared/naturalcrit/combat/defaultMonsterManual.js +++ b/shared/naturalcrit/combat/defaultMonsterManual.js @@ -1,140 +1,140 @@ -module.exports = { - goblin : { - size : 'small', - type : 'beast', - alignment : 'unaligned', - stats : { - hp : 40, - mov: 30, - ac : 13, - }, - scores : { - str : 8, - con : 8, - dex : 8, - int : 8, - wis : 8, - cha : 8 - }, - attr : { - skills : ['Stealth +5'], - lang : ['common'], - cr : 0.25, - }, - abilities : { - "pack tactics" : "Does a thing", - "fancy dance" : "dances fancy" - }, - actions : { - bite : { - type : "Melee weapon attack", - atk : "+4 to hit", - rng : "5ft", - target : "one target", - dmg : "4 (1d4 + 2) piercing damage", - desc: "" - }, - scare : { - uses : "1/day", - desc : "scares you" - } - }, - items : ['rat on a stick'] - }, - - "Goat Slime" : { - hp : 80, - mov: 10, - cr : 0.5, - ac : 16, - attr : { - str : 8, - con : 8, - dex : 6, - int : 4, - wis : 8, - cha : 8 - }, - attacks : { - caress : { - atk : "1d20+1", - dmg : "3d4+1", - type : "sensual" - }, - }, - abilities : { - "Agnostic Gel" : "Immune to magical damage" - }, - items : [] - }, - "badass psycho" : { - hp : 100, - mov: 50, - ac : 14, - cr : 5, - attr : { - str : 17, - con : 18, - dex : 16, - int : 7, - wis : 7, - cha : 7 - }, - attacks : { - "throwing axe" : { - atk : "1d20+5", - dmg : "1d12+5", - type : "piercing", - rng : "30", - notes : "returns to baddie after throw" - }, - shoot : { - atk : "1d20+2", - dmg : "4d4", - rng : "120" - } - }, - spells : { - "meat popsicle" : { - dmg : "4d6", - uses : 8 - }, - "sanity check" : { - dmg : "2d8+4", - uses : 6 - } - }, - abilities : { - "rampage" : "when damaged, can choose to take damage from opportunity attacks for allies" - }, - items : ['buzz_axe', 'healing_potion', 'tuna_fish'] - }, - toxicologist : { - hp : 40, - mov: 30, - ac : 11, - cr : 0.5, - attr : { - str : 7, - con : 11, - dex : 10, - int : 18, - wis : 15, - cha : 7 - }, - spells : { - "publish paper" : { - dmg : "4d6", - uses : 4 - }, - "tox test" : { - heal : "2d8+4", - uses : 6 - } - }, - abilities : { - "conference" : "when around more than 30 other toxicologists, consume 1 drink every 15 minutes" - }, - items : ['grad_student', 'imposter_syndrome', 'ring'] - }, +module.exports = { + goblin : { + size : 'small', + type : 'beast', + alignment : 'unaligned', + stats : { + hp : 40, + mov: 30, + ac : 13, + }, + scores : { + str : 8, + con : 8, + dex : 8, + int : 8, + wis : 8, + cha : 8 + }, + attr : { + skills : ['Stealth +5'], + lang : ['common'], + cr : 0.25, + }, + abilities : { + "pack tactics" : "Does a thing", + "fancy dance" : "dances fancy" + }, + actions : { + bite : { + type : "Melee weapon attack", + atk : "+4 to hit", + rng : "5ft", + target : "one target", + dmg : "4 (1d4 + 2) piercing damage", + desc: "" + }, + scare : { + uses : "1/day", + desc : "scares you" + } + }, + items : ['rat on a stick'] + }, + + "Goat Slime" : { + hp : 80, + mov: 10, + cr : 0.5, + ac : 16, + attr : { + str : 8, + con : 8, + dex : 6, + int : 4, + wis : 8, + cha : 8 + }, + attacks : { + caress : { + atk : "1d20+1", + dmg : "3d4+1", + type : "sensual" + }, + }, + abilities : { + "Agnostic Gel" : "Immune to magical damage" + }, + items : [] + }, + "badass psycho" : { + hp : 100, + mov: 50, + ac : 14, + cr : 5, + attr : { + str : 17, + con : 18, + dex : 16, + int : 7, + wis : 7, + cha : 7 + }, + attacks : { + "throwing axe" : { + atk : "1d20+5", + dmg : "1d12+5", + type : "piercing", + rng : "30", + notes : "returns to baddie after throw" + }, + shoot : { + atk : "1d20+2", + dmg : "4d4", + rng : "120" + } + }, + spells : { + "meat popsicle" : { + dmg : "4d6", + uses : 8 + }, + "sanity check" : { + dmg : "2d8+4", + uses : 6 + } + }, + abilities : { + "rampage" : "when damaged, can choose to take damage from opportunity attacks for allies" + }, + items : ['buzz_axe', 'healing_potion', 'tuna_fish'] + }, + toxicologist : { + hp : 40, + mov: 30, + ac : 11, + cr : 0.5, + attr : { + str : 7, + con : 11, + dex : 10, + int : 18, + wis : 15, + cha : 7 + }, + spells : { + "publish paper" : { + dmg : "4d6", + uses : 4 + }, + "tox test" : { + heal : "2d8+4", + uses : 6 + } + }, + abilities : { + "conference" : "when around more than 30 other toxicologists, consume 1 drink every 15 minutes" + }, + items : ['grad_student', 'imposter_syndrome', 'ring'] + }, } \ No newline at end of file diff --git a/shared/naturalcrit/combat/homebrewIcon.svg.jsx b/shared/naturalcrit/combat/homebrewIcon.svg.jsx index 3892018..f9b936a 100644 --- a/shared/naturalcrit/combat/homebrewIcon.svg.jsx +++ b/shared/naturalcrit/combat/homebrewIcon.svg.jsx @@ -1,13 +1,13 @@ -var React = require('react'); - -var Logo = React.createClass({ - render : function(){ - return - - - - - } -}); - -module.exports = Logo; +var React = require('react'); + +var Logo = React.createClass({ + render : function(){ + return + + + + + } +}); + +module.exports = Logo; diff --git a/shared/naturalcrit/combat/html2canvas.js b/shared/naturalcrit/combat/html2canvas.js index 8792636..c4ea07d 100644 --- a/shared/naturalcrit/combat/html2canvas.js +++ b/shared/naturalcrit/combat/html2canvas.js @@ -1,3375 +1,3375 @@ -/* - html2canvas 0.5.0-alpha1 - Copyright (c) 2015 Niklas von Hertzen - - Released under MIT License -*/ - -(function(window, document, exports, global, define, undefined){ - -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE - * @version 2.0.1 - */ - -(function(){function r(a,b){n[l]=a;n[l+1]=b;l+=2;2===l&&A()}function s(a){return"function"===typeof a}function F(){return function(){process.nextTick(t)}}function G(){var a=0,b=new B(t),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}function H(){var a=new MessageChannel;a.port1.onmessage=t;return function(){a.port2.postMessage(0)}}function I(){return function(){setTimeout(t,1)}}function t(){for(var a=0;a= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, - - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - - /** Temporary variable */ - key; - - /*--------------------------------------------------------------------------*/ - - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - var result = []; - while (length--) { - result[length] = fn(array[length]); - } - return result; - } - - /** - * A simple `Array#map`-like wrapper to work with domain name strings or email - * addresses. - * @private - * @param {String} domain The domain name or email address. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - var parts = string.split('@'); - var result = ''; - if (parts.length > 1) { - // In email addresses, only the domain name should be punycoded. Leave - // the local part (i.e. everything up to `@`) intact. - result = parts[0] + '@'; - string = parts[1]; - } - var labels = string.split(regexSeparators); - var encoded = map(labels, fn).join('.'); - return result + encoded; - } - - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } - - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } - - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } - - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * http://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } - - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; - - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. - - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - - if (index >= inputLength) { - error('invalid-input'); - } - - digit = basicToDigit(input.charCodeAt(index++)); - - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } - - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - - if (digit < t) { - break; - } - - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } - - w *= baseMinusT; - - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); - - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } - - n += floor(i / out); - i %= out; - - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); - - } - - return ucs2encode(output); - } - - /** - * Converts a string of Unicode symbols (e.g. a domain name label) to a - * Punycode string of ASCII-only symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; - - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); - - // Cache the length - inputLength = input.length; - - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; - - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - handledCPCount = basicLength = output.length; - - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. - - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } - - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - - } - return output.join(''); - } - - /** - * Converts a Punycode string representing a domain name or an email address - * to Unicode. Only the Punycoded parts of the input will be converted, i.e. - * it doesn't matter if you call it on a string that has already been - * converted to Unicode. - * @memberOf punycode - * @param {String} input The Punycoded domain name or email address to - * convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(input) { - return mapDomain(input, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } - - /** - * Converts a Unicode string representing a domain name or an email address to - * Punycode. Only the non-ASCII parts of the domain name will be converted, - * i.e. it doesn't matter if you call it with a domain that's already in - * ASCII. - * @memberOf punycode - * @param {String} input The domain name or email address to convert, as a - * Unicode string. - * @returns {String} The Punycode representation of the given domain name or - * email address. - */ - function toASCII(input) { - return mapDomain(input, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.3.1', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; - - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && freeModule) { - if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { // in Rhino or a web browser - root.punycode = punycode; - } - -}(this)); - -var html2canvasNodeAttribute = "data-html2canvas-node"; -var html2canvasCanvasCloneAttribute = "data-html2canvas-canvas-clone"; -var html2canvasCanvasCloneIndex = 0; -var html2canvasCloneIndex = 0; - -window.html2canvas = function(nodeList, options) { - var index = html2canvasCloneIndex++; - options = options || {}; - if (options.logging) { - window.html2canvas.logging = true; - window.html2canvas.start = Date.now(); - } - - options.async = typeof(options.async) === "undefined" ? true : options.async; - options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint; - options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer; - options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled; - options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout; - options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer; - options.strict = !!options.strict; - - if (typeof(nodeList) === "string") { - if (typeof(options.proxy) !== "string") { - return Promise.reject("Proxy must be used when rendering url"); - } - var width = options.width != null ? options.width : window.innerWidth; - var height = options.height != null ? options.height : window.innerHeight; - return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) { - return renderWindow(container.contentWindow.document.documentElement, container, options, width, height); - }); - } - - var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0]; - node.setAttribute(html2canvasNodeAttribute + index, index); - return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) { - if (typeof(options.onrendered) === "function") { - log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"); - options.onrendered(canvas); - } - return canvas; - }); -}; - -window.html2canvas.punycode = this.punycode; -window.html2canvas.proxy = {}; - -function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) { - return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) { - log("Document cloned"); - var attributeName = html2canvasNodeAttribute + html2canvasIndex; - var selector = "[" + attributeName + "='" + html2canvasIndex + "']"; - document.querySelector(selector).removeAttribute(attributeName); - var clonedWindow = container.contentWindow; - var node = clonedWindow.document.querySelector(selector); - var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true); - return oncloneHandler.then(function() { - return renderWindow(node, container, options, windowWidth, windowHeight); - }); - }); -} - -function renderWindow(node, container, options, windowWidth, windowHeight) { - var clonedWindow = container.contentWindow; - var support = new Support(clonedWindow.document); - var imageLoader = new ImageLoader(options, support); - var bounds = getBounds(node); - var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document); - var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document); - var renderer = new options.renderer(width, height, imageLoader, options, document); - var parser = new NodeParser(node, renderer, support, imageLoader, options); - return parser.ready.then(function() { - log("Finished rendering"); - var canvas; - - if (options.type === "view") { - canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0}); - } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) { - canvas = renderer.canvas; - } else { - canvas = crop(renderer.canvas, {width: options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: clonedWindow.pageXOffset, y: clonedWindow.pageYOffset}); - } - - cleanupContainer(container, options); - return canvas; - }); -} - -function cleanupContainer(container, options) { - if (options.removeContainer) { - container.parentNode.removeChild(container); - log("Cleaned up container"); - } -} - -function crop(canvas, bounds) { - var croppedCanvas = document.createElement("canvas"); - var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left)); - var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width)); - var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top)); - var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height)); - croppedCanvas.width = bounds.width; - croppedCanvas.height = bounds.height; - log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", (x2-x1), "height:", (y2-y1)); - log("Resulting crop with width", bounds.width, "and height", bounds.height, " with x", x1, "and y", y1); - croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, x2-x1, y2-y1, bounds.x, bounds.y, x2-x1, y2-y1); - return croppedCanvas; -} - -function documentWidth (doc) { - return Math.max( - Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth), - Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth), - Math.max(doc.body.clientWidth, doc.documentElement.clientWidth) - ); -} - -function documentHeight (doc) { - return Math.max( - Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight), - Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight), - Math.max(doc.body.clientHeight, doc.documentElement.clientHeight) - ); -} - -function smallImage() { - return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; -} - -function isIE9() { - return document.documentMode && document.documentMode <= 9; -} - -// https://github.com/niklasvh/html2canvas/issues/503 -function cloneNodeIE9(node, javascriptEnabled) { - var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false); - - var child = node.firstChild; - while(child) { - if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') { - clone.appendChild(cloneNodeIE9(child, javascriptEnabled)); - } - child = child.nextSibling; - } - - return clone; -} - -function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) { - labelCanvasElements(ownerDocument); - var documentElement = isIE9() ? cloneNodeIE9(ownerDocument.documentElement, options.javascriptEnabled) : ownerDocument.documentElement.cloneNode(true); - var container = containerDocument.createElement("iframe"); - - container.className = "html2canvas-container"; - container.style.visibility = "hidden"; - container.style.position = "fixed"; - container.style.left = "-10000px"; - container.style.top = "0px"; - container.style.border = "0"; - container.width = width; - container.height = height; - container.scrolling = "no"; // ios won't scroll without it - containerDocument.body.appendChild(container); - - return new Promise(function(resolve) { - var documentClone = container.contentWindow.document; - - cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea"); - cloneNodeValues(ownerDocument.documentElement, documentElement, "select"); - - /* Chrome doesn't detect relative background-images assigned in inline