Mercurial > eldonilo > lightstring
changeset 108:5cb4733c5189
many api changes
line wrap: on
line diff
--- a/console/console.css +++ b/console/console.css @@ -36,6 +36,7 @@ body { } #input input { width: 65px; + -webkit-appearance: none; } #input > * { display: inline-block;
--- a/console/console.js +++ b/console/console.js @@ -1,100 +1,109 @@ 'use strict'; -var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; - -if(!Lightstring) - var Lightstring = {}; - -Lightstring.console = { - invertedScroll: true, - log: function(aLog) { - var stanza = vkbeautify.xml(aLog.data, 2, ' '); - var entry = document.createElement('div'); - entry.classList.add('entry'); - entry.classList.add(aLog.dir); - var header = document.createElement('header'); - //FIXME date? should come from the origin? - header.textContent = aLog.dir + ': '; - entry.appendChild(header) - var pre = document.createElement('pre'); - pre.textContent = stanza; - entry.appendChild(pre); - var entriesEl = document.querySelector('#entries') - entriesEl.appendChild(entry); - }, - filter: function(aFilter) { - var entries = document.querySelectorAll('.entry pre'); - for (var i = 0, length = entries.length; i < length; i++) { - var entry = entries[i]; - if (!entry.textContent.match(aFilter)) - entry.parentNode.hidden = true; - else - entry.parentNode.hidden = false; - - //FIXME use the Mutation Observer? get back to the previous scroll state? - this.scrollToBottom(); - } - }, - send: function(aData) { - Lightstring.console.source.postMessage({ - 'send': aData}, document.location.protocol + '//' + document.location.host); - }, - scrollToBottom: function() { - this.entriesEl.scrollTop = (this.entriesEl.scrollHeight - this.entriesEl.clientHeight); - } -}; - (function() { - document.addEventListener('DOMContentLoaded', function() { - - var entriesEl = document.getElementById('entries'); - entriesEl.addEventListener('scroll', function(e) { - if (entriesEl.scrollTop === (entriesEl.scrollHeight - entriesEl.clientHeight)) - Lightstring.console.invertedScroll = true; - else - Lightstring.console.invertedScroll = false; - }) - - new MutationObserver(function(mutations) { - if(Lightstring.console.invertedScroll === true) - Lightstring.console.scrollToBottom(); - }).observe(entriesEl, { - childList: true, - // attributes: false, - // characterData: false - }); - - Lightstring.console.entriesEl = entriesEl; - if (Lightstring.console.invertedScroll) - Lightstring.console.scrollToBottom(); - - window.addEventListener("message", function(e) { - if(!Lightstring.console.source) - Lightstring.console.source = e.source; + var Console = { + holder: [], + invertedScroll: true, + log: function(aLog) { + if (document.readyState !== 'complete') { + this.holder.push(aLog); + return; + } + //beautify + var stanza = vkbeautify.xml(aLog.data, 2, ' '); + var entry = document.createElement('div'); + entry.classList.add('entry'); + entry.classList.add(aLog.dir); + var header = document.createElement('header'); + var date = new Date(); + var hours = (date.getHours() < 10 ? '0' : '') + date.getHours(); + var minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(); + var seconds = (date.getSeconds() < 10 ? '0' : '') + date.getSeconds(); + var timestamp = hours + ':' + minutes + ':' + seconds + '.' + date.getMilliseconds(); + header.textContent = aLog.dir + ': ' + timestamp; + entry.appendChild(header) + var pre = document.createElement('pre'); + pre.textContent = stanza; + entry.appendChild(pre); + //highlight + hljs.highlightBlock(entry.children[1], null, false); + var entriesEl = document.querySelector('#entries') - Lightstring.console.log(e.data); - }, false); + var child = entriesEl.firstChild; + if(child) + entriesEl.insertBefore(entry, child); + else + entriesEl.appendChild(entry) + }, + filter: function(aFilter) { + var entries = document.querySelectorAll('.entry pre'); + for (var i = 0, length = entries.length; i < length; i++) { + var entry = entries[i]; + if (!entry.textContent.match(aFilter)) + entry.parentNode.hidden = true; + else + entry.parentNode.hidden = false; + } + }, + send: function(aData) { + //C'mon you can do better + Lightstring.connections[0].send(aData) + }, + init: function() { + if (Lightstring.Connection) { + Lightstring.Connection.prototype.on('stanza', function(stanza) { + Lightstring.console.log({dir: 'in', data: stanza.toString()}); + }); + Lightstring.Connection.prototype.on('out', function(stanza) { + Lightstring.console.log({dir: 'out', data: stanza.toString()}); + }); + } + if (document.readyState === 'complete') + return this.initView(); + + document.addEventListener('DOMContentLoaded', this.initView); + }, + initView: function() { + Lightstring.console.holder.forEach(function(log) { + Lightstring.console.log(log); + }); - document.getElementById('input').addEventListener('submit', function(e) { - e.preventDefault(); - Lightstring.console.send(this.elements['field'].value) - }); - document.getElementById('clear').addEventListener('click', function(e) { - Lightstring.console.entriesEl.innerHTML = ''; - }); - //FIXME allow xpath, xquery, E4X, whatever XML query syntax - document.getElementById('filter').addEventListener('input', function(e) { - Lightstring.console.filter(this.value); - }); - document.getElementById('input').addEventListener('keypress', function(e) { - if (e.keyCode === 13) { - if (e.shiftKey) { - e.preventDefault(); - var event = document.createEvent('Event'); - event.initEvent('submit', true, true); - this.dispatchEvent(event); + + var entriesEl = document.getElementById('entries'); + Console.entriesEl = entriesEl; + + document.getElementById('input').addEventListener('submit', function(e) { + e.preventDefault(); + Lightstring.console.send(this.elements['field'].value) + }); + document.getElementById('clear').addEventListener('click', function(e) { + Lightstring.console.entriesEl.innerHTML = ''; + }); + //FIXME allow xpath, xquery, E4X, whatever XML query syntax + document.getElementById('filter').addEventListener('input', function(e) { + Lightstring.console.filter(this.value); + }); + document.getElementById('input').addEventListener('keypress', function(e) { + if (e.keyCode === 13) { + if (e.shiftKey) { + e.preventDefault(); + var event = document.createEvent('Event'); + event.initEvent('submit', true, true); + this.dispatchEvent(event); + } } - } - }); - }); + }); + } + }; + + //Lightstring is defined in the parent window context + if (window.frameElement && window.parent.Lightstring) { + window.Lightstring = window.parent.Lightstring; + Lightstring.console = Console; + Lightstring.console.init(); + } + else { + //TODO: link to a doc? + console.error('You must embed this in a iframe.'); + } })(); \ No newline at end of file
--- a/console/console.xhtml +++ b/console/console.xhtml @@ -3,19 +3,23 @@ <head> <title>Lightstring Console</title> <meta charset="UTF-8"/> + <link type="text/css" rel="stylesheet" href="console.css"/> + <link rel="stylesheet" href="lib/highlight/styles/default.css"/> + <script type="application/javascript" src="../lib/EventEmitter.js"/> + <script type="application/javascript" src="../lib/require.js"/> <script type="application/javascript" src="console.js"/> - <script type="application/javascript" src="../lib/vkbeautify.0.97.00.beta.js"/> - <link type="text/css" rel="stylesheet" href="console.css"/> + <script type="application/javascript" src="lib/vkbeautify.0.97.00.beta.js"/> + <script type="application/javascript" src="lib/highlight/highlight.pack.js"/> </head> <body> - <div id="entries"/> + <form id="input"> + <textarea name="field" spellcheck="false"/> + <input type="submit" value="send"/> + </form> <div id="toolbar"> <button id="clear">Clear</button> <input type="search" id="filter" placeholder="Filter"/> </div> - <form id="input"> - <textarea name="field" spellcheck="false"/> - <input type="submit" value="send"/> - </form> + <div id="entries"/> </body> </html> \ No newline at end of file
new file mode 100644 index 0000000000000000000000000000000000000000..46bc7c82acf12b65383642eac82d6ebcb711a73f GIT binary patch literal 6148 zc%1E*%TB^T6o&s98!VAU-MQ@26^U<95ll$b1?-J-@mhm{lIX4v=mYowzK5PNzoraz z;R@9AC5Mlcb51)Q(&+#&t@-Exhya9ewslkzGFGs3O~NdC%rM0mS7;)u?xk!P#oRS8 zM2bt9z4H7$A?v1-;UJw1;Qk=T68rB97PY&$!7Z-kGo>@Be3VW@+{?E+%)AaSMF$DP z4%;|E7f0ye41IK#vrW%CUmZQkJVYC(;wBz2@+w}viiTG)#k{J{o_lpQxf2<lWn5!_ z4ED{-RTM?}eHf>3XT6u9D9Q#>JRf2@p>t=$-z^=KY9czO6FPS`%(HYrhjc{8bVBFO zd}tYNJ`B%nxI-}!9n;B=hO8+6hApS4SpPfU@BbA=`NNo?-EX(>wINucSZia6i_Zcq azX<SHz}#Xf-YXrC>4eUm^+iBY*2M=|<y#N{
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2006, Ivan Sagalaev +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of highlight.js nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/README.md @@ -0,0 +1,120 @@ +# Highlight.js + +Highlight.js highlights syntax in code examples on blogs, forums and, +in fact, on any web page. It's very easy to use because it works +automatically: finds blocks of code, detects a language, highlights it. + +Autodetection can be fine tuned when it fails by itself (see "Heuristics"). + + +## Basic usage + +Link the library and a stylesheet from your page and hook highlighting to +the page load event: + +```html +<link rel="stylesheet" href="styles/default.css"> +<script src="highlight.pack.js"></script> +<script>hljs.initHighlightingOnLoad();</script> +``` + +This will highlight all code on the page marked up as `<pre><code> .. </code></pre>`. +If you use different markup or need to apply highlighting dynamically, read +"Custom initialization" below. + +- You can download your own customized version of "highlight.pack.js" or + use the hosted one as described on the download page: + <http://softwaremaniacs.org/soft/highlight/en/download/> + +- Style themes are available in the download package or as hosted files. + To create a custom style for your site see the class reference in the file + [classref.txt][cr] from the downloaded package. + +[cr]: http://github.com/isagalaev/highlight.js/blob/master/classref.txt + + +## Tab replacement + +You can replace TAB ('\x09') characters used for indentation in your code +with some fixed number of spaces or with a `<span>` to give them special +styling: + +```html +<script type="text/javascript"> + hljs.tabReplace = ' '; // 4 spaces + // ... or + hljs.tabReplace = '<span class="indent">\t</span>'; + + hljs.initHighlightingOnLoad(); +</script> +``` + +## Custom initialization + +If you use different markup for code blocks you can initialize them manually +with `highlightBlock(code, tabReplace, useBR)` function. It takes a DOM element +containing the code to highlight and optionally a string with which to replace +TAB characters. + +Initialization using, for example, jQuery might look like this: + +```javascript +$(document).ready(function() { + $('pre code').each(function(i, e) {hljs.highlightBlock(e)}); +}); +``` + +You can use `highlightBlock` to highlight blocks dynamically inserted into +the page. Just make sure you don't do it twice for already highlighted +blocks. + +If your code container relies on `<br>` tags instead of line breaks (i.e. if +it's not `<pre>`) pass `true` into the third parameter of `highlightBlock` +to make highlight.js use `<br>` in the output: + +```javascript +$('div.code').each(function(i, e) {hljs.highlightBlock(e, null, true)}); +``` + + +## Heuristics + +Autodetection of a code's language is done using a simple heuristic: +the program tries to highlight a fragment with all available languages and +counts all syntactic structures that it finds along the way. The language +with greatest count wins. + +This means that in short fragments the probability of an error is high +(and it really happens sometimes). In this cases you can set the fragment's +language explicitly by assigning a class to the `<code>` element: + +```html +<pre><code class="html">...</code></pre> +``` + +You can use class names recommended in HTML5: "language-html", +"language-php". Classes also can be assigned to the `<pre>` element. + +To disable highlighting of a fragment altogether use "no-highlight" class: + +```html +<pre><code class="no-highlight">...</code></pre> +``` + + +## Export + +File export.html contains a little program that allows you to paste in a code +snippet and then copy and paste the resulting HTML code generated by the +highlighter. This is useful in situations when you can't use the script itself +on a site. + + +## Meta + +- Version: 7.0 +- URL: http://softwaremaniacs.org/soft/highlight/en/ +- Author: Ivan Sagalaev (<maniac@softwaremaniacs.org>) + +For the license terms see LICENSE files. +For the list of contributors see AUTHORS.en.txt file.
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/README.ru.md @@ -0,0 +1,125 @@ +# Highlight.js + +Highlight.js нужен для подсветки синтаксиса в примерах кода в блогах, +форумах и вообще на любых веб-страницах. Пользоваться им очень просто, +потому что работает он автоматически: сам находит блоки кода, сам +определяет язык, сам подсвечивает. + +Автоопределением языка можно управлять, когда оно не справляется само (см. +дальше "Эвристика"). + + +## Простое использование + +Подключите библиотеку и стиль на страницу и повесть вызов подсветки на +загрузку страницы: + +```html +<link rel="stylesheet" href="styles/default.css"> +<script src="highlight.pack.js"></script> +<script>hljs.initHighlightingOnLoad();</script> +``` + +Весь код на странице, обрамлённый в теги `<pre><code> .. </code></pre>` +будет автоматически подсвечен. Если вы используете другие теги или хотите +подсвечивать блоки кода динамически, читайте "Инициализацию вручную" ниже. + +- Вы можете скачать собственную версию "highlight.pack.js" или сослаться + на захостенный файл, как описано на странице загрузки: + <http://softwaremaniacs.org/soft/highlight/download/> + +- Стилевые темы можно найти в загруженном архиве или также использовать + захостенные. Чтобы сделать собственный стиль для своего сайта, вам + будет полезен справочник классов в файле [classref.txt][cr], который тоже + есть в архиве. + +[cr]: http://github.com/isagalaev/highlight.js/blob/master/classref.txt + + +## Замена TABов + +Также вы можете заменить символы TAB ('\x09'), используемые для отступов, на +фиксированное количество пробелов или на отдельный `<span>`, чтобы задать ему +какой-нибудь специальный стиль: + +```html +<script type="text/javascript"> + hljs.tabReplace = ' '; // 4 spaces + // ... or + hljs.tabReplace = '<span class="indent">\t</span>'; + + hljs.initHighlightingOnLoad(); +</script> +``` + + +## Инициализация вручную + +Если вы используете другие теги для блоков кода, вы можете инициализировать их +явно с помощью функции `highlightBlock(code, tabReplace, useBR)`. Она принимает +DOM-элемент с текстом расцвечиваемого кода и опционально - строчку для замены +символов TAB. + +Например с использованием jQuery код инициализации может выглядеть так: + +```javascript +$(document).ready(function() { + $('pre code').each(function(i, e) {hljs.highlightBlock(e)}); +}); +``` + +`highlightBlock` можно также использовать, чтобы подсветить блоки кода, +добавленные на страницу динамически. Только убедитесь, что вы не делаете этого +повторно для уже раскрашенных блоков. + +Если ваш блок кода использует `<br>` вместо переводов строки (т.е. если это не +`<pre>`), передайте `true` третьим параметром в `highlightBlock`: + +```javascript +$('div.code').each(function(i, e) {hljs.highlightBlock(e, null, true)}); +``` + + +## Эвристика + +Определение языка, на котором написан фрагмент, делается с помощью +довольно простой эвристики: программа пытается расцветить фрагмент всеми +языками подряд, и для каждого языка считает количество подошедших +синтаксически конструкций и ключевых слов. Для какого языка нашлось больше, +тот и выбирается. + +Это означает, что в коротких фрагментах высока вероятность ошибки, что +периодически и случается. Чтобы указать язык фрагмента явно, надо написать +его название в виде класса к элементу `<code>`: + +```html +<pre><code class="html">...</code></pre> +``` + +Можно использовать рекомендованные в HTML5 названия классов: +"language-html", "language-php". Также можно назначать классы на элемент +`<pre>`. + +Чтобы запретить расцветку фрагмента вообще, используется класс "no-highlight": + +```html +<pre><code class="no-highlight">...</code></pre> +``` + + +## Экспорт + +В файле export.html находится небольшая программка, которая показывает и дает +скопировать непосредственно HTML-код подсветки для любого заданного фрагмента кода. +Это может понадобится например на сайте, на котором нельзя подключить сам скрипт +highlight.js. + + +## Координаты + +- Версия: 7.0 +- URL: http://softwaremaniacs.org/soft/highlight/ +- Автор: Иван Сагалаев (<maniac@softwaremaniacs.org>) + +Лицензионное соглашение читайте в файле LICENSE. +Список соавторов читайте в файле AUTHORS.ru.txt
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/classref.txt @@ -0,0 +1,544 @@ +This is a full list of available classes corresponding to languages' +syntactic structures. The parentheses after language name contain identifiers +used as class names in `<code>` element. + +Python ("python"): + + keyword keyword + built_in built-in objects (None, False, True and Ellipsis) + number number + string string (of any type) + comment comment + decorator @-decorator for functions + function function header "def some_name(...):" + class class header "class SomeName(...):" + title name of a function or a class inside a header + params everything inside parentheses in a function's or class' header + +Python profiler results ("profile"): + + number number + string string + builtin builtin function entry + filename filename in an entry + summary profiling summary + header header of table of results + keyword column header + function function name in an entry (including parentheses) + title actual name of a function in an entry (excluding parentheses) + +Ruby ("ruby"): + + keyword keyword + string string + subst in-string substitution (#{...}) + comment comment + yardoctag YARD tag + function function header "def some_name(...):" + class class header "class SomeName(...):" + title name of a function or a class inside a header + parent name of a parent class + symbol symbol + instancevar instance variable + +Perl ("perl"): + + keyword keyword + comment comment + number number + string string + regexp regular expression + sub subroutine header (from "sub" till "{") + variable variable starting with "$", "%", "@" + operator operator + pod plain old doc + +PHP ("php"): + + keyword keyword + number number + string string (of any type) + comment comment + phpdoc phpdoc params in comments + variable variable starting with "$" + preprocessor preprocessor marks: "<?php" and "?>" + +Scala ("scala"): + + keyword keyword + number number + string string + comment comment + annotaion annotation + javadoc javadoc comment + javadoctag @-tag in javadoc + class class header + title class name inside a header + params everything in parentheses inside a class header + inheritance keywords "extends" and "with" inside class header + +Go language ("go"): + comment comment + string string constant + number number + keyword language keywords + constant true false nil iota + typename built-in plain types (int, string etc.) + built_in built-in functions + +XML ("xml"): + + tag any tag from "<" till ">" + comment comment + pi processing instruction (<? ... ?>) + cdata CDATA section + attribute attribute + value attribute's value + +HTML ("html"): + + keyword HTML tag + tag any tag from "<" till ">" + comment comment + doctype <!DOCTYPE ... > declaration + attribute tag's attribute with or without value + value attribute's value + +CSS ("css"): + + tag HTML tag in selectors + id #some_name in selectors + class .some_name in selectors + at_rule @-rule till first "{" or ";" + attr_selector attribute selector (square brackets in a[href^=http://]) + pseudo pseudo classes and elemens (:after, ::after etc.) + comment comment + rules everything from "{" till "}" + property property name inside a rule + value property value inside a rule, from ":" till ";" or + till the end of rule block + number number within a value + string string within a value + hexcolor hex color (#FFFFFF) within a value + function CSS function within a value + params everything between "(" and ")" within a function + important "!important" symbol + +Markdown ("markdown"): + + header header + bullet list bullet + emphasis emphasis + strong strong emphasis + blockquote blockquote + code code + horizontal_rule horizontal rule + link_label link label + link_url link url + +Django ("django"): + + keyword HTML tag in HTML, default tags and default filters in templates + tag any tag from "<" till ">" + comment comment + doctype <!DOCTYPE ... > declaration + attribute tag's attribute with or withou value + value attribute's value + template_tag template tag {% .. %} + variable template variable {{ .. }} + template_comment template comment, both {# .. #} and {% comment %} + filter filter from "|" till the next filter or the end of tag + argument filter argument + +JSON ("json"): + + number number + literal "true", "false" and "null" + string string value + attribute name of an object property + value value of an object property + +JavaScript ("javascript"): + + keyword keyword + comment comment + number number + literal special literal: "true", "false" and "null" + string string + regexp regular expression + function header of a function + title name of a function inside a header + params parentheses and everything inside them in a function's header + +CoffeeScript ("coffeescript"): + + keyword keyword + comment comment + number number + literal special literal: "true", "false" and "null" + string string + regexp regular expression + function header of a function + title name of a function variable inside a header + params parentheses and everything inside them in a function's header + +ActionScript ("actionscript"): + + comment comment + string string + number number + keyword keywords + literal literal + reserved reserved keyword + title name of declaration (package, class or function) + preprocessor preprocessor directive (import, include) + type type of returned value (for functions) + package package (named or not) + class class/interface + function function + param params of function + rest_arg rest argument of function + +VBScript ("vbscript"): + + keyword keyword + number number + string string + comment comment + built_in built-in function + +HTTP ("http"): + + request first line of a request + status first line of a response + attribute header name + string header value or query string in a request line + number status code + +Lua ("lua"): + + keyword keyword + number number + string string + comment comment + built_in built-in operator + function header of a function + title name of a function inside a header + params everything inside parentheses in a function's header + long_brackets multiline string in [=[ .. ]=] + +Delphi ("delphi"): + + keyword keyword + comment comment (of any type) + number number + string string + function header of a function, procedure, constructor and destructor + title name of a function, procedure, constructor or destructor + inside a header + params everything inside parentheses in a function's header + class class' body from "= class" till "end;" + +Java ("java"): + + keyword keyword + number number + string string + comment commment + annotaion annotation + javadoc javadoc comment + class class header from "class" till "{" + title class name inside a header + params everything in parentheses inside a class header + inheritance keywords "extends" and "implements" inside class header + +C++ ("cpp"): + + keyword keyword + number number + string string and character + comment comment + preprocessor preprocessor directive + stl_container instantiation of STL containers ("vector<...>") + +Objective C ("objectivec"): + keyword keyword + built_in Cocoa/Cocoa Touch constants and classes + number number + string string + comment comment + preprocessor preprocessor directive + class interface/implementation, protocol and forward class declaration + variable properties and struct accesors + +Vala ("vala"): + + keyword keyword + number number + string string + comment comment + class class definitions + title in class definition + constant ALL_UPPER_CASE + +C# ("cs"): + + keyword keyword + number number + string string + comment commment + xmlDocTag xmldoc tag ("///", "<!--", "-->", "<..>") + +D language ("d"): + + comment comment + string string constant + number number + keyword language keywords (including @attributes) + constant true false null + built_in built-in plain types (int, string etc.) + +RenderMan RSL ("rsl"): + + keyword keyword + number number + string string (including @"..") + comment comment + preprocessor preprocessor directive + shader sahder keywords + shading shading keywords + built_in built-in function + +RenderMan RIB ("rib"): + + keyword keyword + number number + string string + comment comment + commands command + +Maya Embedded Language ("mel"): + + keyword keyword + number number + string string + comment comment + variable variable + +SQL ("sql"): + + keyword keyword (mostly SQL'92 and SQL'99) + number number + string string (of any type: "..", '..', `..`) + comment comment + aggregate aggregate function + +Smalltalk ("smalltalk"): + + keyword keyword + number number + string string + comment commment + symbol symbol + array array + class name of a class + char char + localvars block of local variables + +Lisp ("lisp"): + + keyword keyword + number number + string string + comment commment + variable variable + literal b, t and nil + list non-quoted list + title first symbol in a non-quoted list + body remainder of the non-quoted list + quoted quoted list, both "(quote .. )" and "'(..)" + +Ini ("ini"): + + title title of a section + value value of a setting of any type + string string + number number + keyword boolean value keyword + +Apache ("apache"): + + keyword keyword + number number + comment commment + literal On and Off + sqbracket variables in rewrites "%{..}" + cbracket options in rewrites "[..]" + tag begin and end of a configuration section + +Nginx ("nginx"): + + title directive title + string string + number number + comment comment + built_in built-in constant + variable $-variable + regexp regexp + +Diff ("diff"): + + header file header + chunk chunk header within a file + addition added lines + deletion deleted lines + change changed lines + +DOS ("dos"): + + keyword keyword + flow batch control keyword + stream DOS special files ("con", "prn", ...) + winutils some commands (see dos.js specifically) + envvar environment variables + +Bash ("bash"): + + keyword keyword + string string + number number + comment comment + literal special literal: "true" и "false" + variable variable + shebang script interpreter header + +CMake ("cmake") + + keyword keyword + number number + string string + comment commment + envvar $-variable + +Axapta ("axapta"): + + keyword keyword + number number + string string + comment commment + class class header from "class" till "{" + title class name inside a header + params everything in parentheses inside a class header + inheritance keywords "extends" and "implements" inside class header + preprocessor preprocessor directive + +1C ("1c"): + + keyword keyword + number number + date date + string string + comment commment + function header of function or procudure + title function name inside a header + params everything in parentheses inside a function header + preprocessor preprocessor directive + +AVR assembler ("avrasm"): + + keyword keyword + built_in pre-defined register + number number + string string + comment commment + label label + preprocessor preprocessor directive + localvars substitution in .macro + +VHDL ("vhdl") + + keyword keyword + number number + string string + comment commment + literal signal logical value + typename typename + attribute signal attribute + +Parser3 ("parser3"): + + keyword keyword + number number + comment commment + variable variable starting with "$" + preprocessor preprocessor directive + title user-defined name starting with "@" + +TeX ("tex"): + + comment comment + number number + command command + parameter parameter + formula formula + special special symbol + +Haskell ("haskell"): + + keyword keyword + number number + string string + comment comment + class type classes and other data types + title function name + type type class name + typedef definition of types (type, newtype, data) + +Erlang ("erlang"): + + comment comment + string string + number number + keyword keyword + record_name record access (#record_name) + title name of declaration function + variable variable (starts with capital letter or with _) + pp.keywords module's attribute (-attribute) + function_name atom or atom:atom in case of function call + +Rust ("rust"): + + comment comment + string string + number number + keyword keyword + title name of declaration + preprocessor preprocessor directive + +Matlab ("matlab"): + + comment comment + string string + number number + keyword keyword + title function name + function function + param params of function + +R ("r"): + + comment comment + string string constant + number number + keyword language keywords (function, if) plus "structural" + functions (attach, require, setClass) + literal special literal: TRUE, FALSE, NULL, NA, etc. + +OpenGL Shading Language ("glsl"): + + comment comment + number number + preprocessor preprocessor directive + keyword keyword + built_in GLSL built-in functions and variables + literal true false
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/highlight.pack.js @@ -0,0 +1,1 @@ +var hljs=new function(){function m(p){return p.replace(/&/gm,"&").replace(/</gm,"<")}function f(r,q,p){return RegExp(q,"m"+(r.cI?"i":"")+(p?"g":""))}function b(r){for(var p=0;p<r.childNodes.length;p++){var q=r.childNodes[p];if(q.nodeName=="CODE"){return q}if(!(q.nodeType==3&&q.nodeValue.match(/\s+/))){break}}}function h(t,s){var p="";for(var r=0;r<t.childNodes.length;r++){if(t.childNodes[r].nodeType==3){var q=t.childNodes[r].nodeValue;if(s){q=q.replace(/\n/g,"")}p+=q}else{if(t.childNodes[r].nodeName=="BR"){p+="\n"}else{p+=h(t.childNodes[r])}}}if(/MSIE [678]/.test(navigator.userAgent)){p=p.replace(/\r/g,"\n")}return p}function a(s){var r=s.className.split(/\s+/);r=r.concat(s.parentNode.className.split(/\s+/));for(var q=0;q<r.length;q++){var p=r[q].replace(/^language-/,"");if(e[p]||p=="no-highlight"){return p}}}function c(r){var p=[];(function q(t,u){for(var s=0;s<t.childNodes.length;s++){if(t.childNodes[s].nodeType==3){u+=t.childNodes[s].nodeValue.length}else{if(t.childNodes[s].nodeName=="BR"){u+=1}else{if(t.childNodes[s].nodeType==1){p.push({event:"start",offset:u,node:t.childNodes[s]});u=q(t.childNodes[s],u);p.push({event:"stop",offset:u,node:t.childNodes[s]})}}}}return u})(r,0);return p}function k(y,w,x){var q=0;var z="";var s=[];function u(){if(y.length&&w.length){if(y[0].offset!=w[0].offset){return(y[0].offset<w[0].offset)?y:w}else{return w[0].event=="start"?y:w}}else{return y.length?y:w}}function t(D){var A="<"+D.nodeName.toLowerCase();for(var B=0;B<D.attributes.length;B++){var C=D.attributes[B];A+=" "+C.nodeName.toLowerCase();if(C.value!==undefined&&C.value!==false&&C.value!==null){A+='="'+m(C.value)+'"'}}return A+">"}while(y.length||w.length){var v=u().splice(0,1)[0];z+=m(x.substr(q,v.offset-q));q=v.offset;if(v.event=="start"){z+=t(v.node);s.push(v.node)}else{if(v.event=="stop"){var p,r=s.length;do{r--;p=s[r];z+=("</"+p.nodeName.toLowerCase()+">")}while(p!=v.node);s.splice(r,1);while(r<s.length){z+=t(s[r]);r++}}}}return z+m(x.substr(q))}function j(){function q(w,y,u){if(w.compiled){return}var s=[];if(w.k){var r={};function x(D,C){var A=C.split(" ");for(var z=0;z<A.length;z++){var B=A[z].split("|");r[B[0]]=[D,B[1]?Number(B[1]):1];s.push(B[0])}}w.lR=f(y,w.l||hljs.IR,true);if(typeof w.k=="string"){x("keyword",w.k)}else{for(var v in w.k){if(!w.k.hasOwnProperty(v)){continue}x(v,w.k[v])}}w.k=r}if(!u){if(w.bWK){w.b="\\b("+s.join("|")+")\\s"}w.bR=f(y,w.b?w.b:"\\B|\\b");if(!w.e&&!w.eW){w.e="\\B|\\b"}if(w.e){w.eR=f(y,w.e)}}if(w.i){w.iR=f(y,w.i)}if(w.r===undefined){w.r=1}if(!w.c){w.c=[]}w.compiled=true;for(var t=0;t<w.c.length;t++){if(w.c[t]=="self"){w.c[t]=w}q(w.c[t],y,false)}if(w.starts){q(w.starts,y,false)}}for(var p in e){if(!e.hasOwnProperty(p)){continue}q(e[p].dM,e[p],true)}}function d(D,E){if(!j.called){j();j.called=true}function s(r,O){for(var N=0;N<O.c.length;N++){var M=O.c[N].bR.exec(r);if(M&&M.index==0){return O.c[N]}}}function w(M,r){if(p[M].e&&p[M].eR.test(r)){return 1}if(p[M].eW){var N=w(M-1,r);return N?N+1:0}return 0}function x(r,M){return M.i&&M.iR.test(r)}function L(O,P){var N=[];for(var M=0;M<O.c.length;M++){N.push(O.c[M].b)}var r=p.length-1;do{if(p[r].e){N.push(p[r].e)}r--}while(p[r+1].eW);if(O.i){N.push(O.i)}return N.length?f(P,N.join("|"),true):null}function q(N,M){var O=p[p.length-1];if(O.t===undefined){O.t=L(O,F)}var r;if(O.t){O.t.lastIndex=M;r=O.t.exec(N)}return r?[N.substr(M,r.index-M),r[0],false]:[N.substr(M),"",true]}function A(O,r){var M=F.cI?r[0].toLowerCase():r[0];var N=O.k[M];if(N&&N instanceof Array){return N}return false}function G(M,Q){M=m(M);if(!Q.k){return M}var r="";var P=0;Q.lR.lastIndex=0;var N=Q.lR.exec(M);while(N){r+=M.substr(P,N.index-P);var O=A(Q,N);if(O){y+=O[1];r+='<span class="'+O[0]+'">'+N[0]+"</span>"}else{r+=N[0]}P=Q.lR.lastIndex;N=Q.lR.exec(M)}return r+M.substr(P)}function B(M,N){var r;if(N.sL==""){r=g(M)}else{r=d(N.sL,M)}if(N.r>0){y+=r.keyword_count;C+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function K(r,M){if(M.sL&&e[M.sL]||M.sL==""){return B(r,M)}else{return G(r,M)}}function J(N,r){var M=N.cN?'<span class="'+N.cN+'">':"";if(N.rB){z+=M;N.buffer=""}else{if(N.eB){z+=m(r)+M;N.buffer=""}else{z+=M;N.buffer=r}}p.push(N);C+=N.r}function H(O,N,R){var S=p[p.length-1];if(R){z+=K(S.buffer+O,S);return false}var Q=s(N,S);if(Q){z+=K(S.buffer+O,S);J(Q,N);return Q.rB}var M=w(p.length-1,N);if(M){var P=S.cN?"</span>":"";if(S.rE){z+=K(S.buffer+O,S)+P}else{if(S.eE){z+=K(S.buffer+O,S)+P+m(N)}else{z+=K(S.buffer+O+N,S)+P}}while(M>1){P=p[p.length-2].cN?"</span>":"";z+=P;M--;p.length--}var r=p[p.length-1];p.length--;p[p.length-1].buffer="";if(r.starts){J(r.starts,"")}return S.rE}if(x(N,S)){throw"Illegal"}}var F=e[D];var p=[F.dM];var C=0;var y=0;var z="";try{var t,v=0;F.dM.buffer="";do{t=q(E,v);var u=H(t[0],t[1],t[2]);v+=t[0].length;if(!u){v+=t[1].length}}while(!t[2]);return{r:C,keyword_count:y,value:z,language:D}}catch(I){if(I=="Illegal"){return{r:0,keyword_count:0,value:m(E)}}else{throw I}}}function g(t){var p={keyword_count:0,r:0,value:m(t)};var r=p;for(var q in e){if(!e.hasOwnProperty(q)){continue}var s=d(q,t);s.language=q;if(s.keyword_count+s.r>r.keyword_count+r.r){r=s}if(s.keyword_count+s.r>p.keyword_count+p.r){r=p;p=s}}if(r.language){p.second_best=r}return p}function i(r,q,p){if(q){r=r.replace(/^((<[^>]+>|\t)+)/gm,function(t,w,v,u){return w.replace(/\t/g,q)})}if(p){r=r.replace(/\n/g,"<br>")}return r}function n(t,w,r){var x=h(t,r);var v=a(t);var y,s;if(v=="no-highlight"){return}if(v){y=d(v,x)}else{y=g(x);v=y.language}var q=c(t);if(q.length){s=document.createElement("pre");s.innerHTML=y.value;y.value=k(q,c(s),x)}y.value=i(y.value,w,r);var u=t.className;if(!u.match("(\\s|^)(language-)?"+v+"(\\s|$)")){u=u?(u+" "+v):v}if(/MSIE [678]/.test(navigator.userAgent)&&t.tagName=="CODE"&&t.parentNode.tagName=="PRE"){s=t.parentNode;var p=document.createElement("div");p.innerHTML="<pre><code>"+y.value+"</code></pre>";t=p.firstChild.firstChild;p.firstChild.cN=s.cN;s.parentNode.replaceChild(p.firstChild,s)}else{t.innerHTML=y.value}t.className=u;t.result={language:v,kw:y.keyword_count,re:y.r};if(y.second_best){t.second_best={language:y.second_best.language,kw:y.second_best.keyword_count,re:y.second_best.r}}}function o(){if(o.called){return}o.called=true;var r=document.getElementsByTagName("pre");for(var p=0;p<r.length;p++){var q=b(r[p]);if(q){n(q,hljs.tabReplace)}}}function l(){if(window.addEventListener){window.addEventListener("DOMContentLoaded",o,false);window.addEventListener("load",o,false)}else{if(window.attachEvent){window.attachEvent("onload",o)}else{window.onload=o}}}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=n;this.initHighlighting=o;this.initHighlightingOnLoad=l;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="\\b(0[xX][a-fA-F0-9]+|(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.inherit=function(r,s){var p={};for(var q in r){p[q]=r[q]}if(s){for(var q in s){p[q]=s[q]}}return p}}();hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,dM:{c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:"[^ />]+"},b]}]}}}(hljs); \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/arta.css @@ -0,0 +1,153 @@ +/* +Date: 17.V.2011 +Author: pumbur <pumbur@pumbur.net> +*/ + +pre code +{ + display: block; padding: 0.5em; + background: #222; +} + +pre .profile .header *, +pre .ini .title, +pre .nginx .title +{ + color: #fff; +} + +pre .comment, +pre .javadoc, +pre .preprocessor, +pre .preprocessor .title, +pre .shebang, +pre .profile .summary, +pre .diff, +pre .pi, +pre .doctype, +pre .tag, +pre .template_comment, +pre .css .rules, +pre .tex .special +{ + color: #444; +} + +pre .string, +pre .symbol, +pre .diff .change, +pre .regexp, +pre .xml .attribute, +pre .smalltalk .char, +pre .xml .value, +pre .ini .value +{ + color: #ffcc33; +} + +pre .number, +pre .addition +{ + color: #00cc66; +} + +pre .built_in, +pre .literal, +pre .vhdl .typename, +pre .go .constant, +pre .go .typename, +pre .ini .keyword, +pre .lua .title, +pre .perl .variable, +pre .php .variable, +pre .mel .variable, +pre .django .variable, +pre .css .funtion, +pre .smalltalk .method, +pre .hexcolor, +pre .important, +pre .flow, +pre .inheritance, +pre .parser3 .variable +{ + color: #32AAEE; +} + +pre .keyword, +pre .tag .title, +pre .css .tag, +pre .css .class, +pre .css .id, +pre .css .pseudo, +pre .css .attr_selector, +pre .lisp .title, +pre .winutils, +pre .tex .command, +pre .request, +pre .status +{ + color: #6644aa; +} + +pre .title, +pre .ruby .constant, +pre .vala .constant, +pre .parent, +pre .deletion, +pre .template_tag, +pre .css .keyword, +pre .objectivec .class .id, +pre .smalltalk .class, +pre .lisp .keyword, +pre .apache .tag, +pre .nginx .variable, +pre .envvar, +pre .bash .variable, +pre .go .built_in, +pre .vbscript .built_in, +pre .lua .built_in, +pre .rsl .built_in, +pre .tail, +pre .avrasm .label, +pre .tex .formula, +pre .tex .formula * +{ + color: #bb1166; +} + +pre .yardoctag, +pre .phpdoc, +pre .profile .header, +pre .ini .title, +pre .apache .tag, +pre .parser3 .title +{ + font-weight: bold; +} + +pre .coffeescript .javascript, +pre .xml .javascript, +pre .xml .css, +pre .xml .cdata +{ + opacity: 0.6; +} + +pre code, +pre .javascript, +pre .css, +pre .xml, +pre .subst, +pre .diff .chunk, +pre .css .value, +pre .css .attribute, +pre .lisp .string, +pre .lisp .number, +pre .tail .params, +pre .container, +pre .haskell *, +pre .erlang *, +pre .erlang_repl * +{ + color: #aaa; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/ascetic.css @@ -0,0 +1,49 @@ +/* + +Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> + +*/ + +pre code { + display: block; padding: 0.5em; + background: white; color: black; +} + +pre .string, +pre .tag .value, +pre .filter .argument, +pre .addition, +pre .change, +pre .apache .tag, +pre .apache .cbracket, +pre .nginx .built_in, +pre .tex .formula { + color: #888; +} + +pre .comment, +pre .template_comment, +pre .shebang, +pre .doctype, +pre .pi, +pre .javadoc, +pre .deletion, +pre .apache .sqbracket { + color: #CCC; +} + +pre .keyword, +pre .tag .title, +pre .ini .title, +pre .lisp .title, +pre .http .title, +pre .nginx .title, +pre .css .tag, +pre .winutils, +pre .flow, +pre .apache .tag, +pre .tex .command, +pre .request, +pre .status { + font-weight: bold; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/brown_paper.css @@ -0,0 +1,104 @@ +/* + +Brown Paper style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net> + +*/ + +pre code { + display: block; padding: 0.5em; + background:#b7a68e url(./brown_papersq.png); +} + +pre .keyword, +pre .literal, +pre .change, +pre .winutils, +pre .flow, +pre .lisp .title, +pre .nginx .title, +pre .tex .special, +pre .request, +pre .status { + color:#005599; + font-weight:bold; +} + +pre code, +pre .ruby .subst, +pre .tag .keyword { + color: #363C69; +} + +pre .string, +pre .title, +pre .haskell .type, +pre .tag .value, +pre .css .rules .value, +pre .preprocessor, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .ruby .instancevar, +pre .ruby .class .parent, +pre .built_in, +pre .sql .aggregate, +pre .django .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .javadoc, +pre .ruby .string, +pre .django .filter .argument, +pre .smalltalk .localvars, +pre .smalltalk .array, +pre .attr_selector, +pre .pseudo, +pre .addition, +pre .stream, +pre .envvar, +pre .apache .tag, +pre .apache .cbracket, +pre .tex .number { + color: #2C009F; +} + +pre .comment, +pre .java .annotation, +pre .python .decorator, +pre .template_comment, +pre .pi, +pre .doctype, +pre .deletion, +pre .shebang, +pre .apache .sqbracket, +pre .nginx .built_in, +pre .tex .formula { + color: #802022; +} + +pre .keyword, +pre .literal, +pre .css .id, +pre .phpdoc, +pre .title, +pre .haskell .type, +pre .vbscript .built_in, +pre .sql .aggregate, +pre .rsl .built_in, +pre .smalltalk .class, +pre .diff .header, +pre .chunk, +pre .winutils, +pre .bash .variable, +pre .apache .tag, +pre .tex .command { + font-weight: bold; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.8; +}
new file mode 100644 index 0000000000000000000000000000000000000000..3813903dbf9fa7b1fb5bd11d9534c06667d9056f GIT binary patch literal 18198 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
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/dark.css @@ -0,0 +1,103 @@ +/* + +Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #444; +} + +pre .keyword, +pre .literal, +pre .change, +pre .winutils, +pre .flow, +pre .lisp .title, +pre .nginx .title, +pre .tex .special { + color: white; +} + +pre code, +pre .ruby .subst { + color: #DDD; +} + +pre .string, +pre .title, +pre .haskell .type, +pre .ini .title, +pre .tag .value, +pre .css .rules .value, +pre .preprocessor, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .ruby .instancevar, +pre .ruby .class .parent, +pre .built_in, +pre .sql .aggregate, +pre .django .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .javadoc, +pre .ruby .string, +pre .django .filter .argument, +pre .smalltalk .localvars, +pre .smalltalk .array, +pre .attr_selector, +pre .pseudo, +pre .addition, +pre .stream, +pre .envvar, +pre .apache .tag, +pre .apache .cbracket, +pre .tex .command, +pre .input_number { + color: #D88; +} + +pre .comment, +pre .java .annotation, +pre .python .decorator, +pre .template_comment, +pre .pi, +pre .doctype, +pre .deletion, +pre .shebang, +pre .apache .sqbracket, +pre .tex .formula { + color: #777; +} + +pre .keyword, +pre .literal, +pre .title, +pre .css .id, +pre .phpdoc, +pre .haskell .type, +pre .vbscript .built_in, +pre .sql .aggregate, +pre .rsl .built_in, +pre .smalltalk .class, +pre .diff .header, +pre .chunk, +pre .winutils, +pre .bash .variable, +pre .apache .tag, +pre .tex .special, +pre .request, +pre .status { + font-weight: bold; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.5; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/default.css @@ -0,0 +1,133 @@ +/* + +Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #F0F0F0; +} + +pre code, +pre .ruby .subst, +pre .tag .title, +pre .lisp .title, +pre .nginx .title { + color: black; +} + +pre .string, +pre .title, +pre .constant, +pre .parent, +pre .tag .value, +pre .rules .value, +pre .rules .value .number, +pre .preprocessor, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .instancevar, +pre .aggregate, +pre .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .addition, +pre .flow, +pre .stream, +pre .bash .variable, +pre .apache .tag, +pre .apache .cbracket, +pre .tex .command, +pre .tex .special, +pre .erlang_repl .function_or_atom, +pre .markdown .header { + color: #800; +} + +pre .comment, +pre .annotation, +pre .template_comment, +pre .diff .header, +pre .chunk, +pre .markdown .blockquote { + color: #888; +} + +pre .number, +pre .date, +pre .regexp, +pre .literal, +pre .smalltalk .symbol, +pre .smalltalk .char, +pre .go .constant, +pre .change, +pre .markdown .bullet, +pre .markdown .link_url { + color: #080; +} + +pre .label, +pre .javadoc, +pre .ruby .string, +pre .decorator, +pre .filter .argument, +pre .localvars, +pre .array, +pre .attr_selector, +pre .important, +pre .pseudo, +pre .pi, +pre .doctype, +pre .deletion, +pre .envvar, +pre .shebang, +pre .apache .sqbracket, +pre .nginx .built_in, +pre .tex .formula, +pre .erlang_repl .reserved, +pre .input_number, +pre .markdown .link_label, +pre .vhdl .attribute { + color: #88F +} + +pre .keyword, +pre .id, +pre .phpdoc, +pre .title, +pre .built_in, +pre .aggregate, +pre .css .tag, +pre .javadoctag, +pre .phpdoc, +pre .yardoctag, +pre .smalltalk .class, +pre .winutils, +pre .bash .variable, +pre .apache .tag, +pre .go .typename, +pre .tex .command, +pre .markdown .strong, +pre .request, +pre .status { + font-weight: bold; +} + +pre .markdown .emphasis { + font-style: italic; +} + +pre .nginx .built_in { + font-weight: normal; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.5; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/far.css @@ -0,0 +1,110 @@ +/* + +FAR Style (c) MajestiC <majestic2k@gmail.com> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #000080; +} + +pre code, +.ruby .subst { + color: #0FF; +} + +pre .string, +pre .ruby .string, +pre .haskell .type, +pre .tag .value, +pre .css .rules .value, +pre .css .rules .value .number, +pre .preprocessor, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .built_in, +pre .sql .aggregate, +pre .django .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .addition, +pre .apache .tag, +pre .apache .cbracket, +pre .tex .command { + color: #FF0; +} + +pre .keyword, +pre .css .id, +pre .title, +pre .haskell .type, +pre .vbscript .built_in, +pre .sql .aggregate, +pre .rsl .built_in, +pre .smalltalk .class, +pre .xml .tag .title, +pre .winutils, +pre .flow, +pre .change, +pre .envvar, +pre .bash .variable, +pre .tex .special { + color: #FFF; +} + +pre .comment, +pre .phpdoc, +pre .javadoc, +pre .java .annotation, +pre .template_comment, +pre .deletion, +pre .apache .sqbracket, +pre .tex .formula { + color: #888; +} + +pre .number, +pre .date, +pre .regexp, +pre .literal, +pre .smalltalk .symbol, +pre .smalltalk .char { + color: #0F0; +} + +pre .python .decorator, +pre .django .filter .argument, +pre .smalltalk .localvars, +pre .smalltalk .array, +pre .attr_selector, +pre .pseudo, +pre .xml .pi, +pre .diff .header, +pre .chunk, +pre .shebang, +pre .nginx .built_in, +pre .input_number { + color: #008080; +} + +pre .keyword, +pre .css .id, +pre .title, +pre .haskell .type, +pre .vbscript .built_in, +pre .sql .aggregate, +pre .rsl .built_in, +pre .smalltalk .class, +pre .winutils, +pre .flow, +pre .apache .tag, +pre .nginx .built_in, +pre .tex .command, +pre .tex .special, +pre .request, +pre .status { + font-weight: bold; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/github.css @@ -0,0 +1,133 @@ +/* + +github.com style (c) Vasily Polovnyov <vast@whiteants.net> + +*/ + +pre code { + display: block; padding: 0.5em; + color: #000; + background: #f8f8ff +} + +pre .comment, +pre .template_comment, +pre .diff .header, +pre .javadoc { + color: #998; + font-style: italic +} + +pre .keyword, +pre .css .rule .keyword, +pre .winutils, +pre .javascript .title, +pre .lisp .title, +pre .nginx .title, +pre .subst, +pre .request, +pre .status { + color: #000; + font-weight: bold +} + +pre .number, +pre .hexcolor { + color: #40a070 +} + +pre .string, +pre .tag .value, +pre .phpdoc, +pre .tex .formula { + color: #d14 +} + +pre .title, +pre .id { + color: #900; + font-weight: bold +} + +pre .javascript .title, +pre .lisp .title, +pre .subst { + font-weight: normal +} + +pre .class .title, +pre .haskell .type, +pre .vhdl .literal, +pre .tex .command { + color: #458; + font-weight: bold +} + +pre .tag, +pre .tag .title, +pre .rules .property, +pre .django .tag .keyword { + color: #000080; + font-weight: normal +} + +pre .attribute, +pre .variable, +pre .instancevar, +pre .lisp .body { + color: #008080 +} + +pre .regexp { + color: #009926 +} + +pre .class { + color: #458; + font-weight: bold +} + +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .lisp .keyword, +pre .tex .special, +pre .input_number { + color: #990073 +} + +pre .builtin, +pre .built_in, +pre .lisp .title { + color: #0086b3 +} + +pre .preprocessor, +pre .pi, +pre .doctype, +pre .shebang, +pre .cdata { + color: #999; + font-weight: bold +} + +pre .deletion { + background: #fdd +} + +pre .addition { + background: #dfd +} + +pre .diff .change { + background: #0086b3 +} + +pre .chunk { + color: #aaa +} + +pre .tex .formula { + opacity: 0.5; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/googlecode.css @@ -0,0 +1,143 @@ +/* + +Google Code style (c) Aahan Krish <geekpanth3r@gmail.com> + +*/ + +pre code { + display: block; padding: 0.5em; + background: white; color: black; +} + +pre .comment, +pre .template_comment, +pre .javadoc, +pre .comment * { + color: #800; +} + +pre .keyword, +pre .method, +pre .list .title, +pre .nginx .title, +pre .tag .title, +pre .setting .value, +pre .winutils, +pre .tex .command, +pre .http .title, +pre .request, +pre .status { + color: #008; +} + +pre .envvar, +pre .tex .special { + color: #660; +} + +pre .string, +pre .tag .value, +pre .cdata, +pre .filter .argument, +pre .attr_selector, +pre .apache .cbracket, +pre .date, +pre .regexp { + color: #080; +} + +pre .sub .identifier, +pre .pi, +pre .tag, +pre .tag .keyword, +pre .decorator, +pre .ini .title, +pre .shebang, +pre .input_number, +pre .hexcolor, +pre .rules .value, +pre .css .value .number, +pre .literal, +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .number, +pre .css .function { + color: #066; +} + +pre .class .title, +pre .haskell .type, +pre .smalltalk .class, +pre .javadoctag, +pre .yardoctag, +pre .phpdoc, +pre .typename, +pre .tag .attribute, +pre .doctype, +pre .class .id, +pre .built_in, +pre .setting, +pre .params, +pre .variable { + color: #606; +} + +pre .css .tag, +pre .rules .property, +pre .pseudo, +pre .subst { + color: #000; +} + +pre .css .class, pre .css .id { + color: #9B703F; +} + +pre .value .important { + color: #ff7700; + font-weight: bold; +} + +pre .rules .keyword { + color: #C5AF75; +} + +pre .annotation, +pre .apache .sqbracket, +pre .nginx .built_in { + color: #9B859D; +} + +pre .preprocessor, +pre .preprocessor * { + color: #444; +} + +pre .tex .formula { + background-color: #EEE; + font-style: italic; +} + +pre .diff .header, +pre .chunk { + color: #808080; + font-weight: bold; +} + +pre .diff .change { + background-color: #BCCFF9; +} + +pre .addition { + background-color: #BAEEBA; +} + +pre .deletion { + background-color: #FFC8BD; +} + +pre .comment .yardoctag { + font-weight: bold; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/idea.css @@ -0,0 +1,122 @@ +/* + +Intellij Idea-like styling (c) Vasily Polovnyov <vast@whiteants.net> + +*/ + +pre code { + display: block; padding: 0.5em; + color: #000; + background: #fff; +} + +pre .subst, +pre .title { + font-weight: normal; + color: #000; +} + +pre .comment, +pre .template_comment, +pre .javadoc, +pre .diff .header { + color: #808080; + font-style: italic; +} + +pre .annotation, +pre .decorator, +pre .preprocessor, +pre .doctype, +pre .pi, +pre .chunk, +pre .shebang, +pre .apache .cbracket, +pre .input_number, +pre .http .title { + color: #808000; +} + +pre .tag, +pre .pi { + background: #efefef; +} + +pre .tag .title, +pre .id, +pre .attr_selector, +pre .pseudo, +pre .literal, +pre .keyword, +pre .hexcolor, +pre .css .function, +pre .ini .title, +pre .css .class, +pre .list .title, +pre .nginx .title, +pre .tex .command, +pre .request, +pre .status { + font-weight: bold; + color: #000080; +} + +pre .attribute, +pre .rules .keyword, +pre .number, +pre .date, +pre .regexp, +pre .tex .special { + font-weight: bold; + color: #0000ff; +} + +pre .number, +pre .regexp { + font-weight: normal; +} + +pre .string, +pre .value, +pre .filter .argument, +pre .css .function .params, +pre .apache .tag { + color: #008000; + font-weight: bold; +} + +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .char, +pre .tex .formula { + color: #000; + background: #d0eded; + font-style: italic; +} + +pre .phpdoc, +pre .yardoctag, +pre .javadoctag { + text-decoration: underline; +} + +pre .variable, +pre .envvar, +pre .apache .sqbracket, +pre .nginx .built_in { + color: #660e7a; +} + +pre .addition { + background: #baeeba; +} + +pre .deletion { + background: #ffc8bd; +} + +pre .diff .change { + background: #bccff9; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/ir_black.css @@ -0,0 +1,99 @@ +/* + IR_Black style (c) Vasily Mikhailitchenko <vaskas@programica.ru> +*/ + +pre code { + display: block; padding: 0.5em; + background: #000; color: #f8f8f8; +} + +pre .shebang, +pre .comment, +pre .template_comment, +pre .javadoc { + color: #7c7c7c; +} + +pre .keyword, +pre .tag, +pre .tex .command, +pre .request, +pre .status { + color: #96CBFE; +} + +pre .sub .keyword, +pre .method, +pre .list .title, +pre .nginx .title { + color: #FFFFB6; +} + +pre .string, +pre .tag .value, +pre .cdata, +pre .filter .argument, +pre .attr_selector, +pre .apache .cbracket, +pre .date { + color: #A8FF60; +} + +pre .subst { + color: #DAEFA3; +} + +pre .regexp { + color: #E9C062; +} + +pre .title, +pre .sub .identifier, +pre .pi, +pre .decorator, +pre .tex .special, +pre .haskell .type, +pre .constant, +pre .smalltalk .class, +pre .javadoctag, +pre .yardoctag, +pre .phpdoc, +pre .nginx .built_in { + color: #FFFFB6; +} + +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .number, +pre .variable, +pre .vbscript, +pre .literal { + color: #C6C5FE; +} + +pre .css .tag { + color: #96CBFE; +} + +pre .css .rules .property, +pre .css .id { + color: #FFFFB6; +} + +pre .css .class { + color: #FFF; +} + +pre .hexcolor { + color: #C6C5FE; +} + +pre .number { + color:#FF73FD; +} + +pre .tex .formula { + opacity: 0.7; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/magula.css @@ -0,0 +1,120 @@ +/* +Description: Magula style for highligh.js +Author: Ruslan Keba <rukeba@gmail.com> +Website: http://rukeba.com/ +Version: 1.0 +Date: 2009-01-03 +Music: Aphex Twin / Xtal +*/ + +pre code { + display: block; padding: 0.5em; + background-color: #f4f4f4; +} + +pre code, +pre .ruby .subst, +pre .lisp .title { + color: black; +} + +pre .string, +pre .title, +pre .parent, +pre .tag .value, +pre .rules .value, +pre .rules .value .number, +pre .preprocessor, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .instancevar, +pre .aggregate, +pre .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .addition, +pre .flow, +pre .stream, +pre .bash .variable, +pre .apache .cbracket { + color: #050; +} + +pre .comment, +pre .annotation, +pre .template_comment, +pre .diff .header, +pre .chunk { + color: #777; +} + +pre .number, +pre .date, +pre .regexp, +pre .literal, +pre .smalltalk .symbol, +pre .smalltalk .char, +pre .change, +pre .tex .special { + color: #800; +} + +pre .label, +pre .javadoc, +pre .ruby .string, +pre .decorator, +pre .filter .argument, +pre .localvars, +pre .array, +pre .attr_selector, +pre .pseudo, +pre .pi, +pre .doctype, +pre .deletion, +pre .envvar, +pre .shebang, +pre .apache .sqbracket, +pre .nginx .built_in, +pre .tex .formula, +pre .input_number { + color: #00e; +} + +pre .keyword, +pre .id, +pre .phpdoc, +pre .title, +pre .built_in, +pre .aggregate, +pre .smalltalk .class, +pre .winutils, +pre .bash .variable, +pre .apache .tag, +pre .xml .tag, +pre .tex .command, +pre .request, +pre .status { + font-weight: bold; + color: navy; +} + +pre .nginx .built_in { + font-weight: normal; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.5; +} + +/* --- */ +pre .apache .tag { + font-weight: bold; + color: blue; +} +
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/monokai.css @@ -0,0 +1,116 @@ +/* +Monokai style - ported by Luigi Maselli - http://grigio.org +*/ + +pre code { + display: block; padding: 0.5em; + background: #272822; +} + +pre .params .identifier .keymethods { + color: #FD971F; +} + +pre .tag, +pre .tag .title, +pre .keyword, +pre .literal, +pre .change, +pre .winutils, +pre .flow, +pre .lisp .title, +pre .nginx .title, +pre .tex .special { + color: #F92672; +} + +pre code { + color: #DDD; +} + +pre code .constant { + color: #66D9EF; +} + +pre .class .title { + color: white; +} + +pre .attribute, +pre .symbol, +pre .value, +pre .regexp { + color: #BF79DB; +} + +pre .tag .value, +pre .string, +pre .ruby .subst, +pre .title, +pre .haskell .type, +pre .preprocessor, +pre .ruby .instancevar, +pre .ruby .class .parent, +pre .built_in, +pre .sql .aggregate, +pre .django .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .javadoc, +pre .ruby .string, +pre .django .filter .argument, +pre .smalltalk .localvars, +pre .smalltalk .array, +pre .attr_selector, +pre .pseudo, +pre .addition, +pre .stream, +pre .envvar, +pre .apache .tag, +pre .apache .cbracket, +pre .tex .command, +pre .input_number { + color: #A6E22E; +} + +pre .comment, +pre .java .annotation, +pre .python .decorator, +pre .template_comment, +pre .pi, +pre .doctype, +pre .deletion, +pre .shebang, +pre .apache .sqbracket, +pre .tex .formula { + color: #75715E; +} + +pre .keyword, +pre .literal, +pre .css .id, +pre .phpdoc, +pre .title, +pre .haskell .type, +pre .vbscript .built_in, +pre .sql .aggregate, +pre .rsl .built_in, +pre .smalltalk .class, +pre .diff .header, +pre .chunk, +pre .winutils, +pre .bash .variable, +pre .apache .tag, +pre .tex .special, +pre .request, +pre .status { + font-weight: bold; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.5; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/pojoaque.css @@ -0,0 +1,106 @@ +/* + +Pojoaque Style by Jason Tate +http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html +Based on Solarized Style from http://ethanschoonover.com/solarized + +*/ + +pre code { + display: block; padding: 0.5em; + color: #DCCF8F; + background: url(./pojoaque.jpg) repeat scroll left top #181914; +} + +pre .comment, +pre .template_comment, +pre .diff .header, +pre .doctype, +pre .lisp .string, +pre .javadoc { + color: #586e75; + font-style: italic; +} + +pre .keyword, +pre .css .rule .keyword, +pre .winutils, +pre .javascript .title, +pre .method, +pre .addition, +pre .css .tag, +pre .lisp .title, +pre .nginx .title { + color: #B64926; +} + +pre .number, +pre .command, +pre .string, +pre .tag .value, +pre .phpdoc, +pre .tex .formula, +pre .regexp, +pre .hexcolor { + color: #468966; +} + +pre .title, +pre .localvars, +pre .function .title, +pre .chunk, +pre .decorator, +pre .builtin, +pre .built_in, +pre .lisp .title, +pre .identifier, +pre .title .keymethods, +pre .id { + color: #FFB03B; +} + +pre .attribute, +pre .variable, +pre .instancevar, +pre .lisp .body, +pre .smalltalk .number, +pre .constant, +pre .class .title, +pre .parent, +pre .haskell .type { + color: #b58900; +} + +pre .css .attribute { + color: #b89859; +} + +pre .css .number,pre .css .hexcolor{ + color: #DCCF8F; +} + +pre .css .class { + color: #d3a60c; +} + +pre .preprocessor, +pre .pi, +pre .shebang, +pre .symbol, +pre .diff .change, +pre .special, +pre .keymethods, +pre .attr_selector, +pre .important, +pre .subst, +pre .cdata { + color: #cb4b16; +} + +pre .deletion { + color: #dc322f; +} + +pre .tex .formula { + background: #073642; +}
new file mode 100644 index 0000000000000000000000000000000000000000..9c07d4ab40b6d77e90ff69f0012bcd33b21d31c3 GIT binary patch literal 1186 zc${UDc}$aM9LJyM?fLeC7uq6K<PgZfb*nN{0*p&w2o5Zv+17T>0+TR=f*W)M(6Uft z<*+!%Sbzx%)UoN9KrL~yQY5Q^0b3M`fGv|L%LrEtp&aX8ShDl;{P%tGyONK?;;;ed zgt#Md03rZn;14+F0Txq`o?QeWAOZjcc(edmQ5lM~cR_{`PoQHGlmnDZCR4~Lg@Q7v z6e`n+j-qrYjKy+du`rCu!eL?<o6TjjF&=Nv9v;tsoBe+QQ7RRsp$r<0;lyAuoLsj{ zTsb=pI6PMj$Cc;C<8rw?HxCaU&%?vlcb~8C-whl_fKfpus3brifMAe-LB~CC96$)c zzkrngMF4RIkU&5v|M*yfn76$7Kuwe=zwDd7A7_@a{}utqBfua)d>8=(5x^{usVpo@ z%<O0V(0R$Fjrav$(c^D#5YP%nwB0AsAgVrGC6kE~t9v%t&$Ng_+k+M_7++}jvCu_{ zrxsu~qNu69>{_DIJvGQDmipfFu_!^0x=FU%*m?^|HR_Hp1U4yD&YK;>o=L$9#63ve zl0h_;-Pj1NOgHPo?x-Zj_Pj27JRFVfARf}^agLc3+OBnp6(l_#P;?4(FH$px5&M>l zbzDi0vPOWc+);nKM_6f~ji{N?VB>q${Kv5&g;1C?6&PPX%g+SfF~1BH_0F5FJW^j1 zYO#naA2w;kC^10cU=<rZqqqZPve+vp>7u09I}N0Fj0Vkj%|bKjtrFU_{=}ykT0ciC zFjs{4iMIqhH(V{^91GR2kZ!EX#mgGzAQI5#g?za#=iak(s^8q5yJ(|ZeI=iqUI}cX zdfUT?h*B0j?Q(xA9Z}Rmk#we9QXF5A{+xW_pqm@>>%IW1jmht1*%{4u4ef=Xt43-Q z#aE<(lnHuru3!B4hF6IEu3@om=}_;&EBYaV?&38)S(#^0vGuQs@I9MuEcLzbe7}Jr z?r6RBBvDz0XV{$hFv+tl>pA)M^kC}Hkt7EoPX?nYGx@9B4u8A$<+DU(>XMIzQ!N!x z&J>+J%CpE@JMaN;aW<i*RiAbfL_droN`YUp(V*@tw|co}&38YW(KOV4+d*v9yNu2M z#Qt5=dj@9jDIUGl5`BJ9(;F!k-Wm(GX|KkGM$)AF+U6fmCDggJP?9}ktje{3@$l$} zb+qf&Ba<*cKlUa3K3pGqlypYTiIIYkwY7kpM$;J4>c#zd(`9pID8PPmS7C{OG_YBF zd*VFq5KS7st1zb_p^p9Aw6VK)w*G0J$+OnI|JU!CHsq*@fAOk3a%`*7STJJKg{i-y z>A<#}{Y@1okOwJ~p%<>pg=WSFP4%;dtNTkoQ}JV@te^iB2^fTBi5WX4K{25O+fY8} z63r10X42!$vQmn~%-C_Wy2dIy_j%A{Bt5cAwQPE|N=3~+^<-G^_6ku_%2#~k=Y7o% l0tRuZ&q>x<ZIOIR$>v_g0m~b95c1)=*m${OsvbHf{s2lt#R>ob
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/school_book.css @@ -0,0 +1,111 @@ +/* + +School Book style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net> + +*/ + +pre code { + display: block; padding: 15px 0.5em 0.5em 30px; + font-size: 11px !important; + line-height:16px !important; +} + +pre{ + background:#f6f6ae url(./school_book.png); + border-top: solid 2px #d2e8b9; + border-bottom: solid 1px #d2e8b9; +} + +pre .keyword, +pre .literal, +pre .change, +pre .winutils, +pre .flow, +pre .lisp .title, +pre .nginx .title, +pre .tex .special { + color:#005599; + font-weight:bold; +} + +pre code, +pre .ruby .subst, +pre .tag .keyword { + color: #3E5915; +} + +pre .string, +pre .title, +pre .haskell .type, +pre .tag .value, +pre .css .rules .value, +pre .preprocessor, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .ruby .instancevar, +pre .ruby .class .parent, +pre .built_in, +pre .sql .aggregate, +pre .django .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .javadoc, +pre .ruby .string, +pre .django .filter .argument, +pre .smalltalk .localvars, +pre .smalltalk .array, +pre .attr_selector, +pre .pseudo, +pre .addition, +pre .stream, +pre .envvar, +pre .apache .tag, +pre .apache .cbracket, +pre .nginx .built_in, +pre .tex .command { + color: #2C009F; +} + +pre .comment, +pre .java .annotation, +pre .python .decorator, +pre .template_comment, +pre .pi, +pre .doctype, +pre .deletion, +pre .shebang, +pre .apache .sqbracket { + color: #E60415; +} + +pre .keyword, +pre .literal, +pre .css .id, +pre .phpdoc, +pre .title, +pre .haskell .type, +pre .vbscript .built_in, +pre .sql .aggregate, +pre .rsl .built_in, +pre .smalltalk .class, +pre .xml .tag .title, +pre .diff .header, +pre .chunk, +pre .winutils, +pre .bash .variable, +pre .apache .tag, +pre .tex .command, +pre .request, +pre .status { + font-weight: bold; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.5; +}
new file mode 100644 index 0000000000000000000000000000000000000000..956e9790a0e2c079b3d568348ff3accd1d9cac30 GIT binary patch literal 486 zc%17D@N?(olHy`uVBq!ia0y~yV7?7x3vjRjNjAS6Ga$v1?&#~tz_9*=IcwKTAYZb? zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|R4)r;B4q#jQ7Ycl#YS5MfK$ z?b^fh#qmaEhFDxvyThwfhdfkOPApt1lr{NA;Vr%uzxJuVIyzm(ed_<E=VqS`p8l-k zMtpHz{$@YRySeLE*Ya}$?Ok`{te)BVtcjm@Ca0ycGcY`ur8@;E%+Qhxa`84s1_p;4 zY-oJD$;|t~JbfJzX&@s}8dYuL@09ypybKHt8+3D+85j<5emea-{qg^n_vhYq-Ov6r z_pxa6`M&%2>%V>YHpeb6{N>kw8yDVvD4BRsdcT_1{f;>KrG<RYg?*FxeoI!%3V#n+ z<(NB9_wV(0sS&p&VkZ~NtUI}9>zq0>ui9%_wxQ1-Z?i1be12{{3vd6gZ!=H!#ca6t ztb1!<_v>BHJMQkQH=M-z>-UB$x4nJeu3kLBH0qb`R&V2D>(44m9n*NL9-R1R<DQ9W zJ@ehZtvdW(_j9<ZV62n)X-U)H`sXW7$N0rg-zCq;#^BzWmGa|icM>RMJYD@<);T3K F0RZDd%A^1Q
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/solarized_dark.css @@ -0,0 +1,90 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #002b36; color: #839496; +} + +pre .comment, +pre .template_comment, +pre .diff .header, +pre .doctype, +pre .pi, +pre .lisp .string, +pre .javadoc { + color: #586e75; + font-style: italic; +} + +pre .keyword, +pre .winutils, +pre .method, +pre .addition, +pre .css .tag, +pre .request, +pre .status, +pre .nginx .title { + color: #859900; +} + +pre .number, +pre .command, +pre .string, +pre .tag .value, +pre .phpdoc, +pre .tex .formula, +pre .regexp, +pre .hexcolor { + color: #2aa198; +} + +pre .title, +pre .localvars, +pre .chunk, +pre .decorator, +pre .builtin, +pre .built_in, +pre .identifier, +pre .title .keymethods, +pre .vhdl .literal, +pre .id { + color: #268bd2; +} + +pre .attribute, +pre .variable, +pre .instancevar, +pre .lisp .body, +pre .smalltalk .number, +pre .constant, +pre .class .title, +pre .parent, +pre .haskell .type { + color: #b58900; +} + +pre .preprocessor, +pre .preprocessor .keyword, +pre .shebang, +pre .symbol, +pre .diff .change, +pre .special, +pre .keymethods, +pre .attr_selector, +pre .important, +pre .subst, +pre .cdata { + color: #cb4b16; +} + +pre .deletion { + color: #dc322f; +} + +pre .tex .formula { + background: #073642; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/solarized_light.css @@ -0,0 +1,90 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #fdf6e3; color: #657b83; +} + +pre .comment, +pre .template_comment, +pre .diff .header, +pre .doctype, +pre .pi, +pre .lisp .string, +pre .javadoc { + color: #93a1a1; + font-style: italic; +} + +pre .keyword, +pre .winutils, +pre .method, +pre .addition, +pre .css .tag, +pre .request, +pre .status, +pre .nginx .title { + color: #859900; +} + +pre .number, +pre .command, +pre .string, +pre .tag .value, +pre .phpdoc, +pre .tex .formula, +pre .regexp, +pre .hexcolor { + color: #2aa198; +} + +pre .title, +pre .localvars, +pre .chunk, +pre .decorator, +pre .builtin, +pre .built_in, +pre .identifier, +pre .title .keymethods, +pre .vhdl .literal, +pre .id { + color: #268bd2; +} + +pre .attribute, +pre .variable, +pre .instancevar, +pre .lisp .body, +pre .smalltalk .number, +pre .constant, +pre .class .title, +pre .parent, +pre .haskell .type { + color: #b58900; +} + +pre .preprocessor, +pre .preprocessor .keyword, +pre .shebang, +pre .symbol, +pre .diff .change, +pre .special, +pre .keymethods, +pre .attr_selector, +pre .important, +pre .subst, +pre .cdata { + color: #cb4b16; +} + +pre .deletion { + color: #dc322f; +} + +pre .tex .formula { + background: #eee8d5; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/sunburst.css @@ -0,0 +1,149 @@ +/* + +Sunburst-like style (c) Vasily Polovnyov <vast@whiteants.net> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #000; color: #f8f8f8; +} + +pre .comment, +pre .template_comment, +pre .javadoc { + color: #aeaeae; + font-style: italic; +} + +pre .keyword, +pre .ruby .function .keyword, +pre .request, +pre .status, +pre .nginx .title { + color: #E28964; +} + +pre .function .keyword, +pre .sub .keyword, +pre .method, +pre .list .title { + color: #99CF50; +} + +pre .string, +pre .tag .value, +pre .cdata, +pre .filter .argument, +pre .attr_selector, +pre .apache .cbracket, +pre .date, +pre .tex .command { + color: #65B042; +} + +pre .subst { + color: #DAEFA3; +} + +pre .regexp { + color: #E9C062; +} + +pre .title, +pre .sub .identifier, +pre .pi, +pre .tag, +pre .tag .keyword, +pre .decorator, +pre .shebang, +pre .input_number { + color: #89BDFF; +} + +pre .class .title, +pre .haskell .type, +pre .smalltalk .class, +pre .javadoctag, +pre .yardoctag, +pre .phpdoc { + text-decoration: underline; +} + +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .number { + color: #3387CC; +} + +pre .params, +pre .variable { + color: #3E87E3; +} + +pre .css .tag, +pre .rules .property, +pre .pseudo, +pre .tex .special { + color: #CDA869; +} + +pre .css .class { + color: #9B703F; +} + +pre .rules .keyword { + color: #C5AF75; +} + +pre .rules .value { + color: #CF6A4C; +} + +pre .css .id { + color: #8B98AB; +} + +pre .annotation, +pre .apache .sqbracket, +pre .nginx .built_in { + color: #9B859D; +} + +pre .preprocessor { + color: #8996A8; +} + +pre .hexcolor, +pre .css .value .number { + color: #DD7B3B; +} + +pre .css .function { + color: #DAD085; +} + +pre .diff .header, +pre .chunk, +pre .tex .formula { + background-color: #0E2231; + color: #F8F8F8; + font-style: italic; +} + +pre .diff .change { + background-color: #4A410D; + color: #F8F8F8; +} + +pre .addition { + background-color: #253B22; + color: #F8F8F8; +} + +pre .deletion { + background-color: #420E09; + color: #F8F8F8; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/vs.css @@ -0,0 +1,85 @@ +/* + +Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name> + +*/ +pre code { + display: block; padding: 0.5em; +} + +pre .comment, +pre .annotation, +pre .template_comment, +pre .diff .header, +pre .chunk, +pre .apache .cbracket { + color: rgb(0, 128, 0); +} + +pre .keyword, +pre .id, +pre .built_in, +pre .smalltalk .class, +pre .winutils, +pre .bash .variable, +pre .tex .command, +pre .request, +pre .status, +pre .nginx .title { + color: rgb(0, 0, 255); +} + +pre .string, +pre .title, +pre .parent, +pre .tag .value, +pre .rules .value, +pre .rules .value .number, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .instancevar, +pre .aggregate, +pre .template_tag, +pre .django .variable, +pre .addition, +pre .flow, +pre .stream, +pre .apache .tag, +pre .date, +pre .tex .formula { + color: rgb(163, 21, 21); +} + +pre .ruby .string, +pre .decorator, +pre .filter .argument, +pre .localvars, +pre .array, +pre .attr_selector, +pre .pseudo, +pre .pi, +pre .doctype, +pre .deletion, +pre .envvar, +pre .shebang, +pre .preprocessor, +pre .userType, +pre .apache .sqbracket, +pre .nginx .built_in, +pre .tex .special, +pre .input_number { + color: rgb(43, 145, 175); +} + +pre .phpdoc, +pre .javadoc, +pre .xmlDocTag { + color: rgb(128, 128, 128); +} + +pre .vhdl .typename { font-weight: bold; } +pre .vhdl .string { color: #666666; } +pre .vhdl .literal { color: rgb(163, 21, 21); } +pre .vhdl .attribute { color: #00B0E8; }
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/xcode.css @@ -0,0 +1,153 @@ +/* + +XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com> + +*/ + +pre code { + display: block; padding: 0.5em; + background: #fff; color: black; +} + +pre .comment, +pre .template_comment, +pre .javadoc, +pre .comment * { + color: rgb(0,106,0); +} + +pre .keyword, +pre .literal, +pre .nginx .title { + color: rgb(170,13,145); +} +pre .method, +pre .list .title, +pre .tag .title, +pre .setting .value, +pre .winutils, +pre .tex .command, +pre .http .title, +pre .request, +pre .status { + color: #008; +} + +pre .envvar, +pre .tex .special { + color: #660; +} + +pre .string { + color: rgb(196,26,22); +} +pre .tag .value, +pre .cdata, +pre .filter .argument, +pre .attr_selector, +pre .apache .cbracket, +pre .date, +pre .regexp { + color: #080; +} + +pre .sub .identifier, +pre .pi, +pre .tag, +pre .tag .keyword, +pre .decorator, +pre .ini .title, +pre .shebang, +pre .input_number, +pre .hexcolor, +pre .rules .value, +pre .css .value .number, +pre .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .number, +pre .css .function { + color: rgb(28,0,207); +} + +pre .class .title, +pre .haskell .type, +pre .smalltalk .class, +pre .javadoctag, +pre .yardoctag, +pre .phpdoc, +pre .typename, +pre .tag .attribute, +pre .doctype, +pre .class .id, +pre .built_in, +pre .setting, +pre .params { + color: rgb(92,38,153); +} + +pre .variable { + color: rgb(63,110,116); +} +pre .css .tag, +pre .rules .property, +pre .pseudo, +pre .subst { + color: #000; +} + +pre .css .class, pre .css .id { + color: #9B703F; +} + +pre .value .important { + color: #ff7700; + font-weight: bold; +} + +pre .rules .keyword { + color: #C5AF75; +} + +pre .annotation, +pre .apache .sqbracket, +pre .nginx .built_in { + color: #9B859D; +} + +pre .preprocessor, +pre .preprocessor * { + color: rgb(100,56,32); +} + +pre .tex .formula { + background-color: #EEE; + font-style: italic; +} + +pre .diff .header, +pre .chunk { + color: #808080; + font-weight: bold; +} + +pre .diff .change { + background-color: #BCCFF9; +} + +pre .addition { + background-color: #BAEEBA; +} + +pre .deletion { + background-color: #FFC8BD; +} + +pre .comment .yardoctag { + font-weight: bold; +} + +pre .method .id { + color: #000; +}
new file mode 100644 --- /dev/null +++ b/console/lib/highlight/styles/zenburn.css @@ -0,0 +1,115 @@ +/* + +Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru> +based on dark.css by Ivan Sagalaev + +*/ + +pre code { + display: block; padding: 0.5em; + background: #3F3F3F; + color: #DCDCDC; +} + +pre .keyword, +pre .tag, +pre .css .class, +pre .css .id, +pre .lisp .title, +pre .nginx .title, +pre .request, +pre .status { + color: #E3CEAB; +} + +pre .django .template_tag, +pre .django .variable, +pre .django .filter .argument { + color: #DCDCDC; +} + +pre .number, +pre .date { + color: #8CD0D3; +} + +pre .dos .envvar, +pre .dos .stream, +pre .variable, +pre .apache .sqbracket { + color: #EFDCBC; +} + +pre .dos .flow, +pre .diff .change, +pre .python .exception, +pre .python .built_in, +pre .literal, +pre .tex .special { + color: #EFEFAF; +} + +pre .diff .chunk, +pre .ruby .subst { + color: #8F8F8F; +} + +pre .dos .keyword, +pre .python .decorator, +pre .title, +pre .haskell .type, +pre .diff .header, +pre .ruby .class .parent, +pre .apache .tag, +pre .nginx .built_in, +pre .tex .command, +pre .input_number { + color: #efef8f; +} + +pre .dos .winutils, +pre .ruby .symbol, +pre .ruby .symbol .string, +pre .ruby .symbol .keyword, +pre .ruby .symbol .keymethods, +pre .ruby .string, +pre .ruby .instancevar { + color: #DCA3A3; +} + +pre .diff .deletion, +pre .string, +pre .tag .value, +pre .preprocessor, +pre .built_in, +pre .sql .aggregate, +pre .javadoc, +pre .smalltalk .class, +pre .smalltalk .localvars, +pre .smalltalk .array, +pre .css .rules .value, +pre .attr_selector, +pre .pseudo, +pre .apache .cbracket, +pre .tex .formula { + color: #CC9393; +} + +pre .shebang, +pre .diff .addition, +pre .comment, +pre .java .annotation, +pre .template_comment, +pre .pi, +pre .doctype { + color: #7F9F7F; +} + +pre .coffeescript .javascript, +pre .xml .css, +pre .xml .javascript, +pre .xml .vbscript, +pre .tex .formula { + opacity: 0.5; +} +
--- a/jid.js +++ b/jid.js @@ -16,14 +16,28 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +//https://tools.ietf.org/html/rfc6122 + +(function() { + + + if (typeof define !== 'undefined') { + define(function() { + //return an object to define the "my/shirt" module. + return JID; + }); +} +else { + Lightstring.JID = JID; +} /** * @constructor Creates a new JID object. * @param {String} [aJID] The host, bare or full JID. * @memberOf Lightstring */ -Lightstring.JID = function(aJID) { - this.node = null; +var JID = function(aJID) { + this.local = null; this.domain = null; this.resource = null; @@ -33,7 +47,7 @@ Lightstring.JID = function(aJID) { //TODO: use a stringprep library to validate the input. }; -Lightstring.JID.prototype = { +JID.prototype = { toString: function() { return this.full; }, @@ -42,7 +56,7 @@ Lightstring.JID.prototype = { if (!(aJID instanceof Lightstring.JID)) aJID = new Lightstring.JID(aJID); - return (this.node === aJID.node && + return (this.local === aJID.local && this.domain === aJID.domain && this.resource === aJID.resource) }, @@ -51,8 +65,8 @@ Lightstring.JID.prototype = { if (!this.domain) return null; - if (this.node) - return this.node + '@' + this.domain; + if (this.local) + return this.local + '@' + this.domain; return this.domain; }, @@ -67,10 +81,10 @@ Lightstring.JID.prototype = { s = aJID.indexOf('@'); if (s == -1) { - this.node = null; + this.local = null; this.domain = aJID; } else { - this.node = aJID.substring(0, s); + this.local = aJID.substring(0, s); this.domain = aJID.substring(s+1); } }, @@ -81,8 +95,8 @@ Lightstring.JID.prototype = { var full = this.domain; - if (this.node) - full = this.node + '@' + full; + if (this.local) + full = this.local + '@' + full; if (this.resource) full = full + '/' + this.resource; @@ -105,11 +119,13 @@ Lightstring.JID.prototype = { s = aJID.indexOf('@'); if (s == -1) { - this.node = null; + this.local = null; this.domain = aJID; } else { - this.node = aJID.substring(0, s); + this.local = aJID.substring(0, s); this.domain = aJID.substring(s+1); } } }; +})(); +
new file mode 100644 --- /dev/null +++ b/lib/require.js @@ -0,0 +1,35 @@ +/* + RequireJS 2.0.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details +*/ +var requirejs,require,define; +(function(Z){function w(b){return J.call(b)==="[object Function]"}function G(b){return J.call(b)==="[object Array]"}function q(b,d){if(b){var f;for(f=0;f<b.length;f+=1)if(b[f]&&d(b[f],f,b))break}}function N(b,d){if(b){var f;for(f=b.length-1;f>-1;f-=1)if(b[f]&&d(b[f],f,b))break}}function x(b,d){for(var f in b)if(b.hasOwnProperty(f)&&d(b[f],f))break}function K(b,d,f,g){d&&x(d,function(d,k){if(f||!b.hasOwnProperty(k))g&&typeof d!=="string"?(b[k]||(b[k]={}),K(b[k],d,f,g)):b[k]=d});return b}function s(b, +d){return function(){return d.apply(b,arguments)}}function $(b){if(!b)return b;var d=Z;q(b.split("."),function(b){d=d[b]});return d}function aa(b,d,f){return function(){var g=ga.call(arguments,0),e;if(f&&w(e=g[g.length-1]))e.__requireJsBuild=!0;g.push(d);return b.apply(null,g)}}function ba(b,d,f){q([["toUrl"],["undef"],["defined","requireDefined"],["specified","requireSpecified"]],function(g){var e=g[1]||g[0];b[g[0]]=d?aa(d[e],f):function(){var b=t[O];return b[e].apply(b,arguments)}})}function H(b, +d,f,g){d=Error(d+"\nhttp://requirejs.org/docs/errors.html#"+b);d.requireType=b;d.requireModules=g;if(f)d.originalError=f;return d}function ha(){if(I&&I.readyState==="interactive")return I;N(document.getElementsByTagName("script"),function(b){if(b.readyState==="interactive")return I=b});return I}var ia=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ja=/require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,ca=/\.js$/,ka=/^\.\//,J=Object.prototype.toString,y=Array.prototype,ga=y.slice,la=y.splice,u=!!(typeof window!== +"undefined"&&navigator&&document),da=!u&&typeof importScripts!=="undefined",ma=u&&navigator.platform==="PLAYSTATION 3"?/^complete$/:/^(complete|loaded)$/,O="_",S=typeof opera!=="undefined"&&opera.toString()==="[object Opera]",t={},p={},P=[],L=!1,k,v,C,z,D,I,E,ea,fa;if(typeof define==="undefined"){if(typeof requirejs!=="undefined"){if(w(requirejs))return;p=requirejs;requirejs=void 0}typeof require!=="undefined"&&!w(require)&&(p=require,require=void 0);k=requirejs=function(b,d,f,g){var e=O,r;!G(b)&& +typeof b!=="string"&&(r=b,G(d)?(b=d,d=f,f=g):b=[]);if(r&&r.context)e=r.context;(g=t[e])||(g=t[e]=k.s.newContext(e));r&&g.configure(r);return g.require(b,d,f)};k.config=function(b){return k(b)};require||(require=k);k.version="2.0.2";k.jsExtRegExp=/^\/|:|\?|\.js$/;k.isBrowser=u;y=k.s={contexts:t,newContext:function(b){function d(a,c,l){var A=c&&c.split("/"),b=m.map,i=b&&b["*"],h,d,f,e;if(a&&a.charAt(0)===".")if(c){A=m.pkgs[c]?[c]:A.slice(0,A.length-1);c=a=A.concat(a.split("/"));for(h=0;c[h];h+=1)if(d= +c[h],d===".")c.splice(h,1),h-=1;else if(d==="..")if(h===1&&(c[2]===".."||c[0]===".."))break;else h>0&&(c.splice(h-1,2),h-=2);h=m.pkgs[c=a[0]];a=a.join("/");h&&a===c+"/"+h.main&&(a=c)}else a.indexOf("./")===0&&(a=a.substring(2));if(l&&(A||i)&&b){c=a.split("/");for(h=c.length;h>0;h-=1){f=c.slice(0,h).join("/");if(A)for(d=A.length;d>0;d-=1)if(l=b[A.slice(0,d).join("/")])if(l=l[f]){e=l;break}!e&&i&&i[f]&&(e=i[f]);if(e){c.splice(0,h,e);a=c.join("/");break}}}return a}function f(a){u&&q(document.getElementsByTagName("script"), +function(c){if(c.getAttribute("data-requiremodule")===a&&c.getAttribute("data-requirecontext")===j.contextName)return c.parentNode.removeChild(c),!0})}function g(a){var c=m.paths[a];if(c&&G(c)&&c.length>1)return f(a),c.shift(),j.undef(a),j.require([a]),!0}function e(a,c,l,b){var T=a?a.indexOf("!"):-1,i=null,h=c?c.name:null,f=a,e=!0,g="",k,m;a||(e=!1,a="_@r"+(N+=1));T!==-1&&(i=a.substring(0,T),a=a.substring(T+1,a.length));i&&(i=d(i,h,b),m=o[i]);a&&(i?g=m&&m.normalize?m.normalize(a,function(a){return d(a, +h,b)}):d(a,h,b):(g=d(a,h,b),k=j.nameToUrl(a,null,c)));a=i&&!m&&!l?"_unnormalized"+(O+=1):"";return{prefix:i,name:g,parentMap:c,unnormalized:!!a,url:k,originalName:f,isDefine:e,id:(i?i+"!"+g:g)+a}}function r(a){var c=a.id,l=n[c];l||(l=n[c]=new j.Module(a));return l}function p(a,c,l){var b=a.id,d=n[b];if(o.hasOwnProperty(b)&&(!d||d.defineEmitComplete))c==="defined"&&l(o[b]);else r(a).on(c,l)}function B(a,c){var l=a.requireModules,b=!1;if(c)c(a);else if(q(l,function(c){if(c=n[c])c.error=a,c.events.error&& +(b=!0,c.emit("error",a))}),!b)k.onError(a)}function v(){P.length&&(la.apply(F,[F.length-1,0].concat(P)),P=[])}function t(a,c,l){a=a&&a.map;c=aa(l||j.require,a,c);ba(c,j,a);c.isBrowser=u;return c}function y(a){delete n[a];q(M,function(c,l){if(c.map.id===a)return M.splice(l,1),c.defined||(j.waitCount-=1),!0})}function z(a,c){var l=a.map.id,b=a.depMaps,d;if(a.inited){if(c[l])return a;c[l]=!0;q(b,function(a){if(a=n[a.id])return!a.inited||!a.enabled?(d=null,delete c[l],!0):d=z(a,K({},c))});return d}}function C(a, +c,b){var d=a.map.id,e=a.depMaps;if(a.inited&&a.map.isDefine){if(c[d])return o[d];c[d]=a;q(e,function(i){var i=i.id,h=n[i];!Q[i]&&h&&(!h.inited||!h.enabled?b[d]=!0:(h=C(h,c,b),b[i]||a.defineDepById(i,h)))});a.check(!0);return o[d]}}function D(a){a.check()}function E(){var a=m.waitSeconds*1E3,c=a&&j.startTime+a<(new Date).getTime(),b=[],d=!1,e=!0,i,h,k;if(!U){U=!0;x(n,function(a){i=a.map;h=i.id;if(a.enabled&&!a.error)if(!a.inited&&c)g(h)?d=k=!0:(b.push(h),f(h));else if(!a.inited&&a.fetched&&i.isDefine&& +(d=!0,!i.prefix))return e=!1});if(c&&b.length)return a=H("timeout","Load timeout for modules: "+b,null,b),a.contextName=j.contextName,B(a);e&&(q(M,function(a){if(!a.defined){var a=z(a,{}),c={};a&&(C(a,c,{}),x(c,D))}}),x(n,D));if((!c||k)&&d)if((u||da)&&!V)V=setTimeout(function(){V=0;E()},50);U=!1}}function W(a){r(e(a[0],null,!0)).init(a[1],a[2])}function J(a){var a=a.currentTarget||a.srcElement,c=j.onScriptLoad;a.detachEvent&&!S?a.detachEvent("onreadystatechange",c):a.removeEventListener("load",c, +!1);c=j.onScriptError;a.detachEvent&&!S||a.removeEventListener("error",c,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}var m={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},shim:{}},n={},X={},F=[],o={},R={},N=1,O=1,M=[],U,Y,j,Q,V;Q={require:function(a){return t(a)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports=o[a.map.id]={}},module:function(a){return a.module={id:a.map.id,uri:a.map.url,config:function(){return m.config&&m.config[a.map.id]||{}},exports:o[a.map.id]}}}; +Y=function(a){this.events=X[a.id]||{};this.map=a;this.shim=m.shim[a.id];this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Y.prototype={init:function(a,c,b,d){d=d||{};if(!this.inited){this.factory=c;if(b)this.on("error",b);else this.events.error&&(b=s(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.depMaps.rjsSkipMap=a.rjsSkipMap;this.errback=b;this.inited=!0;this.ignore=d.ignore;d.enabled||this.enabled?this.enable():this.check()}},defineDepById:function(a, +c){var b;q(this.depMaps,function(c,d){if(c.id===a)return b=d,!0});return this.defineDep(b,c)},defineDep:function(a,c){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=c)},fetch:function(){if(!this.fetched){this.fetched=!0;j.startTime=(new Date).getTime();var a=this.map;if(this.shim)t(this,!0)(this.shim.deps||[],s(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;R[a]|| +(R[a]=!0,j.load(this.map.id,a))},check:function(a){if(this.enabled&&!this.enabling){var c=this.map.id,b=this.depExports,d=this.exports,e=this.factory,i;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(this.depCount<1&&!this.defined){if(w(e)){if(this.events.error)try{d=j.execCb(c,e,b,d)}catch(h){i=h}else d=j.execCb(c,e,b,d);if(this.map.isDefine)if((b=this.module)&&b.exports!==void 0&&b.exports!==this.exports)d=b.exports;else if(d===void 0&&this.usingExports)d= +this.exports;if(i)return i.requireMap=this.map,i.requireModules=[this.map.id],i.requireType="define",B(this.error=i)}else d=e;this.exports=d;if(this.map.isDefine&&!this.ignore&&(o[c]=d,k.onResourceLoad))k.onResourceLoad(j,this.map,this.depMaps);delete n[c];this.defined=!0;j.waitCount-=1;j.waitCount===0&&(M=[])}this.defining=!1;if(!a&&this.defined&&!this.defineEmitted)this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0}}else this.fetch()}},callPlugin:function(){var a= +this.map,c=a.id,b=e(a.prefix,null,!1,!0);p(b,"defined",s(this,function(b){var l=this.map.name,i=this.map.parentMap?this.map.parentMap.name:null;if(this.map.unnormalized){if(b.normalize&&(l=b.normalize(l,function(a){return d(a,i,!0)})||""),b=e(a.prefix+"!"+l,this.map.parentMap,!1,!0),p(b,"defined",s(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),b=n[b.id]){if(this.events.error)b.on("error",s(this,function(a){this.emit("error",a)}));b.enable()}}else l=s(this,function(a){this.init([], +function(){return a},null,{enabled:!0})}),l.error=s(this,function(a){this.inited=!0;this.error=a;a.requireModules=[c];x(n,function(a){a.map.id.indexOf(c+"_unnormalized")===0&&y(a.map.id)});B(a)}),l.fromText=function(a,c){var b=L;b&&(L=!1);r(e(a));k.exec(c);b&&(L=!0);j.completeLoad(a)},b.load(a.name,t(a.parentMap,!0,function(a,c){a.rjsSkipMap=!0;return j.require(a,c)}),l,m)}));j.enable(b,this);this.pluginMaps[b.id]=b},enable:function(){this.enabled=!0;if(!this.waitPushed)M.push(this),j.waitCount+= +1,this.waitPushed=!0;this.enabling=!0;q(this.depMaps,s(this,function(a,c){var b,d;if(typeof a==="string"){a=e(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.depMaps.rjsSkipMap);this.depMaps[c]=a;if(b=Q[a.id]){this.depExports[c]=b(this);return}this.depCount+=1;p(a,"defined",s(this,function(a){this.defineDep(c,a);this.check()}));this.errback&&p(a,"error",this.errback)}b=a.id;d=n[b];!Q[b]&&d&&!d.enabled&&j.enable(a,this)}));x(this.pluginMaps,s(this,function(a){var c=n[a.id];c&&!c.enabled&& +j.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,c){var b=this.events[a];b||(b=this.events[a]=[]);b.push(c)},emit:function(a,c){q(this.events[a],function(a){a(c)});a==="error"&&delete this.events[a]}};return j={config:m,contextName:b,registry:n,defined:o,urlFetched:R,waitCount:0,defQueue:F,Module:Y,makeModuleMap:e,configure:function(a){a.baseUrl&&a.baseUrl.charAt(a.baseUrl.length-1)!=="/"&&(a.baseUrl+="/");var c=m.pkgs,b=m.shim,d=m.paths,f=m.map;K(m,a,!0);m.paths=K(d,a.paths,!0);if(a.map)m.map= +K(f||{},a.map,!0,!0);if(a.shim)x(a.shim,function(a,c){G(a)&&(a={deps:a});if(a.exports&&!a.exports.__buildReady)a.exports=j.makeShimExports(a.exports);b[c]=a}),m.shim=b;if(a.packages)q(a.packages,function(a){a=typeof a==="string"?{name:a}:a;c[a.name]={name:a.name,location:a.location||a.name,main:(a.main||"main").replace(ka,"").replace(ca,"")}}),m.pkgs=c;x(n,function(a,c){a.map=e(c)});if(a.deps||a.callback)j.require(a.deps||[],a.callback)},makeShimExports:function(a){var c;return typeof a==="string"? +(c=function(){return $(a)},c.exports=a,c):function(){return a.apply(Z,arguments)}},requireDefined:function(a,c){var b=e(a,c,!1,!0).id;return o.hasOwnProperty(b)},requireSpecified:function(a,c){a=e(a,c,!1,!0).id;return o.hasOwnProperty(a)||n.hasOwnProperty(a)},require:function(a,c,d,f){var g;if(typeof a==="string"){if(w(c))return B(H("requireargs","Invalid require call"),d);if(k.get)return k.get(j,a,c);a=e(a,c,!1,!0);a=a.id;return!o.hasOwnProperty(a)?B(H("notloaded",'Module name "'+a+'" has not been loaded yet for context: '+ +b)):o[a]}d&&!w(d)&&(f=d,d=void 0);c&&!w(c)&&(f=c,c=void 0);for(v();F.length;)if(g=F.shift(),g[0]===null)return B(H("mismatch","Mismatched anonymous define() module: "+g[g.length-1]));else W(g);r(e(null,f)).init(a,c,d,{enabled:!0});E();return j.require},undef:function(a){var c=e(a,null,!0),b=n[a];delete o[a];delete R[c.url];delete X[a];if(b){if(b.events.defined)X[a]=b.events;y(a)}},enable:function(a){n[a.id]&&r(a).enable()},completeLoad:function(a){var c=m.shim[a]||{},b=c.exports&&c.exports.exports, +d,e;for(v();F.length;){e=F.shift();if(e[0]===null){e[0]=a;if(d)break;d=!0}else e[0]===a&&(d=!0);W(e)}e=n[a];if(!d&&!o[a]&&e&&!e.inited)if(m.enforceDefine&&(!b||!$(b)))if(g(a))return;else return B(H("nodefine","No define call for "+a,null,[a]));else W([a,c.deps||[],c.exports]);E()},toUrl:function(a,b){var d=a.lastIndexOf("."),e=null;d!==-1&&(e=a.substring(d,a.length),a=a.substring(0,d));return j.nameToUrl(a,e,b)},nameToUrl:function(a,b,e){var f,g,i,h,j,a=d(a,e&&e.id,!0);if(k.jsExtRegExp.test(a))b= +a+(b||"");else{f=m.paths;g=m.pkgs;e=a.split("/");for(h=e.length;h>0;h-=1)if(j=e.slice(0,h).join("/"),i=g[j],j=f[j]){G(j)&&(j=j[0]);e.splice(0,h,j);break}else if(i){a=a===i.name?i.location+"/"+i.main:i.location;e.splice(0,h,a);break}b=e.join("/")+(b||".js");b=(b.charAt(0)==="/"||b.match(/^[\w\+\.\-]+:/)?"":m.baseUrl)+b}return m.urlArgs?b+((b.indexOf("?")===-1?"?":"&")+m.urlArgs):b},load:function(a,b){k.load(j,a,b)},execCb:function(a,b,d,e){return b.apply(e,d)},onScriptLoad:function(a){if(a.type=== +"load"||ma.test((a.currentTarget||a.srcElement).readyState))I=null,a=J(a),j.completeLoad(a.id)},onScriptError:function(a){var b=J(a);if(!g(b.id))return B(H("scripterror","Script error",a,[b.id]))}}}};k({});ba(k);if(u&&(v=y.head=document.getElementsByTagName("head")[0],C=document.getElementsByTagName("base")[0]))v=y.head=C.parentNode;k.onError=function(b){throw b;};k.load=function(b,d,f){var g=b&&b.config||{},e;if(u)return e=g.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"): +document.createElement("script"),e.type=g.scriptType||"text/javascript",e.charset="utf-8",e.setAttribute("data-requirecontext",b.contextName),e.setAttribute("data-requiremodule",d),e.attachEvent&&!(e.attachEvent.toString&&e.attachEvent.toString().indexOf("[native code")<0)&&!S?(L=!0,e.attachEvent("onreadystatechange",b.onScriptLoad)):(e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)),e.src=f,E=e,C?v.insertBefore(e,C):v.appendChild(e),E=null,e;else da&&(importScripts(f), +b.completeLoad(d))};u&&N(document.getElementsByTagName("script"),function(b){if(!v)v=b.parentNode;if(z=b.getAttribute("data-main")){D=z.split("/");ea=D.pop();fa=D.length?D.join("/")+"/":"./";if(!p.baseUrl)p.baseUrl=fa;z=ea.replace(ca,"");p.deps=p.deps?p.deps.concat(z):[z];return!0}});define=function(b,d,f){var g,e;typeof b!=="string"&&(f=d,d=b,b=null);G(d)||(f=d,d=[]);!d.length&&w(f)&&f.length&&(f.toString().replace(ia,"").replace(ja,function(b,e){d.push(e)}),d=(f.length===1?["require"]:["require", +"exports","module"]).concat(d));if(L&&(g=E||ha()))b||(b=g.getAttribute("data-requiremodule")),e=t[g.getAttribute("data-requirecontext")];(e?e.defQueue:P).push([b,d,f])};define.amd={jQuery:!0};k.exec=function(b){return eval(b)};k(p)}})(this);
--- a/lightstring.js +++ b/lightstring.js @@ -16,307 +16,276 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +(function() { + define(['./jid', './stanza', './transports/websocket.js', './transports/bosh.js'], function(JID, Stanza, WebSocketTransport, BOSHTransport) { + Lightstring.JID = JID; + Lightstring.Stanza = Stanza.stanza; + Lightstring.IQ = Stanza.iq; + Lightstring.doc = Stanza.doc; + Lightstring.Presence = Stanza.presence; + Lightstring.Message = Stanza.message; + Lightstring.BOSHTransport = BOSHTransport; + Lightstring.WebSocketTransport = WebSocketTransport; + return Lightstring; + }); -var Lightstring = { - /** - * @namespace Holds XMPP namespaces. - * @description http://xmpp.org/xmpp-protocols/protocol-namespaces - */ - ns: { - streams: 'http://etherx.jabber.org/streams', - jabber_client: 'jabber:client', - xmpp_stanzas: 'urn:ietf:params:xml:ns:xmpp-stanzas' - }, - /** - * @namespace Holds XMPP stanza builders. - */ - stanzas: { - stream: { - open: function(aService) { - return "<stream:stream to='" + aService + "'" + - " xmlns='" + Lightstring.ns['jabber_client'] + "'" + - " xmlns:stream='" + Lightstring.ns['streams'] + "'" + - " version='1.0'>"; + var Lightstring = { + /* + * @namespace Holds XMPP namespaces. + * @description http://xmpp.org/xmpp-protocols/protocol-namespaces + */ + ns: { + streams: 'http://etherx.jabber.org/streams', + jabber_client: 'jabber:client', + xmpp_stanzas: 'urn:ietf:params:xml:ns:xmpp-stanzas' + }, + /** + * @namespace Holds XMPP stanza builders. + */ + stanzas: { + stream: { + open: function(aService) { + return "<stream:stream to='" + aService + "'" + + " xmlns='" + Lightstring.ns['jabber_client'] + "'" + + " xmlns:stream='" + Lightstring.ns['streams'] + "'" + + " version='1.0'>"; + }, + close: function() { + return "</stream:stream>"; + } }, - close: function() { - return "</stream:stream>"; + errors: { + iq: function(from, id, type, error) { + return "<iq to='" + from + "'" + + " id='" + id + "'" + + " type='error'>" + + "<error type='" + type + "'>" + + "<" + error + " xmlns='" + Lightstring.ns['xmpp_stanzas'] + "'/>" + //TODO: allow text content. + //TODO: allow text and payload. + "</error>" + + "</iq>"; + } } }, - errors: { - iq: function(from, id, type, error) { - return "<iq to='" + from + "'" + - " id='" + id + "'" + - " type='error'>" + - "<error type='" + type + "'>" + - "<" + error + " xmlns='" + Lightstring.ns['xmpp_stanzas'] + "'/>" + //TODO: allow text content. - //TODO: allow text and payload. - "</error>" + - "</iq>"; - } + /** + * @namespace Holds Lightstring plugins + */ + plugins: {}, + /** + * @private Holds the connections + */ + connections: [], + /** + * @function Returns a new unique identifier. + * @param {String} [aPrefix] Prefix to put before the identifier. + * @return {String} Identifier. + */ + id: function(aPrefix) { + return (aPrefix || '') + Date.now(); } - }, - /** - * @namespace Holds Lightstring plugins - */ - plugins: {}, - /** - * @private - */ - parser: new DOMParser(), - /** - * @private - */ - serializer: new XMLSerializer(), + }; + /** - * @function Transforms a XML string to a DOM object. - * @param {String} aString XML string. - * @return {Object} Domified XML. - */ - parse: function(aString) { - var el = null; - //FIXME webkit doesn't throw an error when the parsing fails - try { - el = this.parser.parseFromString(aString, 'text/xml').documentElement; - } - catch (e) { - //TODO: error - } - finally { - return el; - }; - }, - /** - * @function Transforms a DOM object to a XML string. - * @param {Object} aString DOM object. - * @return {String} Stringified DOM. - */ - serialize: function(aElement) { - var string = null; - try { - string = this.serializer.serializeToString(aElement); - } - catch (e) { - //TODO: error - } - finally { - return string; - }; - }, - /** - * @function Get an unique identifier. - * @param {String} [aString] Prefix to put before the identifier. - * @return {String} Identifier. + * @constructor Creates a new Lightstring connection + * @param {String} [aService] The connection manager URL. + * @memberOf Lightstring */ - newId: (function() { - var id = 1024; - return function(prefix) { - if (typeof prefix === 'string') - return prefix + id++; - return '' + id++; - }; - })() -}; + Lightstring.Connection = function(aService) { + if (aService) + this.service = aService; + /** + * @namespace Holds connection events handlers + */ + this.handlers = {}; + /** + * @namespace Holds connection iq callbacks + */ + this.callbacks = {}; + + Lightstring.connections.push(this); + }; + Lightstring.Connection.prototype = new EventEmitter(); + Lightstring.Connection.prototype.onTransportLoaded = function() { + this.transport.open(); + + var that = this; + + this.transport.once('open', function() { + that.emit('open'); + }); + this.transport.on('out', function(stanza) { + setTimeout(function() { + that.emit('out', stanza); + }, 0); + }); + this.transport.on('in', function(stanza) { + //FIXME: node-xmpp-bosh sends a self-closing stream:stream tag; it is wrong! + that.emit('stanza', stanza); + + if (!stanza.el) + return; + + var el = stanza.el; -/** - * @constructor Creates a new Lightstring connection - * @param {String} [aService] The connection manager URL. - * @memberOf Lightstring - */ -Lightstring.Connection = function(aService) { - var that = this; - window.addEventListener('message', function(e) { - that.send(e.data.send) - }); - if (aService) - this.service = aService; + //Authentication + //FIXME SASL mechanisms and XMPP features can be both in a stream:features + if (el.localName === 'features') { + var children = el.childNodes; + for (var i = 0, length = children.length; i < length; i++) { + //SASL mechanisms + if(children[i].localName === 'mechanisms') { + stanza.mechanisms = []; + var nodes = el.getElementsByTagName('mechanism'); + for (var i = 0; i < nodes.length; i++) + stanza.mechanisms.push(nodes[i].textContent); + that.emit('mechanisms', stanza); + return; + } + } + //XMPP features + // else { + //TODO: stanza.features + that.emit('features', stanza); + // } + } + else if (el.localName === 'challenge') { + that.emit('challenge', stanza); + } + else if (el.localName === 'failure') { + that.emit('failure', stanza); + } + else if (el.localName === 'success') { + that.emit('success', stanza); + } + + //Iq callbacks + else if (el.localName === 'iq') { + var payload = el.firstChild; + if (payload) + that.emit('iq/' + payload.namespaceURI + ':' + payload.localName, stanza); + + var id = el.getAttribute('id'); + if (!(id && id in that.callbacks)) + return; + + var type = el.getAttribute('type'); + if (type !== 'result' && type !== 'error') + return; //TODO: warning + + var callback = that.callbacks[id]; + if (type === 'result' && callback.success) + callback.success.call(that, stanza); + else if (type === 'error' && callback.error) + callback.error.call(that, stanza); + + delete that.callbacks[id]; + } + + else if (el.localName === 'presence' || el.localName === 'message') { + that.emit(name, stanza); + } + }); + }; /** - * @namespace Holds connection events handlers - */ - this.handlers = {}; - /** - * @namespace Holds connection iq callbacks + * @function Create and open a websocket then go though the XMPP authentification process. + * @param {String} [aJid] The JID (Jabber id) to use. + * @param {String} [aPassword] The associated password. */ - this.callbacks = {}; -}; -Lightstring.Connection.prototype = new EventEmitter(); -/** - * @function Create and open a websocket then go though the XMPP authentification process. - * @param {String} [aJid] The JID (Jabber id) to use. - * @param {String} [aPassword] The associated password. - */ -Lightstring.Connection.prototype.connect = function(aJid, aPassword) { - this.emit('connecting'); - this.jid = new Lightstring.JID(aJid); - if (aPassword) - this.password = aPassword; + Lightstring.Connection.prototype.connect = function(aJid, aPassword) { + this.emit('connecting'); + this.jid = new Lightstring.JID(aJid); + if (aPassword) + this.password = aPassword; - if (!this.jid.bare) - return; //TODO: error - if (!this.service) - return; //TODO: error + if (!this.jid.bare) + return; //TODO: error + if (!this.service) + return; //TODO: error + + function getProtocol(aURL) { + var a = document.createElement('a'); + a.href = aURL; + return a.protocol.replace(':', ''); + } + var protocol = getProtocol(this.service); - function getProtocol(aURL) { - var a = document.createElement('a'); - a.href = aURL; - return a.protocol.replace(':', ''); - } - var protocol = getProtocol(this.service); - - if (protocol.match('http')) - this.connection = new Lightstring.BOSHConnection(this.service, this.jid); - else if (protocol.match('ws')) - this.connection = new Lightstring.WebSocketConnection(this.service, this.jid); - - this.connection.open(); + if (protocol.match('http')) + this.transport = new Lightstring.BOSHTransport(this.service, this.jid); + else if (protocol.match('ws')) + this.transport = new Lightstring.WebSocketTransport(this.service, this.jid); - var that = this; + this.onTransportLoaded(); + }; + /** + * @function Send a message. + * @param {String|Object} aStanza The message to send. + * @param {Function} [aCallback] Executed on answer. (stanza must be iq) + */ + Lightstring.Connection.prototype.send = function(aStanza, aOnSuccess, aOnError) { + if (!(aStanza instanceof Lightstring.Stanza)) + var stanza = new Lightstring.Stanza(aStanza); + else + var stanza = aStanza; - this.connection.once('open', function() { - that.emit('open'); - }); - this.connection.on('out', function(stanza) { - that.emit('out', stanza); - }); - this.connection.on('in', function(stanza) { - //FIXME: node-xmpp-bosh sends a self-closing stream:stream tag; it is wrong! - that.emit('stanza', stanza); - - if (!stanza.el) + if (!stanza) return; - var el = stanza.el; + if (stanza.name === 'iq') { + var type = stanza.type; + if (type !== 'get' || type !== 'set') + ; //TODO: error - //Authentication - //FIXME SASL mechanisms and XMPP features can be both in a stream:features - if (el.localName === 'features') { - var children = el.childNodes; - for (var i = 0, length = children.length; i < length; i++) { - //SASL mechanisms - if(children[i].localName === 'mechanisms') { - stanza.mechanisms = []; - var nodes = el.getElementsByTagName('mechanism'); - for (var i = 0; i < nodes.length; i++) - stanza.mechanisms.push(nodes[i].textContent); - that.emit('mechanisms', stanza); - return; - } - } - //XMPP features - // else { - //TODO: stanza.features - that.emit('features', stanza); - // } - } - else if (el.localName === 'challenge') { - that.emit('challenge', stanza); - } - else if (el.localName === 'failure') { - that.emit('failure', stanza); - } - else if (el.localName === 'success') { - that.emit('success', stanza); - } + var callback = {success: aOnSuccess, error: aOnError}; - //Iq callbacks - else if (el.localName === 'iq') { - var payload = el.firstChild; - if (payload) - that.emit('iq/' + payload.namespaceURI + ':' + payload.localName, stanza); - - var id = el.getAttribute('id'); - if (!(id && id in that.callbacks)) - return; + var id = stanza.id; + if (!id) + stanza.id = Lightstring.id(); - var type = el.getAttribute('type'); - if (type !== 'result' && type !== 'error') - return; //TODO: warning - - var callback = that.callbacks[id]; - if (type === 'result' && callback.success) - callback.success.call(that, stanza); - else if (type === 'error' && callback.error) - callback.error.call(that, stanza); - - delete that.callbacks[id]; - } - - else if (el.localName === 'presence' || el.localName === 'message') { - that.emit(name, stanza); + this.callbacks[stanza.id] = callback; } - }); -}; -/** - * @function Send a message. - * @param {String|Object} aStanza The message to send. - * @param {Function} [aCallback] Executed on answer. (stanza must be iq) - */ -Lightstring.Connection.prototype.send = function(aStanza, aSuccess, aError) { - if (!(aStanza instanceof Lightstring.Stanza)) - var stanza = new Lightstring.Stanza(aStanza); - else - var stanza = aStanza; - - if (!stanza) - return; + else if (aOnSuccess || aOnError) + ; //TODO: warning (no callback without iq) - if (stanza.el.tagName === 'iq') { - var type = stanza.el.getAttribute('type'); - if (type !== 'get' || type !== 'set') - ; //TODO: error - - var callback = {success: aSuccess, error: aError}; + this.transport.send(stanza.toString()); + }; + /** + * @function Closes the XMPP stream and the socket. + */ + Lightstring.Connection.prototype.disconnect = function() { + this.emit('disconnecting'); + var stream = Lightstring.stanzas.stream.close(); + this.transport.send(stream); + this.emit('out', stream); + this.transport.close(); + }; + Lightstring.Connection.prototype.load = function() { + for (var i = 0; i < arguments.length; i++) { + var name = arguments[i]; + if (!(name in Lightstring.plugins)) + continue; //TODO: error - var id = stanza.el.getAttribute('id'); - if (!id) { - var id = Lightstring.newId('sendiq:'); - stanza.el.setAttribute('id', id); - } - - this.callbacks[id] = callback; - - } - else if (aSuccess || aError) - ; //TODO: warning (no callback without iq) + var plugin = Lightstring.plugins[name]; - this.connection.send(stanza.toString()); -}; -/** - * @function Closes the XMPP stream and the socket. - */ -Lightstring.Connection.prototype.disconnect = function() { - this.emit('disconnecting'); - var stream = Lightstring.stanzas.stream.close(); - this.socket.send(stream); - this.emit('out', stream); - this.socket.close(); -}; -Lightstring.Connection.prototype.load = function() { - for (var i = 0; i < arguments.length; i++) { - var name = arguments[i]; - if (!(name in Lightstring.plugins)) - continue; //TODO: error + //Namespaces + for (var ns in plugin.namespaces) + Lightstring.ns[ns] = plugin.namespaces[ns]; - var plugin = Lightstring.plugins[name]; + //Stanzas + Lightstring.stanzas[name] = {}; + for (var stanza in plugin.stanzas) + Lightstring.stanzas[name][stanza] = plugin.stanzas[stanza]; - //Namespaces - for (var ns in plugin.namespaces) - Lightstring.ns[ns] = plugin.namespaces[ns]; - - //Stanzas - Lightstring.stanzas[name] = {}; - for (var stanza in plugin.stanzas) - Lightstring.stanzas[name][stanza] = plugin.stanzas[stanza]; + //Handlers + for (var handler in plugin.handlers) + this.on(handler, plugin.handlers[handler]); - //Handlers - for (var handler in plugin.handlers) - this.on(handler, plugin.handlers[handler]); + //Methods + this[name] = {}; + for (var method in plugin.methods) + this[name][method] = plugin.methods[method].bind(this); - //Methods - this[name] = {}; - for (var method in plugin.methods) - this[name][method] = plugin.methods[method].bind(this); - - if (plugin.init) - plugin.init.apply(this); - } -}; \ No newline at end of file + if (plugin.init) + plugin.init.apply(this); + } + }; +})(); \ No newline at end of file
--- a/plugins/PLAIN.js +++ b/plugins/PLAIN.js @@ -33,12 +33,13 @@ Lightstring.plugins['PLAIN'] = { return; var token = btoa( - this.jid + + this.jid.bare + '\u0000' + - this.jid.node + + this.jid.local + '\u0000' + this.password ); + this.send( "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'" + " mechanism='PLAIN'>" + token + "</auth>" @@ -56,7 +57,7 @@ Lightstring.plugins['PLAIN'] = { var Conn = this; //TODO check if bind supported var bind = - "<iq type='set' id='"+Lightstring.newId('sendiq:')+"'>" + + "<iq type='set' id='" + Lightstring.id() + "'>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>" + (this.jid.resource? "<resource>" + this.jid.resource + "</resource>": "") + "</bind>" + @@ -68,7 +69,7 @@ Lightstring.plugins['PLAIN'] = { //Session http://xmpp.org/rfcs/rfc3921.html#session Conn.jid = new Lightstring.JID(stanza.el.textContent); Conn.send( - "<iq type='set' id='"+Lightstring.newId('sendiq:')+"'>" + + "<iq type='set' id='" + Lightstring.id() + "'>" + "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>" + "</iq>", function() {
new file mode 100644 --- /dev/null +++ b/plugins/delay.js @@ -0,0 +1,41 @@ +'use strict'; + +/** + Copyright (c) 2011, Sonny Piers <sonny at fastmail dot net> + Copyright (c) 2012, Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +//////////// +//Presence// http://xmpp.org/rfcs/rfc6121.html#presence +//////////// +(function() { + Object.defineProperty(Lightstring.Stanza.prototype, "delay", { + get : function(){ + var delayEl = this.el.querySelector('delay'); + if (!delayEl) + return null; + + var delay = { + stamp: delayEl.getAttribute('stamp'), + from: delayEl.getAttribute('from'), + reason: delayEl.textContent + } + return delay; + }, + // set : function(newValue){ bValue = newValue; }, + enumerable : true, + configurable : true + }); +})();
new file mode 100755 --- /dev/null +++ b/plugins/events.js @@ -0,0 +1,28 @@ +'use strict'; + +/** + Copyright (c) 2012, Sonny Piers <sonny at fastmail dot net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +Lightstring.plugins['events'] = { + handlers: { + 'input': function callback(stanza) { + + }, + //~ 'output': function callback(stanza) { + //~ alert('output'); + //~ } + } +};
--- a/plugins/im.js +++ b/plugins/im.js @@ -45,21 +45,31 @@ Lightstring.plugins['im'] = { return message; }, - received: function(aTo, aId) { - var message = Lightstring.parse( - "<message to='" + aTo + "'>" + - "<received xmlns='urn:xmpp:receipts' id='" + aId + "'/>" + - "</message>" - ); - return message; - }, - read: function(aTo, aId) { - var message = Lightstring.parse( - "<message to='" + aTo + "'>" + - "<read xmlns='urn:xmpp:receipts' id='" + aId + "'/>" + - "</message>" - ); - return message; - }, } }; +Object.defineProperties(Lightstring.Stanza.prototype, { + 'body': { + get : function(){ + var bodyEl = this.el.querySelector('body'); + if (!bodyEl) + return null; + + return bodyEl.textContent; + }, + // set : function(newValue){ bValue = newValue; }, + enumerable : true, + configurable : true + }, + 'subject': { + get : function(){ + var subjectEl = this.el.querySelector('subject'); + if (!subjectEl) + return null; + + return subjectEl.textContent; + }, + // set : function(newValue){ bValue = newValue; }, + enumerable : true, + configurable : true + } +}); \ No newline at end of file
--- a/plugins/ping.js +++ b/plugins/ping.js @@ -49,3 +49,19 @@ Lightstring.plugins['ping'] = { } } } +Object.defineProperties(Lightstring.Stanza.prototype, { + 'ping': { + get : function() { + return !!(this.el.querySelector('ping')); + }, + set: function(aBool) { + if (this.ping) + return; + + var pingEl = Lightstring.doc.createElementNS(Lightstring.ns.ping, 'ping'); + this.el.appendChild(pingEl); + }, + enumerable : true, + configurable : true + }, +});
--- a/plugins/presence.js +++ b/plugins/presence.js @@ -40,6 +40,9 @@ if (object.type && legal_types.indexOf(object.type) !== -1) attributs += " type='" + object.type + "'"; + if (object.to) + attributs += " to='" + object.to + "'"; + if (object.priority) payloads += "<priority>" + object.priority + "</priority>"; @@ -65,6 +68,30 @@ send: function(aObject) { this.send(Lightstring.stanzas.presence.out(aObject)); } - } + }, }; + + Object.defineProperties(Lightstring.Stanza.prototype, { + 'show': { + get : function() { + return this.el.getAttribute('show'); + }, + enumerable : true, + configurable : true + }, + 'priority': { + get : function() { + return this.el.getAttribute('priority'); + }, + enumerable : true, + configurable : true + }, + 'status': { + get : function() { + return this.el.getAttribute('status'); + }, + enumerable : true, + configurable : true + }, + }) })();
new file mode 100644 --- /dev/null +++ b/plugins/receipts.js @@ -0,0 +1,115 @@ +'use strict'; + +/** + Copyright (c) 2011, Sonny Piers <sonny at fastmail dot net> + Copyright (c) 2012, Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +///////////////////////////////////////////////////////////////////////////////// +//XEP-0184: Message Delivery Receipts http://xmpp.org/extensions/xep-0184.html // +///////////////////////////////////////////////////////////////////////////////// +(function () { + +var ns = 'urn:xmpp:receipts'; +Lightstring.plugins['receipts'] = { + namespaces: { + receipts: ns + }, + // features: [ns], + // methods: { + // 'received': function(aOnSuccess, aOnError) { + // } + // } +}; +Object.defineProperties(Lightstring.Stanza.prototype, { + 'receipt': { + get : function() { + var receiptEl; + for (var i = 0, length = this.el.childNodes.length; i < length; i++) { + if (this.el.childNodes[i].namespaceURI === ns) { + receiptEl = this.el.childNodes[i]; + break; + } + } + if (!receiptEl) + return null; + + var receipt = {name: receiptEl.localName}; + + var id = receiptEl.getAttribute('id'); + if (id) + receipt.id = id; + + return receipt; + }, + set: function(aProps) { + var receipt = Lightstring.doc.createElementNS(ns, aProps.name); + if (aProps.id) + receipt.setAttribute('id', aProps.id); + + var receiptEl; + for (var i = 0, length = this.el.childNodes.length; i < length; i++) { + if (this.el.childNodes[i].namespaceURI === ns) { + receiptEl = this.el.childNodes[i]; + break; + } + } + if (receiptEl) + this.el.removeChild(receiptEl); + + this.el.appendChild(receipt); + }, + enumerable : true, + configurable : true + }, + 'request': { + get : function() { + var receipt = this.receipt; + if (!receipt || (receipt.name !== 'request')) + return null; + + return receipt; + }, + set: function(aBool) { + this.receipt = {name: 'request'} + if (!this.id) + this.id = Lightstring.id(); + }, + enumerable : true, + configurable : true + }, + 'received': { + get : function() { + var receipt = this.receipt; + if (!receipt || (receipt.name !== 'received')) + return null; + + return receipt; + }, + set: function(aId) { + this.receipt = {name: 'received', id: aId} + }, + enumerable : true, + configurable : true + }, +}); +Lightstring.Stanza.prototype.replyWithReceived = function(aProps) { + var reply = this.reply(aProps); + reply.received = this.id; + + return reply; +}; + +})(); \ No newline at end of file
--- a/plugins/roster.js +++ b/plugins/roster.js @@ -73,6 +73,10 @@ Lightstring.plugins['roster'] = { if (subscription) contact.subscription = subscription; + var ask = item.getAttribute('ask'); + if (ask) + contact.ask = ask; + var groups = item.getElementsByTagName('group'); if(groups) { contact.groups = [];
--- a/stanza.js +++ b/stanza.js @@ -16,53 +16,246 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +(function() { + +if (typeof define !== 'undefined') { + define(function() { + return { + 'stanza': Stanza, + 'presence': Presence, + 'iq': IQ, + 'message': Message, + 'doc': doc, + }; + }); +} +else { + Lightstirng.Stanza = Stanza; + Lightstirng.Presence = Presence; + Lightstirng.IQ = IQ; + Lightstirng.Message = Message; + Lightstirng.doc = doc; +} + +/** + * @private + */ +var doc = document.implementation.createDocument(null, 'dummy', null); +/** + * @private + */ +var parser = new DOMParser(); +/** + * @private + */ +var serializer = new XMLSerializer(); +/** + * @function Transforms a XML string to a DOM object. + * @param {String} aString XML string. + * @return {Object} Domified XML. + */ +var parse = function(aString) { + var el = parser.parseFromString(aString, 'text/xml').documentElement; + if (el.tagName === 'parsererror') + ;//do something + return el; +}; +/** + * @function Transforms a DOM object to a XML string. + * @param {Object} aString DOM object. + * @return {String} Stringified DOM. + */ +var serialize = function(aElement) { + var string = null; + try { + string = serializer.serializeToString(aElement); + } + catch (e) { + //TODO: error + } + finally { + return string; + }; +}; + /** * @constructor Creates a new Stanza object. * @param {String|Object} [aStanza] The XML or DOM content of the stanza - * @memberOf Lightstring + */ +var Stanza = function(aStanza) { + this.createEl(aStanza); +}; +/** + * @constructor Creates a new Message stanza object. + * @param {String|Object} [aStanza] The XML or DOM content of the stanza + */ + var Message = function(aStanza) { + if ((typeof aStanza === 'object') && (!(aStanza instanceof Element))) + aStanza.name = 'message'; + this.createEl(aStanza); +}; +Message.prototype = Stanza.prototype; +/** + * @constructor Creates a new IQ stanza object. + * @param {String|Object} [aStanza] The XML or DOM content of the stanza */ -Lightstring.Stanza = function(aStanza) { - if (typeof aStanza === 'string') - this.el = Lightstring.parse(aStanza); +var IQ = function(aStanza) { + if ((typeof aStanza === 'object') && (!(aStanza instanceof Element))) + aStanza.name = 'iq'; + this.createEl(aStanza); +}; +IQ.prototype = Stanza.prototype; +/** + * @constructor Creates a new Presence stanza object. + * @param {String|Object} [aStanza] The XML or DOM content of the stanza + */ +var Presence = function(aStanza) { + if ((typeof aStanza === 'object') && (!(aStanza instanceof Element))) + aStanza.name = 'presence'; + this.createEl(aStanza); +}; +Presence.prototype = Stanza.prototype; +Stanza.prototype.createEl = function(aStanza) { + if (typeof aStanza === 'string') { + this.el = parse(aStanza); + } else if (aStanza instanceof Element) this.el = aStanza; + else if (typeof aStanza === 'object') { + var el = doc.createElement(aStanza.name); + this.el = el; + delete aStanza.name; + for (var i in aStanza) { + this[i] = aStanza[i]; + } + } else this.el = null;//TODO error }; -Lightstring.Stanza.prototype.toString = function() { - return Lightstring.serialize(this.el); +Stanza.prototype.toString = function() { + return serialize(this.el); +}; +Stanza.prototype.reply = function(aProps) { + var props = aProps || {}; + + props.name = this.name; + var reply = new Stanza(props); + + if (this.from) + reply.to = this.from; + + + if (reply.name !== 'iq') + return reply; + + if (this.id) + reply.id = this.id; + + reply.type = 'result'; + + return reply; }; -Object.defineProperty(Lightstring.Stanza.prototype, "from", { +//from attribute +Object.defineProperty(Stanza.prototype, "from", { get : function(){ return this.el.getAttribute('from'); }, + set : function(aString) { + this.el.setAttribute('from', aString); + }, + enumerable : true, + configurable : true +}); +//stanza tag name +Object.defineProperty(Stanza.prototype, "name", { + get : function(){ + return this.el.localName; + }, + //FIXME // set : function(newValue){ bValue = newValue; }, enumerable : true, configurable : true }); -Object.defineProperty(Lightstring.Stanza.prototype, "name", { - get : function(){ - return this.el.localName; - }, - // set : function(newValue){ bValue = newValue; }, - enumerable : true, - configurable : true -}); -Object.defineProperty(Lightstring.Stanza.prototype, "id", { +//id attribute +Object.defineProperty(Stanza.prototype, "id", { get : function(){ return this.el.getAttribute('id'); }, - // set : function(newValue){ bValue = newValue; }, + set : function(aString) { + this.el.setAttribute('id', aString); + }, + enumerable : true, + configurable : true +}); +//to attribute +Object.defineProperty(Stanza.prototype, "to", { + get : function(){ + return this.el.getAttribute('to'); + }, + set : function(aString) { + this.el.setAttribute('to', aString); + }, + enumerable : true, + configurable : true +}); +//type attribute +Object.defineProperty(Stanza.prototype, "type", { + get : function(){ + return this.el.getAttribute('type'); + }, + set : function(aString) { + this.el.setAttribute('type', aString); + }, enumerable : true, configurable : true }); -Object.defineProperty(Lightstring.Stanza.prototype, "to", { +//body +Object.defineProperty(Stanza.prototype, "body", { get : function(){ - return this.el.getAttribute('to'); - }, - // set : function(newValue){ bValue = newValue; }, + var bodyEl = this.el.querySelector('body').textContent; + if (!bodyEl) + return null; + else + return bodyEl.textContent; + }, + set : function(aString) { + var bodyEl = this.el.querySelector('body'); + if (!bodyEl) { + bodyEl = doc.createElement('body'); + bodyEl = this.el.appendChild(bodyEl); + } + bodyEl.textContent = aString; + }, enumerable : true, configurable : true -}); \ No newline at end of file +}); +//subject +Object.defineProperty(Stanza.prototype, "subject", { + get : function(){ + var subjectEl = this.el.querySelector('subject').textContent; + if (!subjectEl) + return null; + else + return subjectEl.textContent; + }, + set : function(aString) { + var subjectEl = this.el.querySelector('subject'); + if (!subjectEl) { + subjectEl = doc.createElement('subject'); + subjectEl = this.el.appendChild(subjectEl); + } + subjectEl.textContent = aString; + }, + enumerable : true, + configurable : true +}); +Stanza.prototype.replyWithSubscribed = function(aProps) { + var reply = this.reply(aProps); + reply.type = 'subscribed'; + + return reply; +}; + +})(); \ No newline at end of file
--- a/transports/bosh.js +++ b/transports/bosh.js @@ -1,74 +1,79 @@ 'use strict'; (function() { - Lightstring.BOSHConnection = function(aService) { + + if (typeof define !== 'undefined') { + define(function() { + return BOSHTransport; + }); + } + else { + Lightstring.BOSHTransport = BOSHTransport; + } + + var BOSHTransport = function(aService, aJID) { this.service = aService; this.rid = 1337; + this.jid = aJID; this.currentRequests = 0; this.maxHTTPRetries = 5; this.maxRequests = 2; this.queue = []; }; - Lightstring.BOSHConnection.prototype = new EventEmitter(); - Lightstring.BOSHConnection.prototype.open = function() { + BOSHTransport.prototype = new EventEmitter(); + BOSHTransport.prototype.open = function() { var that = this; var attrs = { wait: '60', hold: '1', - to: 'yuilop', + to: this.jid.domain, content: 'text/xml; charset=utf-8', ver: '1.6', 'xmpp:version': '1.0', 'xmlns:xmpp': 'urn:xmpp:xbosh', }; - this.request(attrs, null, function(data) { + this.request(attrs, [], function(data) { that.emit('open'); that.sid = data.getAttribute('sid'); that.maxRequests = data.getAttribute('maxRequests') || that.maxRequests; + if (!data.getElementsByTagNameNS('http://etherx.jabber.org/streams', 'features')[0]) { + that.request(); + } }); this.on('in', function(stanza) { - if (stanza.localName === 'success') { + if (stanza.name === 'success') { that.request({ + 'to': that.jid.domain, 'xmpp:restart': 'true', 'xmlns:xmpp': 'urn:xmpp:xbosh' }) } }) }; - Lightstring.BOSHConnection.prototype.request = function(attrs, children, aOnSuccess, aOnError, aRetry) { - // if (children && children[0] && children[0].name === 'body') { - // var body = children[0]; - // } - // else { - // var body = new ltx.Element('body'); - // if (children) { - // if(util.isArray(children)) - // for (var k in children) - // body.cnode(children[k]); - // else - // body.cnode(children); - // } - // } + BOSHTransport.prototype.request = function(attrs, children, aOnSuccess, aOnError, aRetry) { + if (!children) + children = []; - var body = new Lightstring.Stanza('<body rid="' + this.rid++ + '" xmlns="http://jabber.org/protocol/httpbind"/>'); + var body = Lightstring.doc.createElement('body'); + body.setAttribute('rid', this.rid++); + body.setAttribute('xmlns', 'http://jabber.org/protocol/httpbind'); //sid if (this.sid) - body.el.setAttribute('sid', this.sid); + body.setAttribute('sid', this.sid); //attributes on body for (var i in attrs) - body.el.setAttribute(i, attrs[i]); + body.setAttribute(i, attrs[i]); //children - for (var i in children) - body.el.appendChild(children[i]); - - + for (var i = 0, length = children.length; i < length; i++) { + body.appendChild(children[i]); + }; var retry = aRetry || 0; @@ -87,7 +92,6 @@ // req.addEventListener("abort", transferCanceled, false); var that = this; - // req.responseType = 'document'; req.addEventListener("load", function() { if (req.status < 200 || req.status >= 400) { that.emit('error', "HTTP status " + req.status); @@ -99,7 +103,7 @@ var body = this.response; that.emit('rawin', body); var bodyEl = Lightstring.parse(body); - that.processResponse(bodyEl) + that.processResponse(bodyEl); if (aOnSuccess) aOnSuccess(bodyEl); @@ -116,18 +120,21 @@ // } // }); // this.emit('rawout', body.toString()); - if (body.children) { - for(var i = 0; i < body.children.length; i++) { - var child = body.children[i]; - that.emit('out', child); + if (body.childNodes) { + for(var i = 0; i < body.childNodes.length; i++) { + var child = body.childNodes[i]; + that.emit('out', new Lightstring.Stanza(child)); } } - this.emit('rawout', body); + + var bodyStr = Lightstring.serialize(body); - req.send(Lightstring.serialize(body)); + this.emit('rawout', bodyStr); + + req.send(bodyStr); this.currentRequests++; }; - Lightstring.BOSHConnection.prototype.send = function(aData) { + BOSHTransport.prototype.send = function(aData) { if (!aData) { var el = ''; } @@ -152,7 +159,7 @@ setTimeout(this.mayRequest.bind(this), 0) }; - Lightstring.BOSHConnection.prototype.end = function(stanzas) { + BOSHTransport.prototype.end = function(stanzas) { var that = this; stanzas = stanzas || []; @@ -168,21 +175,23 @@ delete that.sid; }); }; - Lightstring.BOSHConnection.prototype.processResponse = function(bodyEl) { - if (bodyEl && bodyEl.children) { - for(var i = 0; i < bodyEl.children.length; i++) { - var child = bodyEl.children[i]; - this.emit('in', child); + BOSHTransport.prototype.processResponse = function(bodyEl) { + var children = bodyEl.childNodes + if (children.length) { + for(var i = 0; i < children.length; i++) { + var child = children[i]; + var stanza = new Lightstring.Stanza(child); + this.emit('in', stanza); } } - if (bodyEl && bodyEl.getAttribute('type') === 'terminate') { + else if (bodyEl.getAttribute('type') === 'terminate') { var condition = bodyEl.getAttribute('condition'); this.emit('error', new Error(condition || "Session terminated")); this.emit('close'); } }; - Lightstring.BOSHConnection.prototype.mayRequest = function() { + BOSHTransport.prototype.mayRequest = function() { var canRequest = this.sid && (this.currentRequests === 0 || ((this.queue.length > 0 && this.currentRequests < this.maxRequests)) ); @@ -192,7 +201,6 @@ var stanzas = this.queue; this.queue = []; - //~ this.rid++; var that = this; this.request({}, stanzas, @@ -200,12 +208,12 @@ function(data) { //if (data) //that.processResponse(data); - setTimeout(that.mayRequest.bind(that), 0); }, //error function(error) { + console.log('error') that.emit('error', error); that.emit('close'); delete that.sid;
--- a/transports/websocket.js +++ b/transports/websocket.js @@ -1,23 +1,33 @@ 'use strict'; (function() { - Lightstring.WebSocket = WebSocket || MozWebSocket || undefined; - Lightstring.WebSocketConnection = function(aService, aJid) { + var WebSocket = window.WebSocket || window.MozWebSocket || undefined; + + if (typeof define !== 'undefined') { + define(function() { + return WebSocketTransport; + }); + } + else { + Lightstring.WebSocketTransport = WebSocketTransport; + } + + var WebSocketTransport = function(aService, aJid) { this.service = aService; this.jid = aJid; }; - Lightstring.WebSocketConnection.prototype = new EventEmitter(); - Lightstring.WebSocketConnection.prototype.open = function() { - if(!Lightstring.WebSocket) + WebSocketTransport.prototype = new EventEmitter(); + WebSocketTransport.prototype.open = function() { + if(!WebSocket) return; //TODO: error this.socket = new WebSocket(this.service, 'xmpp'); var that = this; this.socket.addEventListener('open', function() { - //FIXME: Opera/Safari WebSocket implementation doesn't support sub-protocol mechanism. - //if (this.protocol !== 'xmpp') - //return; //TODO: error + if (this.protocol !== 'xmpp') + ; //TODO: warning (Opera and Safari doesn't support this property) + that.emit('open'); var stream = Lightstring.stanzas.stream.open(that.jid.domain); @@ -39,8 +49,9 @@ that.emit('in', stanza); }); }; - Lightstring.WebSocketConnection.prototype.send = function(aStanza) { + WebSocketTransport.prototype.send = function(aStanza) { this.emit('out', aStanza); this.socket.send(aStanza.toString()); }; + })(); \ No newline at end of file