add docco-style Ox.SourceViewer, Ox.ExamplePage and Ox.ExamplePanel, and a demo

This commit is contained in:
rolux 2012-04-04 16:59:58 +02:00
parent 7b7bedb65a
commit ef0e161ab0
16 changed files with 224002 additions and 3 deletions

View file

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>OxJS ExamplePanel Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="../../dev/Ox.js"></script>
<script>
Ox.load('UI', function() {
///*
Ox.ExamplePanel({
examples: ['cities'],
path: Ox.PATH + '../examples/',
replace: [[/\b(Ox[\.\w]+)\b/g, '<b>$1</b>']]
})
.appendTo(Ox.$body);
//*/
/*
Ox.ExamplePage({
height: window.innerHeight,
html: Ox.PATH + '../examples/cities/index.html',
js: Ox.PATH + '../examples/cities/js/example.js',
title: 'Cities',
width: window.innerWidth
})
.appendTo(Ox.$body);
*/
});
</script>
</head>
<body></body>
</html>

View file

@ -0,0 +1,41 @@
#toolbar > .OxElement:first-child {
float: left;
margin: 4px 2px 4px 4px;
}
#toolbar > .OxElement:last-child {
float: right;
margin: 4px 4px 4px 2px;
}
.OxDialog #content {
padding: 8px 16px 8px 16px;
overflow: hidden;
}
.OxDialog img {
float: left;
width: 256px;
height: 256px;
border-radius: 16px;
margin: 8px;
//background: rgb(128, 128, 128);
box-shadow: 0 0 1px rgb(128, 128, 128);
}
.OxTextList .OxItem .OxCell > div.region {
width: 12px;
height: 12px;
border-width: 1px;
border-radius: 2px;
margin-left: -3px;
}
.OxTextList .OxItem .OxCell > img.flag {
width: 14px;
height: 14px;
margin: 0 0 0 -3px;
border-radius: 2px;
}
.OxTextList .OxItem .OxCell > img.capital {
width: 10px;
height: 10px;
margin: 2px 0 0 -1px;
}

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Cities</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="keywords" content="Ox.Map, Ox.TextList"/>
<link rel="shortcut icon" type="image/png" href="../../source/Ox/png/OxJS16.png"/>
<link rel="stylesheet" type="text/css" href="css/example.css"/>
<script type="text/javascript" src="../../dev/Ox.js"></script>
<script type="text/javascript" src="js/example.js"></script>
</head>
<body>
</body>
</html>

View file

@ -0,0 +1,509 @@
/*
...
*/
'use strict';
/*
Since we will be doing some mapping, we have to load the Geo module.
*/
Ox.load({UI: {}, Geo: {}}, function() {
Ox.getJSON('json/cities.json', function(cities) {
/*
The JSON data originally comes from geonames.org. It's an array of
10,000 city objects, each of which has the following properties:
<pre>
{
"country_code": "CN",
"elevation": 0,
"feature_code": "PPLA",
"latitude": 31.22222,
"longitude": 121.45806,
"name": "Shanghai",
"population": 14608512
}
</pre>
*/
cities = cities.map(function(data, id) {
/*
First of all, we have to patch this data, so that it becomes more useful
both for the list and the map. Ox.getCountryByCode gives us the names of
the country, region and continent. For the map, we need a geoname, and
the cities have to be rectangular areas, not just points. So we set the
area to 100 square meters per inhabitant, which will turn out to be
relatively realistic. Then we calculate how large the resulting square
will be, in degrees. (The number of degrees from west to east depends on
the city's proximity to the equator. OxJS has some utility functions
built in that make this easy to compute.) Finally, we can set the values
for south, north, west and east. A nice side effect of deriving the size
of the city from its population is that the map, which will always show
the largest places in the visible area, will now show the most populated
cities.
*/
var area = Math.max(data.population, 1) * 100,
country = Ox.getCountryByCode(data.country_code),
latSize = Math.sqrt(area) / Ox.EARTH_CIRCUMFERENCE * 360,
lngSize = Math.sqrt(area) * Ox.getDegreesPerMeter(data.latitude);
/*
Our city object will look like this:<pre>
{
"area": 1460851200,
"capital": false,
"country": "China",
"east": 121.65880869475835,
"elevation": 0,
"geoname": "Shanghai, China",
"id": "0",
"lat": 31.22222,
"lng": 121.45806,
"name": "Shanghai",
"north": 31.393892916013158,
"population": 14608512,
"region": "Asia, Eastern Asia, China",
"south": 31.050547083986842,
"west": 121.25731130524166
}</pre>
Obviously, in a real-world scenario, you would make sure that the
data already comes in this form.
*/
return {
area: area,
capital: data.feature_code == 'PPLC',
country: country.name,
east: data.longitude + lngSize / 2,
elevation: data.elevation,
geoname: [data.name, country.name].join(', '),
id: id.toString(),
lat: data.latitude,
lng: data.longitude,
name: data.name,
north: data.latitude + latSize / 2,
population: data.population,
region: [country.continent, country.region, country.name].join(', '),
south: data.latitude - latSize / 2,
west: data.longitude - lngSize / 2
};
/**/
});
var listAPI = Ox.api(cities, {
cache: true,
sort: ['-population', '+name'],
sums: ['population']
}),
$preview = Ox.Button({
disabled: true,
selectable: true,
title: 'view',
type: 'image'
})
.bindEvent({
change: function(data) {
$list[(data.value ? 'open' : 'close') + 'Preview']();
}
}),
/*
As we want the list to be searchable, we add an input element.
*/
$find = Ox.Input({
clear: true,
placeholder: 'Find',
width: 192
})
.bindEvent({
submit: function(data) {
listAPI({
keys: [],
query: {
conditions: data.value ? [
{
key: 'name',
operator: '=',
value: data.value
},
{
key: 'region',
operator: '=',
value: data.value
}
] : [],
operator: '|'
}
}, function(result) {
$list.options({items: result.data.items});
});
}
}),
$toolbar = Ox.Bar({size: 24})
.attr({id: 'toolbar'})
.append($preview)
.append($find),
$list = Ox.TextList({
columns: [
{
/*
We don't want to display the id, so we omit the
visible attribute, which defaults to false. We still
have to include the id here, since is the unique key
of our table. In consequence, whenever the list
fires a select event, it will reference this value
as the item's id.
*/
id: 'id',
operator: '+',
title: 'Id',
unique: true
},
{
/*
We use the format function to display the region as
a colored icon with a tooltip. The OxTypeIcon class
makes the icon themed (its border color will depend
on the current theme), the region class is added to
apply our own custom CSS, and Ox.getGeoColor returns
a color for the region. Note that the actual value
is 'Continent, Region, Country', which results in a
nicer sort order than just 'Region'.
*/
format: function(value) {
var region = value.split(', ')[1];
return Ox.Element({
tooltip: region
})
.addClass('OxTypeIcon region')
.css({
background: 'rgb('
+ Ox.getGeoColor(region).join(', ')
+ ')'
});
},
id: 'region',
/*
The operator indicates that we want the default sort
order for this column to be ascending.
*/
operator: '+',
/*
We want the column title to be a symbol, so we pass
the 'icon' symbol at a titleImage. We can pick
anything from the collection of symbols that comes
with Ox.UI. The column still needs a textual title,
to be displayed in the menu that allows to show or
hide specific columns.
*/
title: 'Region',
titleImage: 'icon',
/**/
visible: true,
width: 16
},
{
/*
Ox.getFlagByGeoname and Ox.getFlagByCountryCode
return pretty flag icons.
*/
format: function(value) {
return Ox.Element({
element: '<img>',
tooltip: value
})
.addClass('flag')
.attr({
src: Ox.getFlagByGeoname(value)
})
},
id: 'country',
operator: '+',
title: 'Country',
titleImage: 'flag',
visible: true,
width: 16
},
{
format: function(value) {
return value
? $('<img>')
.addClass('capital')
.attr({
src: Ox.UI.getImageURL('symbolStar')
})
: '';
},
id: 'capital',
operator: '-',
title: 'Capital',
titleImage: 'star',
visible: true,
width: 16
},
{
/*
The format function has a second argument that
contains the values of all columns. This allows us
to format a value dependent on other values. In this
case, we want to display the name in bold if the
value for capital is true.
*/
format: function(value, data) {
return data.capital
? '<b>' + value + '</b>'
: value;
},
id: 'name',
operator: '+',
/*
As it wouldn't make much sense to display the list
without the name column, we make it non-removable.
*/
removable: false,
title: 'Name',
visible: true,
width: 128
},
{
/*
Since the following values are numbers, they should
be right-aligned. Also, we use some of the built-in
format functions.
*/
align: 'right',
format: function(value) {
return Ox.formatNumber(value);
},
id: 'population',
operator: '-',
title: 'Population',
visible: true,
width: 80
},
{
format: function(value) {
return Ox.formatDegrees(value, 'lat');
},
align: 'right',
id: 'lat',
operator: '-',
title: 'Latitude',
visible: true,
width: 80
},
{
format: function(value) {
return Ox.formatDegrees(value, 'lng');
},
align: 'right',
id: 'lng',
operator: '+',
title: 'Longitude',
visible: true,
width: 80
},
{
format: function(value) {
return Ox.formatNumber(value) + ' m';
},
align: 'right',
id: 'elevation',
operator: '-',
title: 'Elevation',
width: 80
}
],
/*
This allows the user to move the columns around
*/
columnsMovable: true,
/*
This enables the UI to show or hide specific columns
*/
columnsRemovable: true,
/*
This makes sure the column titles get displayed
*/
columnsVisible: true,
items: cities,
/*
FIXME: Actually, 'keys' doesn't make so much sense when the
API is local, since the list has been passed all data anyway
*/
keys: ['capital'],
max: 1,
scrollbarVisible: true,
/*
We have to specify the default sort order.
*/
sort: ['-population', '+name'],
sums: ['population']
})
.bindEvent({
closepreview: function() {
$preview.options({value: false});
$dialog.close();
},
init: function(data) {
$status.html(
(data.items ? Ox.formatNumber(data.items) : 'No')
+ ' Cit' + (data.items == 1 ? 'y' : 'ies')
+ ', Populaion: ' + (
data.population
? Ox.formatNumber(data.population)
: 'None'
)
);
},
open: function(data) {
$map.zoomToPlace();
},
openpreview: function(data) {
var item = Ox.getObjectById(cities, data.ids[0]);
$flagImage = $('<img>')
.attr({
src: Ox.getFlagByGeoname(item.country, 256)
});
$mapImage = Ox.MapImage({
height: 256,
markers: [item],
place: Ox.getCountryByGeoname(item.country),
width: 256
});
setImageSizes();
$preview.options({value: true});
$dialog.options({
content: $content = Ox.Element()
.attr({id: 'content'})
.append($flagImage)
.append($mapImage),
title: [item.name, item.country].join(', ')
}).open();
},
select: function(data) {
$preview.options({disabled: data.ids.length == 0});
$map.options({selected: data.ids[0]}).panToPlace();
}
}),
$flagImage,
$mapImage,
$content = Ox.Element(),
$dialog = Ox.Dialog({
closeButton: true,
content: $content,
fixedRatio: true,
focus: false,
height: 288,
maximizeButton: true,
maxHeight: 432,
maxWidth: 864,
minHeight: 144,
minWidth: 384,
width: 576
})
.bindEvent({
close: function() {
$list.closePreview();
},
resize: function(data) {
$content.css({height: data.height - 16 + 'px'})
setImageSizes();
}
}),
$status = $('<div>').css({
margin: '3px',
fontSize: '9px',
textAlign: 'center'
}),
$statusbar = Ox.Bar({size: 16}).append($status),
$map = Ox.Map({
clickable: true,
keys: ['population'],
markerColor: function(place) {
return place.population === void 0 ? [128, 128, 128]
: place.population > 10000000 ? [255, 0, 0]
: place.population > 5000000 ? [255, 32, 0]
: place.population > 2000000 ? [255, 64, 0]
: place.population > 1000000 ? [255, 96, 0]
: place.population > 500000 ? [255, 128, 0]
: place.population > 200000 ? [255, 160, 0]
: place.population > 100000 ? [255, 192, 0]
: place.population > 50000 ? [255, 224, 0]
: [255, 255, 0];
},
markerSize: function(place) {
return place.population === void 0 ? 16
: place.population > 10000000 ? 24
: place.population > 5000000 ? 22
: place.population > 2000000 ? 20
: place.population > 1000000 ? 18
: place.population > 500000 ? 16
: place.population > 200000 ? 14
: place.population > 100000 ? 12
: place.population > 50000 ? 10
: 8;
},
places: cities,
showControls: true,
showToolbar: true,
showZoombar: true
})
.bindEvent({
select: function(data) {
$list.options({
selected: data.place ? [data.place.id] : []
});
}
}),
$listPanel = Ox.SplitPanel({
elements: [
{element: $toolbar, size: 24},
{element: $list},
{element: $statusbar, size: 16}
],
orientation: 'vertical'
}),
$mainPanel = Ox.SplitPanel({
elements: [
{
element: $listPanel.bindEvent({
resize: function(data) {
$find.options({
width: data.size < 220
? data.size - 28
: 192
});
}
}),
resizable: true,
resize: [176, 256, 336, 416, 496].map(function(size) {
return size + Ox.UI.SCROLLBAR_SIZE;
}),
size: 416 + Ox.UI.SCROLLBAR_SIZE
},
{
element: $map.bindEvent({
resizeend: function(data) {
$map.resizeMap();
}
})
}
],
orientation: 'horizontal'
})
.appendTo(Ox.$body);
function setImageSizes() {
var size = Math.floor(($dialog.options('width') - 64) / 2);
[$flagImage, $mapImage].forEach(function($image) {
$image.css({width: size + 'px', height: size + 'px'});
});
}
Ox.$window.bind({
resize: function() {
$map.resizeMap();
}
});
});
});

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,74 @@
import json
import math
import re
from ox.geo import get_country
def read_table(source, target, keys, filter_=lambda x: True, map_=lambda x: x, sort_=lambda x: x):
def parse_value(str, t):
if type(t) == float:
str = float(str) if str else t
elif type(t) == int:
str = int(str) if str else t
return str
data = []
f = open(source)
for r, row in enumerate(f):
if row and row[0] != '#':
item = {}
cols = row[:-1].split('\t')
for c, col in enumerate(cols):
key = keys[c]
if type(key['type']) == list:
if col:
col = col.split(',')
value = map(lambda x: parse_value(x, key['type'][0]), col)
else:
value = []
else:
value = parse_value(col, key['type'])
item[key['name']] = value
if filter_(item):
data.append(map_(item))
data = sorted(data, key=sort_)
f = open(target, 'w')
f.write(json.dumps(data, indent=4, sort_keys=True))
f.close()
print len(data), 'cities'
# http://download.geonames.org/export/dump/
# http://www.geonames.org/export/codes.html
source = '../txt/cities1000.txt'
target = '../json/cities.json'
keys = [
{'name': 'geonameid', 'type': 0},
{'name': 'name', 'type': ''},
{'name': 'asciiname', 'type': ''},
{'name': 'alternatenames', 'type': ['']},
{'name': 'latitude', 'type': 0.0},
{'name': 'longitude', 'type': 0.0},
{'name': 'feature_class', 'type': ''},
{'name': 'feature_code', 'type': ''},
{'name': 'country_code', 'type': ''},
{'name': 'cc2', 'type': ['']},
{'name': 'admin1_code', 'type': ''},
{'name': 'admin2_code', 'type': ''},
{'name': 'admin3_code', 'type': ''},
{'name': 'admin4_code', 'type': ''},
{'name': 'population', 'type': 0},
{'name': 'elevation', 'type': 0},
{'name': 'gtopo30', 'type': 0},
{'name': 'timezone', 'type': ''},
{'name': 'modification_date', 'type': ''}
]
filter_ = lambda x: re.search('^PPL(C|A)$', x['feature_code']) or x['population'] >= 49589
def map_(x):
data = {}
for key in [
'country_code', 'elevation', 'feature_code'
'latitude', 'longitude', 'name', 'population'
]:
data[key] = x[key]
return data
sort_ = lambda x: -x['population']
read_table(source, target, keys, filter_, map_, sort_)

122949
examples/cities/txt/cities1000.txt Executable file

File diff suppressed because it is too large Load diff

View file

@ -1899,6 +1899,35 @@ Scrollbars
border-radius: 6px;
}
/*
================================================================================
SourceViewer
================================================================================
*/
.OxSourceViewer table {
border-collapse: collapse;
}
.OxSourceViewer td {
vertical-align: top;
}
.OxSourceViewer .OxComment {
padding: 4px 8px 4px 8px;
border-right-width: 1px;
border-right-style: solid;
font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console;
line-height: 16px;
//white-space: pre;
-moz-user-select: text;
-webkit-user-select: text;
}
.OxSourceViewer .OxComment pre {
font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console;
line-height: 16px;
margin: 0;
}
/*
================================================================================
SyntaxHightlighter
@ -1909,7 +1938,7 @@ SyntaxHightlighter
display: table-cell;
padding: 4px;
font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console;
//line-height: 14px;
line-height: 16px;
}
.OxSyntaxHighlighter > .OxLineNumbers {
text-align: right;

View file

@ -20,6 +20,8 @@ Ox.DocPanel <f> Documentation Panel
Ox.DocPanel = function(options, self) {
// FIXME: defaults should be falsy
self = self || {};
var that = Ox.Element({}, self)
.defaults({
@ -65,8 +67,8 @@ Ox.DocPanel = function(options, self) {
function loadList(callback) {
var counter = 0,
length = self.options.files.length,
docItems = [];
docItems = [],
length = self.options.files.length;
self.options.files.forEach(function(file) {
Ox.doc(self.options.path + file, function(fileItems) {

View file

@ -0,0 +1,137 @@
'use strict'
Ox.ExamplePage = function(options, self) {
self = self || {};
var that = Ox.Element({}, self)
.defaults({
html: '',
js: '',
replace: [],
selected: 'source',
title: ''
})
.options(options || {});
self.$toolbar = Ox.Bar({size: 24});
self.$title = Ox.Label({
title: self.options.title
})
.css({float: 'left', margin: '4px'})
.appendTo(self.$toolbar)
self.$reloadButton = Ox.Button({
disabled: self.options.selected == 'source',
title: 'redo',
tooltip: 'Reload',
type: 'image'
})
.css({float: 'right', margin: '4px 4px 4px 2px'})
.bindEvent({
click: function() {
self.$frame.attr({src: self.options.html});
}
})
.appendTo(self.$toolbar);
self.$tabs = Ox.ButtonGroup({
buttons: [
{
id: 'source',
title: 'View Source'
},
{
id: 'live',
title: 'View Live'
}
],
selectable: true,
value: self.options.selected
})
.css({float: 'right', margin: '4px 2px 4px 4px'})
.bindEvent({
change: function(data) {
self.options.selected = data.value;
self.$reloadButton.options({disabled: data.value == 'source'});
self.$content.animate({
marginLeft: data.value == 'source'
? 0 : -self.options.width + 'px'
}, 250, function() {
if (data.value == 'live' && !self.$frame.attr('src')) {
self.$frame.attr({src: self.options.html});
}
});
}
})
.appendTo(self.$toolbar);
self.$viewer = Ox.SourceViewer({
file: self.options.js,
replace: self.options.replace
})
.css({
position: 'absolute',
left: 0,
top: 0,
width: self.options.width + 'px',
height: self.options.height - 24 + 'px'
});
self.$frame = Ox.Element('<iframe>')
.css({
position: 'absolute',
left: self.options.width + 'px',
top: 0,
border: 0
})
.attr({
width: self.options.width,
height: self.options.height
});
self.$content = Ox.Element()
.css({
position: 'absolute',
width: self.options.width * 2 + 'px'
})
.append(self.$viewer)
.append(self.$frame)
self.$container = Ox.Element()
.append(self.$content)
that.setElement(
Ox.SplitPanel({
elements: [
{element: self.$toolbar, size: 24},
{element: self.$container}
],
orientation: 'vertical'
})
);
Ox.$window.bind({
resize: function() {
setSize();
}
});
setTimeout(setSize, 100);
function setSize() {
self.options.width = that.width();
self.options.height = that.height();
self.$content.css({
width: self.options.width * 2 + 'px',
})
self.$viewer.css({
width: self.options.width + 'px',
height: self.options.height - 24 + 'px'
})
self.$frame.attr({
width: self.options.width,
height: self.options.height - 24
});
}
return that;
};

View file

@ -0,0 +1,108 @@
'use strict';
Ox.ExamplePanel = function(options, self) {
self = self || {};
var that = Ox.Element({}, self)
.defaults({
collapsibe: false,
examples: [],
path: '',
replace: [],
resizable: false,
resize: [],
size: 256,
})
.options(options || {})
self.$list = Ox.Element();
self.$page = Ox.Element();
that.setElement(
self.$panel = Ox.SplitPanel({
elements: [
{
collapsible: self.options.collapsible,
element: self.$list,
resizable: self.options.resizable,
resize: self.options.resize,
size: self.options.size
},
{
element: self.$page
}
],
orientation: 'horizontal'
})
);
loadList(function(items) {
self.items = items;
self.$list = Ox.TextList({
columns: [
{
id: 'id',
unique: true
},
{
id: 'title',
operator: '+',
title: 'Title',
visible: true,
width: self.options.size - Ox.UI.SCROLLBAR_SIZE
}
],
items: self.items,
scrollbarVisible: true,
sort: ['+title']
})
.bindEvent({
select: function(data) {
var item;
if (data.ids.length) {
item = Ox.getObjectById(self.items, data.ids[0]);
self.$panel.replaceElement(1,
self.$page = Ox.ExamplePage({
height: window.innerHeight,
html: item.html,
js: item.js,
replace: self.options.replace,
title: item.title,
width: window.innerWidth - self.options.size
})
)
} else {
self.$page.empty()
}
}
});
self.$panel.replaceElement(0, self.$list);
that.triggerEvent('load', {});
});
function loadList(callback) {
var items = [];
self.options.examples.forEach(function(example) {
var file = self.options.path + example + '/index.html';
Ox.get(file, function(html) {
var keywords = html.match(/<meta name="keywords" content="(.+)"/),
title = html.match(/<title>(.+)<\/title>/);
items.push({
html: file,
id: example,
js: self.options.path + example + '/js/example.js',
keywords: keywords ? keywords[1].split(', ') : [],
title: title ? title[1] : 'Untitled'
});
items.length == self.options.examples.length && callback(items);
});
});
}
function parseExample() {
}
return that;
};

View file

@ -0,0 +1,77 @@
'use strict';
Ox.SourceViewer = function(options, self) {
self = self || {};
var that = Ox.Container({}, self)
.defaults({
file: '',
replace: []
})
.options(options)
.addClass('OxSourceViewer');
self.replace = Ox.merge(
[[
// removes indentation inside <pre> tags
/<pre>([\s\S]+)<\/pre>/g,
function(pre, text) {
var lines = trim(text).split('\n'),
indent = Ox.min(lines.map(function(line) {
var match = line.match(/^\s+/);
return match ? match[0].length : 0;
}));
return '<pre>' + lines.map(function(line) {
return line.substr(indent);
}).join('\n') + '</pre>';
}
]],
self.options.replace
);
Ox.print('RE', self.replace)
self.$table = $('<table>').appendTo(that.$content);
Ox.get(self.options.file, function(source) {
var sections = [{comment: '', code: ''}];
Ox.tokenize(source).forEach(function(token, i) {
var text = source.substr(token.offset, token.length),
type = token.type == 'comment' ? 'comment' : 'code';
if (type == 'comment') {
i && sections.push({comment: '', code: ''});
text = /^\/\*/.test(text)
? Ox.sub(text, 2, -2)
: Ox.sub(text, 2);
self.replace.forEach(function(replace) {
text = text.replace(replace[0], replace[1]);
});
}
Ox.last(sections)[type] += text;
});
sections.forEach(function(section) {
var $section = $('<tr>'),
$comment = $('<td>')
.addClass('OxComment')
.html(trim(section.comment)),
$code = $('<td>')
.addClass('OxCode')
.append(
Ox.SyntaxHighlighter({
source: trim(section.code)
})
)
$section
.append($comment)
.append($code)
.appendTo(self.$table);
});
});
function trim(str) {
// removes leading or trailing empty line
return str.replace(/^\s*\n/, '').replace(/\n\s*$/, '');
}
return that;
};

View file

@ -642,6 +642,19 @@ Scrollbars
background: rgb(208, 208, 208);
}
/*
================================================================================
SourceViewer
================================================================================
*/
.OxThemeClassic .OxSourceViewer .OxComment {
border-color: rgb(208, 208, 208);
}
.OxThemeClassic .OxSourceViewer .OxCode {
background-color: rgb(255, 255, 255);
}
/*
================================================================================
SyntaxHighlighter

View file

@ -628,6 +628,19 @@ Scrollbars
background: rgb(64, 64, 64);
}
/*
================================================================================
SourceViewer
================================================================================
*/
.OxThemeModern .OxSourceViewer .OxComment {
border-color: rgb(48, 48, 48);
}
.OxThemeModern .OxSourceViewer .OxCode {
background-color: rgb(0, 0, 0);
}
/*
================================================================================
SyntaxHighlighter