Add frontend assets and plugin bundles

Add the legacy frontend themes, scripts, and plugin assets required by the main SPOTA interfaces.
This commit is contained in:
Power BI Dev
2026-05-02 10:09:32 +07:00
parent efdb11db3f
commit a52c2a8462
2061 changed files with 513282 additions and 0 deletions

5
assets/plugins/summernote/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
# vim editing
*.swp
.tern-port
# node modules
node_modules

View File

@@ -0,0 +1,11 @@
language: node_js
node_js:
- 0.10
branches:
only:
- master
before_script:
- node --version
- npm --version
- npm install -g grunt-cli
script: grunt test --verbose

View File

@@ -0,0 +1,26 @@
module.exports = function(grunt) {
grunt.initConfig({
qunit: { all: [ 'test/*.html' ] },
uglify: {
my_target: {
files: { 'build/summernote.min.js': ['summernote.js'] }
}
},
recess: {
dist: {
options: { compile: true, compress: true },
files: {
'build/summernote.css': ['summernote.less']
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-recess');
grunt.registerTask('test', 'qunit');
grunt.registerTask('build', ['uglify', 'recess']);
grunt.registerTask('default', ['qunit', 'uglify', 'recess']);
};

View File

@@ -0,0 +1,154 @@
# Summernote
Super Simple WYSIWYG Editor on Bootstrap(3.0 and 2.x).
[![Build Status](https://secure.travis-ci.org/HackerWins/summernote.png)](http://travis-ci.org/HackerWins/summernote)
### Summernote
Summernote is a javascript program that helps you to create WYSIWYG Editor on web.
Demo Page: http://hackerwins.github.io/summernote/
### Why Summernote?
Summernote has something specials no like others.
Simple UI, Interative WYSIWYG editing, easy integrate Backend server and so much others.
#### Inspired by
* Gmail WYSIWYG Editor (http://www.gmail.com)
* Redactor (http://imperavi.com/redactor/)
### Easy to install
Summernote uses opensouce libraries(jQuery, bootstrap, fontAwesome)
#### 01. include js/css
Include Following code into `<head>` tag of your HTML:
```html
<!-- include libries(jQuery, bootstrap, fontawesome) -->
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<!-- bootstrap v3 -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css" />
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" />
<!-- bootstrap v2.x
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<link href="//netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.min.css" rel="stylesheet">
-->
<!-- include summernote css/js-->
<link rel="stylesheet" href="summernote.css" />
<script type="text/javascript" src="summernote.min.js"></script>
```
If your summernote download is placed in a different folder, don't forget to change file's paths.
#### 02. target elements
And place `div` tag to somewhere in the `body` tag. This element will be placed by the visual representation of the summernote.
```html
<div id="summernote">Hello Summernote</div>
```
#### 03. summernote
Finally, run script after document ready.
```javascript
$(document).ready(function() {
$('#summernote').summernote();
});
```
### API
Get HTML `code` if you need.
```javascript
var sHTML = $('#summernote').code();
```
`Destroy` summernote.
```javascript
$('#summernote').destroy();
```
#### Dependencies
* jQuery: http://jquery.com/
* bootstrap: http://twitter.github.io/bootstrap/
* fontAwesome: https://github.com/FortAwesome/Font-Awesome
### Supported platform
* Modern Browser (Safari, Chrome, Firefox, Opera, Internet Explorer 9+)
* OS (Windows, Mac)
### Upcoming Features
* Air Mode
* Responsive Toolbar
* Table: Handles(Sizing, Selection) and Popover
#### v0.4 2013-10-01
* Support both Bootstrap 3.0 and 2.x
* support IE8
* Image Upload
* Fullscreen
### Change Log
#### v0.3 2013-09-01
* `FIXED` bugs(image upload, fontsize, tab, recent color, ...)
* `ADDED` help dialog(keyboard shortcut)
* `ADDED` init options(event callbacks, custom toolbar)
* `ADDED` resize bar
* `ADDED` support IE8 Beta(some range bugs, can't insert Image)
#### v0.2, 2013-08-01
* `ADDED` undo/redo
* `ADDED` image sizing handle and popover
* `ADDED` support standalone css
* `ADDED` support Multiple Editor
* `REMOVED` jQuery.curstyles dependency
#### v0.1, 2013-07-01
* `ADDED` font style: size, color, bold, italic, underline, remove font style
* `ADDED` para style: bullet, align, outdent, indent, line height
* `ADDED` image: drag & drop, dialog
* `ADDED` link: popover and dialog
* `ADDED` table: create table with dimension picker
### for Hacker
#### structure of summernote.js
```
$.extend - Renderer (Markup)
\ EventHandler - Editor - Range (W3CRange extention)
\ Style (Style Getter and Setter)
\ History (Store on jQuery.data)
\ Toolbar
\ Popover
\ Handle
\ Dialog
----------Common Utils----------
Dom, List, Func
```
#### build summernote
```bash
# grunt-cli is need by grunt; you might have this installed already
npm install -g grunt-cli
npm install
grunt build
```
At this point, you should now have a `build/` directory populated with everything you need to use summernote.
#### test summernote
run tests with PhantomJS
```bash
grunt test
```
### Contacts
* Email: susukang98@gmail.com
* Twitter: http://twitter.com/hackerwins
### License
summernote may be freely distributed under the MIT license.

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>summernote</title>
<!-- include jquery -->
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<!-- include libraries BS2 -->
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<link href="//netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.min.css" rel="stylesheet">
<!-- include summernote -->
<link rel="stylesheet/less" type="text/css" href="summernote.less" />
<script type="text/javascript" src="summernote.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.summernote').summernote({height: 300, focus: true});
});
</script>
</head>
<body>
<div class="container">
<div class="summernote"></div>
</div>
<script type="text/javascript">
less = {
env: "development", // or "production"
async: false, // load imports async
fileAsync: false, // load imports async when in a page under
// a file protocol
poll: 1000, // when in watch mode, time in ms between polls
functions: {}, // user functions, keyed by name
dumpLineNumbers: "comments", // or "mediaQuery" or "all"
relativeUrls: false,// whether to adjust url's to be relative
// if false, url's are already relative to the
// entry less file
rootpath: ":/a.com/"// a path to add on to the start of every url
//resource
};
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.3.3/less.min.js" type="text/javascript"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,156 @@
/*---------------------------------------------------
LESS Elements 0.9
---------------------------------------------------
A set of useful LESS mixins
More info at: http://lesselements.com
---------------------------------------------------*/
.gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) {
background: @color;
background: -webkit-gradient(linear,
left bottom,
left top,
color-stop(0, @start),
color-stop(1, @stop));
background: -ms-linear-gradient(bottom,
@start,
@stop);
background: -moz-linear-gradient(center bottom,
@start 0%,
@stop 100%);
background: -o-linear-gradient(@stop,
@start);
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@stop,@start));
}
.bw-gradient(@color: #F5F5F5, @start: 0, @stop: 255) {
background: @color;
background: -webkit-gradient(linear,
left bottom,
left top,
color-stop(0, rgb(@start,@start,@start)),
color-stop(1, rgb(@stop,@stop,@stop)));
background: -ms-linear-gradient(bottom,
rgb(@start,@start,@start) 0%,
rgb(@stop,@stop,@stop) 100%);
background: -moz-linear-gradient(center bottom,
rgb(@start,@start,@start) 0%,
rgb(@stop,@stop,@stop) 100%);
background: -o-linear-gradient(rgb(@stop,@stop,@stop),
rgb(@start,@start,@start));
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",rgb(@stop,@stop,@stop),rgb(@start,@start,@start)));
}
.bordered(@top-color: #EEE, @right-color: #EEE, @bottom-color: #EEE, @left-color: #EEE) {
border-top: solid 1px @top-color;
border-left: solid 1px @left-color;
border-right: solid 1px @right-color;
border-bottom: solid 1px @bottom-color;
}
.drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) {
-webkit-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
-moz-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
}
.rounded(@radius: 2px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
.border-radius(@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {
-webkit-border-top-right-radius: @topright;
-webkit-border-bottom-right-radius: @bottomright;
-webkit-border-bottom-left-radius: @bottomleft;
-webkit-border-top-left-radius: @topleft;
-moz-border-radius-topright: @topright;
-moz-border-radius-bottomright: @bottomright;
-moz-border-radius-bottomleft: @bottomleft;
-moz-border-radius-topleft: @topleft;
border-top-right-radius: @topright;
border-bottom-right-radius: @bottomright;
border-bottom-left-radius: @bottomleft;
border-top-left-radius: @topleft;
.background-clip(padding-box);
}
.opacity(@opacity: 0.5) {
-webkit-opacity: @opacity;
-khtml-opacity: @opacity;
-moz-opacity: @opacity;
opacity: @opacity;
@opperc: @opacity * 100;
-ms-filter: ~"progid:DXImageTransform.Microsoft.Alpha(opacity=@{opperc})";
filter: ~"alpha(opacity=@{opperc})";
}
.transition-duration(@duration: 0.2s) {
-moz-transition-duration: @duration;
-webkit-transition-duration: @duration;
-o-transition-duration: @duration;
transition-duration: @duration;
}
.transform(...) {
-webkit-transform: @arguments;
-moz-transform: @arguments;
-o-transform: @arguments;
-ms-transform: @arguments;
transform: @arguments;
}
.rotation(@deg:5deg){
.transform(rotate(@deg));
}
.scale(@ratio:1.5){
.transform(scale(@ratio));
}
.transition(@duration:0.2s, @ease:ease-out) {
-webkit-transition: all @duration @ease;
-moz-transition: all @duration @ease;
-o-transition: all @duration @ease;
transition: all @duration @ease;
}
.inner-shadow(@horizontal:0, @vertical:1px, @blur:2px, @alpha: 0.4) {
-webkit-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
-moz-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
}
.box-shadow(@arguments) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}
.box-sizing(@sizing: border-box) {
-ms-box-sizing: @sizing;
-moz-box-sizing: @sizing;
-webkit-box-sizing: @sizing;
box-sizing: @sizing;
}
.user-select(@argument: none) {
-webkit-user-select: @argument;
-moz-user-select: @argument;
-ms-user-select: @argument;
user-select: @argument;
}
.columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) {
-moz-column-width: @colwidth;
-moz-column-count: @colcount;
-moz-column-gap: @colgap;
-moz-column-rule-color: @columnRuleColor;
-moz-column-rule-style: @columnRuleStyle;
-moz-column-rule-width: @columnRuleWidth;
-webkit-column-width: @colwidth;
-webkit-column-count: @colcount;
-webkit-column-gap: @colgap;
-webkit-column-rule-color: @columnRuleColor;
-webkit-column-rule-style: @columnRuleStyle;
-webkit-column-rule-width: @columnRuleWidth;
column-width: @colwidth;
column-count: @colcount;
column-gap: @colgap;
column-rule-color: @columnRuleColor;
column-rule-style: @columnRuleStyle;
column-rule-width: @columnRuleWidth;
}
.translate(@x:0, @y:0) {
.transform(translate(@x, @y));
}
.background-clip(@argument: padding-box) {
-moz-background-clip: @argument;
-webkit-background-clip: @argument;
background-clip: @argument;
}

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>summernote</title>
<!-- include jquery -->
<script src="//code.jquery.com/jquery-1.9.1.min.js"></script>
<!-- include libraries BS3 -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css" />
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" />
<!-- include summernote -->
<link rel="stylesheet/less" type="text/css" href="summernote.less" />
<script type="text/javascript" src="summernote.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.summernote').summernote({height: 300, focus: true, tabsize: 2});
});
</script>
</head>
<body>
<div class="container">
<h3>Bootstrap v3.0</h3>
<div class="summernote"></div>
<h3>Bootstrap v2.x</h3>
<iframe src="bs2.html" width="100%" height="300px" frameBorder="0"></iframe>
</div>
<script type="text/javascript">
less = {
env: "development", // or "production"
async: false, // load imports async
fileAsync: false, // load imports async when in a page under
// a file protocol
poll: 1000, // when in watch mode, time in ms between polls
functions: {}, // user functions, keyed by name
dumpLineNumbers: "comments", // or "mediaQuery" or "all"
relativeUrls: false,// whether to adjust url's to be relative
// if false, url's are already relative to the
// entry less file
rootpath: ":/a.com/"// a path to add on to the start of every url
//resource
};
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.3.3/less.min.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -0,0 +1,19 @@
{
"name": "Summernote",
"description": "Super Simple WYSIWYG Editor on Bootstrap",
"version": "0.1.0",
"repository": {
"type": "git",
"url": "https://github.com/HackerWins/summernote.git"
},
"author": {
"name": "Hackerwins",
"email": "<susukang98@gmail.com>"
},
"devDependencies": {
"grunt": "*",
"grunt-contrib-qunit": "*",
"grunt-contrib-uglify": "~0.2.2",
"grunt-recess": "*"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,352 @@
@import "elements.less";
/* Theme Variables
------------------------------------------*/
@border-color: #a9a9a9;
@background-color: #f5f5f5;
/* Layout
------------------------------------------*/
.note-editor {
border: 1px solid @border-color;
/* fullscreen mode */
&.fullscreen {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1050; /* bs3 modal-backdrop: 1030, bs2: 1040 */
.note-editable {
background-color: white;
}
.note-resizebar {
display: none;
}
}
/* toolbar */
.note-toolbar {
padding-left: 5px;
padding-bottom: 5px;
margin: 0;
background-color: @background-color;
border-bottom: 1px solid @border-color;
&>.btn-group {
margin-top: 5px;
margin-left: 0;
margin-right: 5px;
}
.note-table {
.dropdown-menu {
min-width: 0;
padding: 5px;
.note-dimension-picker {
font-size: 18px;
.note-dimension-picker-mousecatcher {
position: absolute !important;
z-index: 3;
width: 10em;
height: 10em;
cursor: pointer;
}
.note-dimension-picker-unhighlighted {
position: relative !important;
z-index: 1;
width: 5em;
height: 5em;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIj4+Pjp6ekKlAqjAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKhmnaJzPAAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;
}
.note-dimension-picker-highlighted {
position: absolute !important;
z-index: 2;
width: 1em;
height: 1em;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASAgMAAAAroGbEAAAACVBMVEUAAIjd6vvD2f9LKLW+AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfYAR0BKwNDEVT0AAAAG0lEQVQI12NgAAOtVatWMTCohoaGUY+EmIkEAEruEzK2J7tvAAAAAElFTkSuQmCC') repeat;
}
}
}
}
.note-style {
h1, h2, h3, h4, h5, h6, blockquote {
margin: 0;
}
}
.note-fontsize {
button {
height: 26px;
}
}
.note-color {
.dropdown-toggle {
width: 20px;
padding: 2px 5px;
}
.dropdown-menu {
min-width: 290px;
.btn-group {
margin: 0;
&:first-child {
margin: 0 5px;
}
.note-palette-title {
font-size: 12px;
}
}
}
}
.note-para {
.dropdown-menu {
min-width: 153px;
padding: 5px;
}
li:first-child {
margin-bottom: 5px;
}
}
}
.note-statusbar {
background-color: @background-color;
.note-resizebar {
height: 8px;
width: 100%;
border-top: 1px solid @border-color;
cursor: s-resize;
.note-icon-bar {
width: 20px;
margin: 1px auto;
border-top: 1px solid @border-color;
}
}
}
// popover
.note-popover .popover {
max-width: none;
.popover-content {
padding: 5px;
a {
display: inline-block;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* for FF */
vertical-align: middle; /* for FF */
}
.btn-group+.btn-group {
margin-left: 5px;
}
}
& .arrow {
left: 20px;
}
}
/* note handle */
.note-handle {
/* control selection */
.note-control-selection {
position: absolute;
display: none;
border: 1px solid black;
&>div { position: absolute; }
.note-control-selection-bg {
width: 100%;
height: 100%;
background-color: black;
.opacity(0.30)
}
.note-control-handle {
width: 7px;
height: 7px;
border: 1px solid black;
}
.note-control-holder {
.note-control-handle;
}
.note-control-sizing {
.note-control-handle;
background-color: white;
}
.note-control-nw {
top: -5px;
left: -5px;
border-right: none;
border-bottom: none;
}
.note-control-ne {
top: -5px;
right: -5px;
border-bottom: none;
border-left: none;
}
.note-control-sw {
bottom: -5px;
left: -5px;
border-top: none;
border-right: none;
}
.note-control-se {
right: -5px;
bottom: -5px;
cursor: se-resize;
}
.note-control-selection-info {
right: 0;
bottom: 0;
padding: 5px;
margin: 5px;
color: white;
background-color: black;
font-size: 12px;
.rounded(5px);
.opacity(0.7);
}
}
}
/* dialog */
.note-dialog {
&>div {
display: none; /* BS2's hide pacth. */
}
.note-image-dialog {
.note-dropzone {
min-height: 200px;
font-size: 30px;
line-height: 6; /* vertical-align */
color: lightgray;
text-align: center;
border: 4px dashed lightgray;
}
}
.note-help-dialog {
@note-shortcut-hl: #dd0;
font-size: 12px;
color: white;
background-color: black !important;
.opacity(0.9);
.modal-content {
background: transparent;
border: 1px solid white;
.box-shadow(none);
.rounded(5px);
}
/* BS2's background pacth. */
background: transparent;
border: none;
a {
font-size: 12px;
color: white;
}
.title {
color: white;
font-size: 14px;
font-weight: bold;
padding-bottom: 5px;
border-bottom: white 1px solid;
}
.modal-close {
font-size: 14px;
color: @note-shortcut-hl;
cursor: pointer;
}
.note-shortcut-layout {
width: 100%;
td {
vertical-align: top;
}
}
.note-shortcut {
margin-top: 8px;
th {
text-align: left;
font-size: 13px;
color: @note-shortcut-hl;
}
td:first-child {
min-width: 110px;
font-family: "Courier New";
color: @note-shortcut-hl;
text-align: right;
padding-right: 10px
}
}
}
}
/* editable */
.note-editable {
padding: 10px;
overflow: scroll;
outline: none;
}
/* dropdown-menu for toolbar and popover */
.dropdown-menu {
min-width: 90px;
/* dropdown-menu right position */
/* http://forrst.com/posts/Bootstrap_right_positioned_dropdown-2KB */
&.right {
right: 0;
left: auto;
&::before { right: 9px; left: auto !important; }
&::after { right: 10px; left: auto !important; }
}
/* dropdown-menu for selectbox */
li a i {
color: deepskyblue;
visibility: hidden;
}
li a.checked i {
visibility: visible;
}
}
/* buttons for toolbar and popover */
.btn-sm {
min-height: 33px;
font-size: 14px;
}
/* color palette for toolbar and popover */
.note-color-palette {
line-height: 1;
div {
.note-color-btn {
width: 17px;
height: 17px;
padding: 0;
margin: 0;
border: 1px solid #fff;
}
.note-color-btn:hover {
border: 1px solid #000;
}
}
}
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>summernote :: dom.spec</title>
<link rel="stylesheet" href="qunit-1.11.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="qunit-1.11.0.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="../summernote.js"></script>
<script src="dom.spec.js"></script>
</body>
</html>

View File

@@ -0,0 +1,207 @@
/**
* dom.spec.js
* (c) 2013~ Alan Hong
* summernote may be freely distributed under the MIT license./
*/
var dom = $.fn.summernoteInner().dom,
func = $.fn.summernoteInner().func;
test('dom.ancestor', function() {
var $cont, $b, elB;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), elB = $b[0].firstChild;
equal(dom.ancestor(elB, dom.isB), $b[0], 'find ancestor B');
equal(dom.ancestor(elB, dom.isDiv), $cont[0], 'find ancestor DIV');
equal(dom.ancestor(elB, dom.isU), null, 'find ancestor U: null');
});
test('dom.listAncestor', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><i><s><u><b>b</b></u></s></i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
deepEqual(dom.listAncestor($b[0], function(node) {
return node === $i[0];
}), [$b[0], $u[0], $s[0], $i[0]], 'listAncestor from b to i');
deepEqual(dom.listAncestor($u[0], function(node) {
return node === $s[0];
}), [$u[0], $s[0]], 'listAncestor from u to s');
});
test('dom.commonAncestor', function() {
var $cont, $b, elB;
$cont = $('<div><span><b>b</b><u>u</u></span><span><s>s</s><i>i</i></span></div>');
$span = $cont.find('span');
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
equal(dom.commonAncestor($b[0], $u[0]), $span[0], 'common(b, u) => span');
equal(dom.commonAncestor($b[0], $s[0]), $cont[0], 'common(b, s) => div');
});
test('dom.listBetween', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
deepEqual(dom.listBetween($b[0], $b[0]), [$b[0]], 'same elements');
deepEqual(dom.listBetween($b[0], $u[0]), [$b[0], $b[0].firstChild, $u[0]], 'adjacent');
deepEqual(dom.listBetween($b[0], $s[0]), [$b[0], $b[0].firstChild,
$u[0], $u[0].firstChild,
$s[0]], 'distance 2');
});
test('dom.listNext', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
deepEqual(dom.listNext($u[0]), [$u[0], $s[0], $i[0]], 'with no pred');
deepEqual(dom.listNext($i[0]), [$i[0]], 'last item with no pred');
deepEqual(dom.listNext($s[0], func.eq($i[0])), [$s[0], $i[0]], 's to i');
});
test('dom.listPrev', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
deepEqual(dom.listPrev($s[0]), [$s[0], $u[0], $b[0]], 'with no pred');
deepEqual(dom.listPrev($b[0]), [$b[0]], 'first item with no pred');
deepEqual(dom.listPrev($i[0], func.eq($s[0])), [$i[0], $s[0]], 'i to s');
});
test('dom.position', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
equal(dom.position($b[0]), 0, 'should b return zero');
equal(dom.position($u[0]), 1, 'should u return one');
equal(dom.position($s[0]), 2, 'should s return three');
equal(dom.position($i[0]), 3, 'should i return four');
equal(dom.position($b[0].firstChild), 0, 'should text in b return zero');
});
test('dom.makeOffsetPath', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
deepEqual(dom.makeOffsetPath($cont[0], $cont[0]), [], 'should return empty list');
deepEqual(dom.makeOffsetPath($cont[0], $b[0]), [0], 'should return [0]');
deepEqual(dom.makeOffsetPath($cont[0], $b[0].firstChild), [0, 0], 'should return [0, 0]');
deepEqual(dom.makeOffsetPath($cont[0], $u[0]), [1], 'shuold return [1]');
deepEqual(dom.makeOffsetPath($cont[0], $u[0].firstChild), [1, 0], 'shuold return [1, 0]');
deepEqual(dom.makeOffsetPath($cont[0], $s[0]), [2], 'shuold return [2]');
deepEqual(dom.makeOffsetPath($cont[0], $s[0].firstChild), [2, 0], 'shuold return [2, 0]');
deepEqual(dom.makeOffsetPath($cont[0], $i[0]), [3], 'shuold return [3]');
deepEqual(dom.makeOffsetPath($cont[0], $i[0].firstChild), [3, 0], 'shuold return [3, 0]');
});
test('dom.fromOffsetPath', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
var cont = $cont[0];
$.each([$b[0], $u[0], $s[0], $i[0]], function(idx, node) {
equal(dom.fromOffsetPath(cont, dom.makeOffsetPath(cont, node)), node);
var child = node.firstChild;
equal(dom.fromOffsetPath(cont, dom.makeOffsetPath(cont, child)), child);
});
});
var equalsToUpperCase = function(actual, expected, comment) {
ok(actual.toUpperCase() == expected.toUpperCase(), comment);
};
test('dom.split', function() {
var $cont, $b, $u, $s, $i;
// 01. element pivot case
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$u = $cont.find('u');
dom.split($cont[0], $u[0], 0);
equalsToUpperCase($cont.html(), '<b>b</b>', 'splitBy u tag with offset 0');
equalsToUpperCase($cont.next().html(), '<u>u</u><s>s</s><i>i</i>', 'right hand side');
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$u = $cont.find('u');
dom.split($cont[0], $u[0], 1);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u>', 'splitBy u tag with offset 1');
equalsToUpperCase($cont.next().html(), '<s>s</s><i>i</i>', 'right hand side');
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b');
dom.split($cont[0], $b[0], 0);
equalsToUpperCase($cont.html(), '', 'splitBy b tag with offset 0 (left edge case)');
equalsToUpperCase($cont.next().html(), '<b>b</b><u>u</u><s>s</s><i>i</i>', 'right hand side');
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$i = $cont.find('i');
dom.split($cont[0], $i[0], 1);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u><s>s</s><i>i</i>', 'splitBy i tag with offset 1 (right edge case)');
equalsToUpperCase($cont.next().html(), '', 'right hand side');
// textNode pivot case
$cont = $('<div><b>b</b><u>u</u><s>strike</s><i>i</i></div>'); //bustrikei
$s = $cont.find('s');
dom.split($cont[0], $s[0].firstChild, 3);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u><s>str</s>', 'splitBy s tag with offset 3 (middle case)');
equalsToUpperCase($cont.next().html(), '<s>ike</s><i>i</i>', 'right hand side');
$cont = $('<div><b>b</b><u>u</u><s>strike</s><i>i</i></div>'); //bustrikei
$s = $cont.find('s');
dom.split($cont[0], $s[0].firstChild, 0);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u><s></s>', 'splitBy s tag with offset 0 (left edge case)');
equalsToUpperCase($cont.next().html(), '<s>strike</s><i>i</i>', 'right hand side');
$cont = $('<div><b>b</b><u>u</u><s>strike</s><i>i</i></div>'); //bustrikei
$s = $cont.find('s');
dom.split($cont[0], $s[0].firstChild, 6);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u><s>strike</s>', 'splitBy s tag with offset 6 (right edge case)');
equalsToUpperCase($cont.next().html(), '<s></s><i>i</i>', 'right hand side');
$cont = $('<div><b>b</b><u>u</u><s>strike</s><i>i</i></div>'); //bustrikei
$s = $cont.find('s');
dom.split($s[0], $s[0].firstChild, 3);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u><s>str</s><s>ike</s><i>i</i>', 'splitBy s tag with offset 3 (2 depth case)');
$cont = $('<div><b>b</b><u>u</u><s>strike</s><i>i</i></div>'); //bustrikei
$s = $cont.find('s');
dom.split($s[0].firstChild, $s[0].firstChild, 3);
equalsToUpperCase($cont.html(), '<b>b</b><u>u</u><s>strike</s><i>i</i>', 'splitBy s tag with offset 3 (1 depth, textNode case)');
$cont = $('<div><span><b>b</b><u>u</u><s>s</s><i>i</i></span></div>'); //busi
$span = $cont.find('span');
dom.split($span[0], $span[0], 2);
equalsToUpperCase($cont.html(), '<span><b>b</b><u>u</u></span><span><s>s</s><i>i</i></span>', 'splitBy span tag with offset 2 (1 depth, element case)');
});

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>summernote :: list.spec</title>
<link rel="stylesheet" href="qunit-1.11.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="qunit-1.11.0.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="../summernote.js"></script>
<script src="list.spec.js"></script>
</body>
</html>

View File

@@ -0,0 +1,53 @@
/**
* list.spec.js
* (c) 2013~ Alan Hong
* summernote may be freely distributed under the MIT license./
*/
var list = $.fn.summernoteInner().list;
test('list.head', function() {
deepEqual(list.head([1, 2, 3]), 1, 'should return the first element');
});
test('list.last', function() {
deepEqual(list.last([1, 2, 3]), 3, 'should return the last element');
});
test('list.initial', function() {
deepEqual(list.initial([1, 2, 3]), [1, 2], 'should exclude last element');
});
test('list.tail', function() {
deepEqual(list.tail([1, 2, 3]), [2, 3], 'should exclude first element');
});
test('list.sum', function() {
deepEqual(list.sum([1, 2, 3]), 6, 'should return 6');
deepEqual(list.sum([1, 2, 3], function(v) { return v * 2; }), 12, 'should return 12');
});
test('list.from', function() {
var $cont, $b, $u, $s, $i;
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); //busi
$b = $cont.find('b'), $u = $cont.find('u'),
$s = $cont.find('s'), $i = $cont.find('i');
deepEqual(list.from($cont[0].childNodes),
[$b[0], $u[0], $s[0], $i[0]], 'should return array of childNodes');
});
test('list.clusterBy', function() {
var aaClustered = list.clusterBy([1, 1, 2, 2, 3], function(itemA, itemB) {
return itemA === itemB;
});
deepEqual([[1, 1], [2, 2], [3]], aaClustered, 'should cluster by equality 1');
var aaClustered = list.clusterBy([1, 2, 2, 1, 3], function(itemA, itemB) {
return itemA === itemB;
});
deepEqual([[1], [2, 2], [1], [3]], aaClustered, 'should cluster by equality 2');
});
test('list.compact', function() {
deepEqual(list.compact([0, 1, false, 2, '', 3]), [1,2,3], 'falsey values of `array` removed');
});

View File

@@ -0,0 +1,244 @@
/**
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
-webkit-border-top-right-radius: 5px;
-webkit-border-top-left-radius: 5px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-testrunner-toolbar label {
display: inline-block;
padding: 0 .5em 0 .1em;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
overflow: hidden;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
#qunit-modulefilter-container {
float: right;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests li .runtime {
float: right;
font-size: smaller;
}
.qunit-assert-list {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.qunit-collapsed {
display: none;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
padding: 5px;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #3c510c;
background-color: #fff;
border-left: 10px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>summernote :: dom.spec</title>
<link rel="stylesheet" href="qunit-1.11.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="qunit-1.11.0.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="../summernote.js"></script>
<script src="range.spec.js"></script>
</body>
</html>

View File

@@ -0,0 +1,36 @@
/**
* range.spec.js
* (c) 2013~ Alan Hong
* summernote may be freely distributed under the MIT license./
*/
var range = $.fn.summernoteInner().range;
test('rng.listPara', function() {
var $cont, $b, elB, rng;
//01. 1 depth
$cont = $('<div><p>para1</p><p>para2</p></div>');
$para = $cont.find('p');
rng = range.create($para[0].firstChild, 0, $para[1].firstChild, 1);
equal(rng.listPara().length, 2, 'should listPara return array of paragraphs[2]');
rng = range.create($para[0].firstChild, 0, $para[0].firstChild, 0);
equal(rng.listPara().length, 1, 'should listPara return array of a para');
//02. multi depth
$cont = $('<div><p>p<b>ar</b>a1</p><p>para2</p></div>');
$b = $cont.find('b');
rng = range.create($b[0].firstChild, 0, $b[0].firstChild, 0);
equal(rng.listPara().length, 1, 'should listPara return array of a para');
//03. on list, on heading
$cont = $('<div><ul><li>para1</li><li>para2</li></ul></div>');
$li = $cont.find('li');
rng = range.create($li[0].firstChild, 0, $li[1].firstChild, 1);
equal(rng.listPara().length, 2, 'should listPara return array of list paragraphs');
$cont = $('<div><h1>heading1</h1><h2>heading2</h2></div>');
$h1 = $cont.find('h1'), $h2 = $cont.find('h2');
rng = range.create($h1[0].firstChild, 0, $h2[0].firstChild, 1);
equal(rng.listPara().length, 2, 'should listPara return array of list paragraphs');
});