[aloha] upgraded to 0.22.7 and added textcolor plugin
* textcolor: fixed plugin bugs, added translation for zh * image: fixed default.jpg src bug * added 'ru' support for seaf edit * rm aloha-0.22.3 and ununsed files in aloha-0.22.7
Before Width: | Height: | Size: 5.6 KiB |
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* jsTree browser theme 1.0
|
||||
* Supported features: dots/no-dots, icons/no-icons, focused, loading
|
||||
* Supported plugins: ui (hovered, clicked), checkbox, contextmenu, search
|
||||
*/
|
||||
|
||||
.jstree li a {
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.jstree-browser li > ins {
|
||||
cursor: pointer;
|
||||
background: url(../img/arrow-315-medium.png) no-repeat center center;
|
||||
}
|
||||
|
||||
/*
|
||||
.jstree-browser ins { background-image:url("xd.png"); background-repeat:no-repeat; background-color:transparent; }
|
||||
.jstree-browser li { background-position:-90px 0; background-repeat:repeat-y; border-left: 1px dotted #ccc; }
|
||||
*/
|
||||
.jstree-browser li {
|
||||
margin-left: 10px;
|
||||
padding-left: 5px;
|
||||
border-left: 1px dotted #ccc;
|
||||
}
|
||||
.jstree-browser li.jstree-last { background:transparent; }
|
||||
.jstree-browser > ul:first-child > li { border-left-width: 0; }
|
||||
|
||||
.jstree-browser li > ins {
|
||||
background: transparent no-repeat center center;
|
||||
opacity: 0.7;
|
||||
filter: alpha(opacity=70);
|
||||
}
|
||||
.jstree-browser li > ins:hover {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.jstree-browser li.jstree-open > ins {
|
||||
background-image: url(../img/arrow-315-medium.png);
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.jstree-browser li.jstree-closed > ins {
|
||||
background-image: url(../img/arrow-000-medium.png);
|
||||
}
|
||||
.jstree-browser li.jstree-leaf > ins {
|
||||
background-image: url(../img/control-stop-square-small.png);
|
||||
}
|
||||
/*
|
||||
.jstree-browser .jstree-hovered { background:#f9d53f; border:1px solid #f7b940; }
|
||||
.jstree-browser .jstree-clicked { background:#88c7ea; border:1px solid #48a3d2; }
|
||||
*/
|
||||
.jstree-browser .jstree-hovered {
|
||||
color: #303539;
|
||||
}
|
||||
.jstree-browser .jstree-clicked {
|
||||
}
|
||||
.jstree-browser .jstree-hovered.jstree-clicked {
|
||||
}
|
||||
|
||||
/* Folder */
|
||||
.jstree-browser a .jstree-icon {
|
||||
background: url(../img/folder-horizontal-open.png) no-repeat center center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.jstree-browser a.jstree-loading .jstree-icon { background:url(../img/throbber.gif) center center no-repeat !important; }
|
||||
.jstree-browser a.jstree-clicked .jstree-icon {
|
||||
background-image: url(../img/folder-open.png);
|
||||
}
|
||||
|
||||
/* IE6 BEGIN */
|
||||
/*
|
||||
.jstree-browser li,
|
||||
.jstree-browser ins,
|
||||
#vakata-dragged.jstree-browser .jstree-invalid,
|
||||
#vakata-dragged.jstree-browser .jstree-ok,
|
||||
#jstree-marker.jstree-browser { _background-image:url("d.gif"); }
|
||||
.jstree-browser .jstree-open ins { _background-position:-72px 0; }
|
||||
.jstree-browser .jstree-closed ins { _background-position:-54px 0; }
|
||||
.jstree-browser .jstree-leaf ins { _background-position:-36px 0; }
|
||||
.jstree-browser a ins.jstree-icon { _background-position:-56px -19px; }
|
||||
#vakata-contextmenu.jstree-browser-context ins { _display:none; }
|
||||
#vakata-contextmenu.jstree-browser-context li { _zoom:1; }
|
||||
.jstree-browser .jstree-undetermined a .jstree-checkbox { _background-position:-20px -19px; }
|
||||
.jstree-browser .jstree-checked a .jstree-checkbox { _background-position:-38px -19px; }
|
||||
.jstree-browser .jstree-unchecked a .jstree-checkbox { _background-position:-2px -19px; }
|
||||
*/
|
||||
/* IE6 END */
|
@@ -1,756 +0,0 @@
|
||||
/*Grid*/
|
||||
.ui-jqgrid {position: relative; font-size:11px; border: 0;}
|
||||
.ui-jqgrid .ui-jqgrid-view {position: relative;left:0px; top: 0px; padding: .0em;}
|
||||
/* caption*/
|
||||
.ui-jqgrid .ui-jqgrid-titlebar {padding: .3em .2em .2em .3em; position: relative; border-left: 0px none;border-right: 0px none; border-top: 0px none;}
|
||||
.ui-jqgrid .ui-jqgrid-title { float: left; margin: .1em 0 .2em; }
|
||||
.ui-jqgrid .ui-jqgrid-titlebar-close { position: absolute;top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height:18px;}.ui-jqgrid .ui-jqgrid-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-jqgrid .ui-jqgrid-titlebar-close:hover { padding: 0; }
|
||||
/* header*/
|
||||
.ui-jqgrid .ui-jqgrid-hdiv {position: relative; margin: 0em;padding: 0em; overflow-x: hidden; overflow-y: auto; border-left: 0px none; border-top : 0px none; border-right : 0px none;}
|
||||
.ui-jqgrid .ui-jqgrid-hbox {float: left; padding-right: 20px;}
|
||||
.ui-jqgrid .ui-jqgrid-htable {table-layout:fixed;margin:0em;}
|
||||
.ui-jqgrid .ui-jqgrid-htable th {height:22px;padding: 2px 2px 0 2px;}
|
||||
.ui-jqgrid .ui-jqgrid-htable th div {overflow: hidden; position:relative; height:17px;}
|
||||
.ui-th-column, .ui-jqgrid .ui-jqgrid-htable th.ui-th-column {overflow: hidden;white-space: nowrap;text-align:center;border-top : 0px none;border-bottom : 0px none;}
|
||||
.ui-th-ltr, .ui-jqgrid .ui-jqgrid-htable th.ui-th-ltr {border-left : 0px none;}
|
||||
.ui-th-rtl, .ui-jqgrid .ui-jqgrid-htable th.ui-th-rtl {border-right : 0px none;}
|
||||
.ui-jqgrid .ui-th-div-ie {white-space: nowrap; zoom :1; height:17px;}
|
||||
.ui-jqgrid .ui-jqgrid-resize {height:20px;position: relative; cursor :e-resize;display: inline;overflow: hidden;}
|
||||
.ui-jqgrid .ui-grid-ico-sort {overflow:hidden;position:absolute;display:inline; cursor: pointer;}
|
||||
.ui-jqgrid .ui-icon-asc {margin-top:-3px; height:12px;}
|
||||
.ui-jqgrid .ui-icon-desc {margin-top:3px;height:12px;}
|
||||
.ui-jqgrid .ui-i-asc {margin-top:0px;height:16px;}
|
||||
.ui-jqgrid .ui-i-desc {margin-top:0px;margin-left:13px;height:16px;}
|
||||
.ui-jqgrid tr.ui-search-toolbar th { border-top-width: 1px; border-top-color: inherit; border-top-style: ridge }
|
||||
tr.ui-search-toolbar input {margin: 1px 0px 0px 0px}
|
||||
tr.ui-search-toolbar select {margin: 1px 0px 0px 0px}
|
||||
/* body */
|
||||
.ui-jqgrid .ui-jqgrid-bdiv {position: relative; margin: 0em; padding:0; overflow: auto; text-align:left;}
|
||||
.ui-jqgrid .ui-jqgrid-btable {table-layout:fixed; margin:0em;}
|
||||
.ui-jqgrid tr.jqgrow { outline-style: none; background: none; }
|
||||
.ui-jqgrid tr.jqgrow td {font-weight: normal; overflow: hidden; white-space: pre; height: 22px;padding: 0 2px 0 2px;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
||||
.ui-jqgrid tr.jqgfirstrow td {padding: 0 2px 0 2px;border-right-width: 1px; border-right-style: solid;}
|
||||
.ui-jqgrid tr.jqgroup td {font-weight: normal; overflow: hidden; white-space: pre; height: 22px;padding: 0 2px 0 2px;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
||||
.ui-jqgrid tr.jqfoot td {font-weight: bold; overflow: hidden; white-space: pre; height: 22px;padding: 0 2px 0 2px;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
||||
.ui-jqgrid tr.ui-row-ltr td {text-align:left;border-right-width: 1px; border-right-color: inherit; border-right-style: solid;}
|
||||
.ui-jqgrid tr.ui-row-rtl td {text-align:right;border-left-width: 1px; border-left-color: inherit; border-left-style: solid;}
|
||||
.ui-jqgrid td.jqgrid-rownum { padding: 0 2px 0 2px; margin: 0px; border: 0px none;}
|
||||
.ui-jqgrid .ui-jqgrid-resize-mark { width:2px; left:0; background-color:#777; cursor: e-resize; cursor: col-resize; position:absolute; top:0; height:100px; overflow:hidden; display:none; border:0 none;}
|
||||
/* footer */
|
||||
.ui-jqgrid .ui-jqgrid-sdiv {position: relative; margin: 0em;padding: 0em; overflow: hidden; border-left: 0px none; border-top : 0px none; border-right : 0px none;}
|
||||
.ui-jqgrid .ui-jqgrid-ftable {table-layout:fixed; margin-bottom:0em;}
|
||||
.ui-jqgrid tr.footrow td {font-weight: bold; overflow: hidden; white-space:nowrap; height: 21px;padding: 0 2px 0 2px;border-top-width: 1px; border-top-color: inherit; border-top-style: solid;}
|
||||
.ui-jqgrid tr.footrow-ltr td {text-align:left;border-right-width: 1px; border-right-color: inherit; border-right-style: solid;}
|
||||
.ui-jqgrid tr.footrow-rtl td {text-align:right;border-left-width: 1px; border-left-color: inherit; border-left-style: solid;}
|
||||
/* Pager*/
|
||||
.ui-jqgrid .ui-jqgrid-pager { border-left: 0px none;border-right: 0px none; border-bottom: 0px none; margin: 0px; padding: 0px; position: relative; height: 40px;white-space: nowrap;overflow: hidden;}
|
||||
.ui-jqgrid .ui-pager-control {position: relative;}
|
||||
.ui-jqgrid .ui-pg-table {position: relative; padding-bottom:2px; width:auto; margin: 0em;}
|
||||
.ui-jqgrid .ui-pg-table td {font-weight:normal; vertical-align:middle; padding:1px;}
|
||||
.ui-jqgrid .ui-pg-button { height:19px;}
|
||||
.ui-jqgrid .ui-pg-button span { display: block; margin: 1px; float:left;}
|
||||
.ui-jqgrid .ui-pg-button span.ui-separator { display: none;}
|
||||
.ui-jqgrid .ui-pg-button:hover { padding: 0px; }
|
||||
.ui-jqgrid .ui-state-disabled:hover {padding:1px;}
|
||||
.ui-jqgrid .ui-pg-input { height:13px;font-size:.8em; margin: 0em;}
|
||||
.ui-jqgrid .ui-pg-selbox {font-size:.8em; line-height:18px; display:block; height:18px; margin: 0em;}
|
||||
.ui-jqgrid .ui-separator {display: none; height: 18px; border-left: 1px solid #ccc ; border-right: 1px solid #ccc ; margin: 1px; float: right;}
|
||||
.ui-jqgrid .ui-paging-info {font-weight: normal; height: 19px; margin: 0; line-height: 1em; padding-right: 10px;}
|
||||
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div {padding:1px 0;float:left;list-style-image:none;list-style-position:outside;list-style-type:none;position:relative;}
|
||||
.ui-jqgrid .ui-jqgrid-pager .ui-pg-button { cursor:pointer; }
|
||||
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div span.ui-icon {float:left;margin:0 2px;}
|
||||
.ui-jqgrid td input, .ui-jqgrid td select .ui-jqgrid td textarea { margin: 0em;}
|
||||
.ui-jqgrid td textarea {width:auto;height:auto;}
|
||||
.ui-jqgrid .ui-jqgrid-toppager {border-left: 0px none;border-right: 0px none; border-top: 0px none; margin: 0px; padding: 0px; position: relative; height: 25px;white-space: nowrap;overflow: hidden;}
|
||||
/*subgrid*/
|
||||
.ui-jqgrid .ui-jqgrid-btable .ui-sgcollapsed span {display: block;}
|
||||
.ui-jqgrid .ui-subgrid {margin:0em;padding:0em; width:100%;}
|
||||
.ui-jqgrid .ui-subgrid table {table-layout: fixed;}
|
||||
.ui-jqgrid .ui-subgrid tr.ui-subtblcell td {height:18px;border-right-width: 1px; border-right-color: inherit; border-right-style: solid;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
||||
.ui-jqgrid .ui-subgrid td.subgrid-data {border-top: 0px none;}
|
||||
.ui-jqgrid .ui-subgrid td.subgrid-cell {border-width: 0px 0px 1px 0px;}
|
||||
.ui-jqgrid .ui-th-subgrid {height:20px;}
|
||||
/* loading */
|
||||
.ui-jqgrid .loading {position: absolute; top: 45%;left: 45%;width: auto;z-index:101;padding: 6px; margin: 5px;text-align: center;font-weight: bold;display: none;border-width: 2px;}
|
||||
.ui-jqgrid .jqgrid-overlay {display:none;z-index:100;}
|
||||
* html .jqgrid-overlay {
|
||||
width: ~"expression(this.parentNode.offsetWidth+'px')";
|
||||
height: ~"expression(this.parentNode.offsetHeight+'px')";
|
||||
}
|
||||
* .jqgrid-overlay iframe {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
z-index:-1;
|
||||
width: ~"expression(this.parentNode.offsetWidth+'px')";
|
||||
height: ~"expression(this.parentNode.offsetHeight+'px')";
|
||||
}
|
||||
/* Tree Grid */
|
||||
.ui-jqgrid .tree-wrap {position: relative; height: 18px; float: left; overflow: hidden; white-space: nowrap;}
|
||||
.ui-jqgrid .tree-minus {position: absolute; height: 18px; width: 18px; overflow: hidden;}
|
||||
.ui-jqgrid .tree-plus {position: absolute; height: 18px; width: 18px; overflow: hidden;}
|
||||
.ui-jqgrid .tree-leaf {position: absolute; height: 18px; width: 18px; overflow: hidden;}
|
||||
.ui-jqgrid .treeclick {cursor: pointer;}
|
||||
/* moda dialog */
|
||||
.ui-jqgrid .ui-jqgrid-resize-ltr {float: right; margin: -2px -2px -2px 0px;}
|
||||
.ui-jqgrid .ui-jqgrid-resize-rtl {float: left; margin: -2px 0px -1px -3px;}
|
||||
/* caption */
|
||||
.ui-jqgrid .ui-jqgrid-titlebar {
|
||||
position: relative;
|
||||
|
||||
border-radius-topleft: 0;
|
||||
-moz-border-radius-topleft: 0;
|
||||
-webkit-border-top-left-radius: 0;
|
||||
|
||||
border-radius-topright: 2px;
|
||||
-moz-border-radius-topright: 2px;
|
||||
-webkit-border-top-right-radius: 2px;
|
||||
|
||||
border: 0;
|
||||
background-color: #303539;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
center top,
|
||||
center bottom,
|
||||
color-stop(0.00, #6c6f74),
|
||||
color-stop(0.05, #4c4f54),
|
||||
color-stop(0.10, #3f4448),
|
||||
color-stop(0.45, #383d41),
|
||||
color-stop(0.50, #303539),
|
||||
color-stop(0.95, #33363b),
|
||||
color-stop(1.00, #4c4f54)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#6c6f74 0%,
|
||||
#4c4f54 5%,
|
||||
#3f4448 10%,
|
||||
#383d41 45%,
|
||||
#303539 50%,
|
||||
#33363b 95%,
|
||||
#4c4f54 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#383d41',
|
||||
endColorstr='#303539',
|
||||
gradientType='0'
|
||||
);
|
||||
|
||||
color: #ddd;
|
||||
|
||||
text-shadow: 0 0 4px #23262b;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
line-height: 2em;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-title {
|
||||
float: none;
|
||||
display: block;
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-titlebar-close {display: none;}
|
||||
/* header */
|
||||
.ui-jqgrid .ui-jqgrid-hdiv {
|
||||
background: #303539;
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-htable {
|
||||
border: 0;
|
||||
background: #fff;
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-htable th {
|
||||
background-color: #303539;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
center top,
|
||||
center bottom,
|
||||
color-stop(0.00, #6c6f74),
|
||||
color-stop(0.05, #4c4f54),
|
||||
color-stop(0.10, #3f4448),
|
||||
color-stop(0.45, #383d41),
|
||||
color-stop(0.50, #303539),
|
||||
color-stop(0.95, #33363b),
|
||||
color-stop(1.00, #4c4f54)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#6c6f74 0%,
|
||||
#4c4f54 5%,
|
||||
#3f4448 10%,
|
||||
#383d41 45%,
|
||||
#303539 50%,
|
||||
#33363b 95%,
|
||||
#4c4f54 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#383d41',
|
||||
endColorstr='#303539',
|
||||
gradientType='0'
|
||||
);
|
||||
|
||||
color: #ddd;
|
||||
text-shadow: 0 0 4px #23262b;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-htable th:hover {
|
||||
background-color: #3f4448;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
center top,
|
||||
center bottom,
|
||||
color-stop(0.00, #6c6f74),
|
||||
color-stop(0.05, #4c4f54),
|
||||
color-stop(0.45, #3f4448),
|
||||
color-stop(0.50, #383d41),
|
||||
color-stop(1.00, #3f4448)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#6c6f74 0%,
|
||||
#4c4f54 5%,
|
||||
#3f4448 45%,
|
||||
#383d41 50%,
|
||||
#3f4448 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#4c4f54',
|
||||
endColorstr='#3f4448',
|
||||
gradientType='0'
|
||||
);
|
||||
color: #fff;
|
||||
text-shadow: 0 0 2px gba(0, 0, 0, .5);
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-htable th:hover .ui-grid-ico-sort {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.ui-th-ltr, .ui-jqgrid .ui-jqgrid-htable th.ui-th-ltr {
|
||||
border: 1px solid #33363b;
|
||||
border-right: 1px solid #3f4448;
|
||||
}
|
||||
.ui-jqgrid-resize {
|
||||
background: #fff;
|
||||
opacity: 0.10;
|
||||
filter: alpha(opacity=10);
|
||||
text-indent: 0;
|
||||
}
|
||||
.ui-jqgrid-resize:hover {
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.ui-jqgrid .s-ico {
|
||||
display: none;
|
||||
}
|
||||
.ui-jqgrid .ui-grid-ico-sort {
|
||||
display: none;
|
||||
}
|
||||
.ui-jqgrid-sortable {
|
||||
cursor: default;
|
||||
}
|
||||
.ui-jqgrid .ui-icon-asc {
|
||||
background: url(../img/sort-alphabet.png) no-repeat center center;
|
||||
}
|
||||
.ui-jqgrid .ui-icon-desc {
|
||||
background: url(../img/sort-alphabet-descending.png) no-repeat center center;
|
||||
}
|
||||
.ui-jqgrid .ui-grid-ico-sort.ui-state-disabled {
|
||||
display: none;
|
||||
}
|
||||
.ui-th-column, .ui-jqgrid .ui-jqgrid-htable th.ui-th-column {
|
||||
text-align: left;
|
||||
text-indent: 10px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
/* body */
|
||||
.ui-jqgrid .ui-jqgrid-btable {
|
||||
border: 0;
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-bdiv {
|
||||
background: #fff;
|
||||
}
|
||||
.ui-jqgrid tr.jqgfirstrow td {
|
||||
border: 0;
|
||||
}
|
||||
.ui-jqgrid tr.jqgrow td{
|
||||
border: 1px solid #f5f5f5;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
padding: 2px;
|
||||
color: #636363;
|
||||
font-size: 12px;
|
||||
cursor: default;
|
||||
}
|
||||
.ui-jqgrid tr.jqgrow:hover td {
|
||||
color: #303539;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.ui-jqgrid tr.ui-row-ltr td {
|
||||
border-width: 1px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* Pager */
|
||||
.ui-jqgrid .ui-pg-table {
|
||||
border: 0;
|
||||
}
|
||||
.ui-jqgrid .ui-pg-table td {
|
||||
padding: 5px;
|
||||
border: 0;
|
||||
color: #ddd;
|
||||
background-color: #303539;
|
||||
}
|
||||
.ui-jqgrid .ui-pg-table td.ui-pg-button {
|
||||
opacity: 1 !important;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.ui-jqgrid .ui-jqgrid-pager {
|
||||
border: 0;
|
||||
border-top: 1px solid #33363b;
|
||||
color: #ddd;
|
||||
text-shadow: 0 0 4px #23262b;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
opacity: 0.6;
|
||||
filter: alpha(opacity=60);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button:hover {
|
||||
padding: 5px;
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button.ui-state-disabled {
|
||||
cursor: default;
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button.ui-state-disabled .ui-icon {
|
||||
opacity: 0.10;
|
||||
filter: alpha(opacity=10);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button .ui-icon {
|
||||
display: inline-block;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button .ui-icon-seek-next {
|
||||
background-image: url(../img/arrow.png);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button .ui-icon-seek-end {
|
||||
background-image: url(../img/arrow-stop.png);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button .ui-icon-seek-prev {
|
||||
background-image: url(../img/arrow-180.png);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-button .ui-icon-seek-first {
|
||||
background-image: url(../img/arrow-stop-180.png);
|
||||
}
|
||||
.ui-jqgrid .ui-pg-input {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 11px;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0.00, #bbb),
|
||||
color-stop(0.10, #ddd),
|
||||
color-stop(0.30, #eee),
|
||||
color-stop(1.00, #fff)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#ccc 0%,
|
||||
#ddd 10%,
|
||||
#eee 30%,
|
||||
#fff 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#dddddd',
|
||||
endColorstr='#ffffff',
|
||||
gradientType='0'
|
||||
);
|
||||
|
||||
border-width: 0;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
|
||||
color: #777;
|
||||
text-align: center;
|
||||
}
|
||||
/* subgrid */
|
||||
/* loading */
|
||||
.ui-jqgrid .loading {
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: 45%;
|
||||
width: auto;
|
||||
z-index:101;
|
||||
padding: 6px 6px 6px 20px;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
display: none;
|
||||
border-width: 2px;
|
||||
font-weight: normal;
|
||||
color: #777;
|
||||
|
||||
background: url(../img/throbber.gif) no-repeat left center;
|
||||
}
|
||||
.ui-jqgrid .jqgrid-overlay {display:none; z-index:100;}
|
||||
|
||||
/**
|
||||
*
|
||||
* Modal
|
||||
*
|
||||
**********************************************************************/
|
||||
.repository-browser-modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 999;
|
||||
|
||||
background-image: -webkit-radial-gradient(
|
||||
rgba(127, 127, 127, 0.5) 0%,
|
||||
rgba(127, 127, 127, 0.6) 40%,
|
||||
rgba(0, 0, 0, 0.7) 100%
|
||||
);
|
||||
background-image: -moz-radial-gradient(
|
||||
rgba(127, 127, 127, 0.5),
|
||||
rgba(127, 127, 127, 0.6) 40%,
|
||||
rgba(0, 0, 0, 0.7)
|
||||
);
|
||||
}
|
||||
div.repository-browser-modal-window {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
.repository-browser-modal-window .ui-widget {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ui-layout
|
||||
*
|
||||
**********************************************************************/
|
||||
.ui-layout-resizer {
|
||||
background-color: #303539;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left center,
|
||||
right center,
|
||||
color-stop(0.00, #303539),
|
||||
color-stop(0.30, #4c4f54),
|
||||
color-stop(0.70, #6c6f74),
|
||||
color-stop(1.00, #303539)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
left center,
|
||||
#303539 0%,
|
||||
#4c4f54 30%,
|
||||
#6c6f74 70%,
|
||||
#303539 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#4c4f54',
|
||||
endColorstr='#303539',
|
||||
gradientType='0'
|
||||
);
|
||||
}
|
||||
.ui-layout-toggler {
|
||||
border: 1px solid #355ea0;
|
||||
background-color: #508ac9;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
right center,
|
||||
left center,
|
||||
color-stop(0.00, #81add2),
|
||||
color-stop(0.10, #5693cc),
|
||||
color-stop(0.45, #5b9acf),
|
||||
color-stop(0.60, #508ac9),
|
||||
color-stop(1.00, #456eb0)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
right center,
|
||||
#81add2 0%,
|
||||
#5693cc 10%,
|
||||
#5b9acf 45%,
|
||||
#508ac9 60%,
|
||||
#456eb0 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#81add2',
|
||||
endColorstr='#456eb0',
|
||||
gradientType='0'
|
||||
);
|
||||
}
|
||||
.ui-layout-toggler:hover {
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
|
||||
.ui-draggable-dragging {
|
||||
opacity: 0.85;
|
||||
/* filter: alpha(opacity=85); */
|
||||
}
|
||||
|
||||
.repository-browser-shadow {
|
||||
background: transparent;
|
||||
-moz-box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
||||
-webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
||||
}
|
||||
.repository-browser-rounded-top {
|
||||
border-radius-topleft: 2px;
|
||||
-moz-border-radius-topleft: 2px;
|
||||
-webkit-border-top-left-radius: 2px;
|
||||
border-radius-topright: 2px;
|
||||
-moz-border-radius-topright: 2px;
|
||||
-webkit-border-top-right-radius: 2px;
|
||||
}
|
||||
.repository-browser-grid {
|
||||
height: 400px;
|
||||
border: 1px solid #53565b;
|
||||
border: 1px solid rgba(0,0,0,0.2);
|
||||
text-align: left;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
.repository-browser-clear {
|
||||
float: none;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/**
|
||||
* List
|
||||
*****************************************************************************/
|
||||
.repository-browser-list a {
|
||||
color: #777;
|
||||
text-decoration: none;
|
||||
}
|
||||
.repository-browser-list .ui-state-hover a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.repository-browser-list-altrow {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.repository-browser-list-resizable {}
|
||||
.repository-browser-list-icon {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
background: transparent no-repeat center center;
|
||||
}
|
||||
.repository-browser-icon-page {
|
||||
background: url(../img/gcn-icons/gcn-icon-page.gif) no-repeat center center;
|
||||
}
|
||||
.repository-browser-icon-file {
|
||||
background: url(../img/gcn-icons/gcn-icon-file.gif) no-repeat center center;
|
||||
}
|
||||
.repository-browser-icon-image {
|
||||
background: url(../img/gcn-icons/gcn-icon-image.gif) no-repeat center center;
|
||||
}
|
||||
.repository-browser-grab-handle {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.repository-browser-btns {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
}
|
||||
.repository-browser-btn {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin: -1px 5px 0 0;
|
||||
padding: 0 8px;
|
||||
border: 1px solid #355ea0;
|
||||
background-color: #508ac9;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
center top,
|
||||
center bottom,
|
||||
color-stop(0.00, #81add2),
|
||||
color-stop(0.10, #5693cc),
|
||||
color-stop(0.45, #5b9acf),
|
||||
color-stop(0.60, #508ac9),
|
||||
color-stop(1.00, #456eb0)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#81add2 0%,
|
||||
#5693cc 10%,
|
||||
#5b9acf 45%,
|
||||
#508ac9 60%,
|
||||
#456eb0 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#81add2',
|
||||
endColorstr='#456eb0',
|
||||
gradientType='0'
|
||||
);
|
||||
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80);
|
||||
|
||||
line-height: 22px;
|
||||
color: #fff;
|
||||
text-shadow: 0 0 4px #23262b;
|
||||
}
|
||||
.repository-browser-btn:hover {
|
||||
opacity: 0.9;
|
||||
filter: alpha(opacity=90);
|
||||
}
|
||||
.repository-browser-btn.repository-browser-pressed {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.repository-browser-btns input {
|
||||
float: left;
|
||||
height: 15px;
|
||||
padding: 4px 2px;
|
||||
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0.00, #bbb),
|
||||
color-stop(0.10, #ddd),
|
||||
color-stop(0.30, #eee),
|
||||
color-stop(1.00, #fff)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#ccc 0%,
|
||||
#ddd 10%,
|
||||
#eee 30%,
|
||||
#fff 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#dddddd',
|
||||
endColorstr='#ffffff',
|
||||
gradientType='0'
|
||||
);
|
||||
|
||||
color: #555;
|
||||
font-size: 13px;
|
||||
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.repository-browser-search-btn {
|
||||
border-radius-topleft: 0;
|
||||
-moz-border-radius-topleft: 0;
|
||||
-webkit-border-top-left-radius: 0;
|
||||
border-radius-bottomleft: 0;
|
||||
-moz-border-radius-bottomleft: 0;
|
||||
-webkit-border-bottom-left-radius: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.repository-browser-search-icon {
|
||||
width: 16px;
|
||||
height: 22px;
|
||||
display: inline-block;
|
||||
background: url(../img/magnifier-left.png) no-repeat center center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.repository-browser-close-btn {
|
||||
margin-right: 0;
|
||||
}
|
||||
/**
|
||||
* Tree
|
||||
*****************************************************************************/
|
||||
.repository-browser-tree {
|
||||
overflow: scroll;
|
||||
padding-left: 4px;
|
||||
background: #fff;
|
||||
font-size: 12px;
|
||||
}
|
||||
.repository-browser-tree-header {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border-radius-topleft: 2px;
|
||||
-moz-border-radius-topleft: 2px;
|
||||
-webkit-border-top-left-radius: 2px;
|
||||
height: 18px;
|
||||
padding: 8px;
|
||||
background-color: #303539;
|
||||
background-image: -webkit-gradient(
|
||||
linear,
|
||||
center top,
|
||||
center bottom,
|
||||
color-stop(0.00, #6c6f74),
|
||||
color-stop(0.05, #4c4f54),
|
||||
color-stop(0.10, #3f4448),
|
||||
color-stop(0.45, #383d41),
|
||||
color-stop(0.50, #303539),
|
||||
color-stop(0.95, #33363b),
|
||||
color-stop(1.00, #4c4f54)
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
center top,
|
||||
#6c6f74 0%,
|
||||
#4c4f54 5%,
|
||||
#3f4448 10%,
|
||||
#383d41 45%,
|
||||
#303539 50%,
|
||||
#33363b 95%,
|
||||
#4c4f54 100%
|
||||
);
|
||||
filter: progid:DXImageTransform.Microsoft.Gradient(
|
||||
startColorstr='#383d41',
|
||||
endColorstr='#303539',
|
||||
gradientType='0'
|
||||
);
|
||||
|
||||
color: #ddd;
|
||||
text-shadow: 0 0 4px #23262b;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
line-height: 1.5em;
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* List icons
|
||||
*****************************************************************************/
|
||||
.repository-browser-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 auto;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Customize from here:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
.repository-browser-search-field,
|
||||
.repository-browser-search-btn {
|
||||
display: none;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 589 B |
Before Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 665 B |
Before Width: | Height: | Size: 590 B |
Before Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 647 B |
Before Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 606 B |
Before Width: | Height: | Size: 594 B |
Before Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 1.8 KiB |
@@ -1,32 +0,0 @@
|
||||
define("RepositoryBrowser",["Class","jquery","PubSub","repository-browser-i18n-"+(window&&window.__DEPS__&&window.__DEPS__.lang||"en"),"jstree","jqgrid","jquery-layout"],function(m,d,n,o){function p(a){a.each(function(){d(this).attr("unselectable","on").css({"-moz-user-select":"none","-webkit-user-select":"none","user-select":"none"}).each(function(){this.onselectstart=function(){return!1}})})}var j=[],k=0,g=(new Date).getTime(),q={repositoryManager:null,repositoryFilter:[],objectTypeFilter:[],renditionFilter:["cmis:none"],
|
||||
filter:["url"],element:null,isFloating:!1,verticalPadding:100,horizontalPadding:50,maxHeight:1E3,minHeight:400,minWidth:400,maxWidth:1200,treeWidth:300,listWidth:"auto",pageSize:8,adaptPageSize:!1,rowHeight:32,rootPath:"",rootFolderId:"aloha",columns:{icon:{title:"",width:30,sortable:!1,resizable:!1},name:{title:"Name",width:200,sorttype:"text"},url:{title:"URL",width:220,sorttype:"text"},preview:{title:"Preview",width:150,sorttype:"text"}},i18n:{Browsing:"Browsing",Close:"Close","in":"in","Input search text...":"Input search text...",
|
||||
numerous:"numerous",of:"of","Repository Browser":"Repository Browser",Search:"Search","Searching for":"Searching for",Viewing:"Viewing"}};return m.extend({_cachedRepositoryObjects:{},_searchQuery:null,_orderBy:null,_prefilledValue:null,$_grid:null,$_tree:null,$_list:null,_isOpened:!0,_constructor:function(){this.init.apply(this,arguments)},init:function(a){a=d.extend({},q,a,{i18n:o});if(!a.element||0===a.element.length)a.isFloating=!0,a.element=this._createOverlay();if(a.maxWidth<a.minWidth)a.maxWidth=
|
||||
a.minWidth;d.extend(this,a);this._prefilledValue=this._i18n("Input search text...");this._cachedRepositoryObjects={};this._pagingCount=this._orderBy=this._searchQuery=null;this._pagingOffset=0;this._pagingBtns={first:null,end:null,next:null,prev:null};this._initializeUI();j.push(this);n.pub("repository-browser.initialized",{data:this})},_i18n:function(a){return this.i18n[a]||a},_initializeUI:function(){this.element.attr("data-repository-browser",++g);this.element.width(this.maxWidth);this.$_grid=
|
||||
this._createGrid(this.element).resize();this._setInitialHeight();this.$_tree=this._createTree(this.$_grid.find(".ui-layout-west"));this.$_list=this._createList(this.$_grid.find(".ui-layout-center"));var a=this,b=this.treeWidth/5;this.$_grid.layout({enableCursorHotkey:!1,west__size:this.treeWidth-1,west__minSize:this.treeWidth-b,west__maxSize:this.treeWidth+b,center__size:"auto",paneClass:"ui-layout-pane",resizerClass:"ui-layout-resizer",togglerClass:"ui-layout-toggler",onresize:function(b,d){"center"===
|
||||
b&&a.$_list.setGridWidth(d.width())}}).sizePane("west",this.treeWidth);p(this.$_grid);this._preloadImages();d(function(){d(window).resize(function(){a._onWindowResized()})});this.element.mousedown(function(){d.each(j,function(a){this.element.css("z-index",99999+a)});d(this).css("z-index",99999+j.length+1)});d(".repository-browser-grid").css("width",this.maxWidth);this.close();this._adaptPageSize()},_setInitialHeight:function(){var a=this.maxHeight-d(window).height()+this.verticalPadding;this.$_grid.height(a>
|
||||
0?Math.max(this.minHeight,this.maxHeight-a):this.maxHeight)},_onWindowResized:function(){var a=this.maxWidth-d(window).width()+this.horizontalPadding,a=a>0?Math.max(this.minWidth,this.maxWidth-a):this.maxWidth;this.element.width(a);this.$_grid.width(a);this._setInitialHeight();a=this.$_grid.find(".repository-browser-tree-header");this.$_tree.height(this.$_grid.height()-a.outerHeight(!0));a=this.$_grid.find(".ui-layout-center");a.find(".ui-jqgrid-bdiv").height(this.$_grid.height()-(a.find(".ui-jqgrid-titlebar").height()+
|
||||
a.find(".ui-jqgrid-hdiv").height()+a.find(".ui-jqgrid-pager").height()));this._adaptPageSize()&&this._currentFolder&&this._fetchItems(this._currentFolder)},_preloadImages:function(){for(var a=this.rootPath+"img/",b="arrow-000-medium.png,arrow-180.png,arrow-315-medium.png,arrow-stop-180.png,arrow-stop.png,arrow.png,control-stop-square-small.png,folder-horizontal-open.png,folder-open.png,magnifier-left.png,page.png,picture.png,sort-alphabet-descending.png,sort-alphabet.png".split(","),c=b.length;c;)document.createElement("img").src=
|
||||
a+b[--c]},_processRepoResponse:function(a,b,c){var d=[],f;typeof b==="function"&&(c=b,b=void 0);for(f=0;f<a.length;f++)d.push(this._harvestRepoObject(a[f]));c(d,b)},_harvestRepoObject:function(a){++g;this._cachedRepositoryObjects[g]=d.extend(a,{uid:g,loaded:!1});return this._processRepoObject(this._cachedRepositoryObjects[g])},_processRepoObject:function(a){var b,c,e,f=this;switch(a.baseType){case "folder":b="folder";break;case "document":b="document"}c=a.hasMoreItems||a.baseType==="folder"?"closed":
|
||||
null;a.hasMoreItems===!1&&(c=null);a.children&&(e=[],d.each(a.children,function(){e.push(f._harvestRepoObject(this));c="open"}));this._currentFolder&&this._currentFolder.id===a.id&&window.setTimeout(function(){f.$_tree.jstree("select_node","li[data-repo-obj='"+a.uid+"']")},0);return{data:{title:a.name,attr:{"data-repo-obj":a.uid},icon:b||""},attr:{rel:a.type,"data-repo-obj":a.uid},state:c,resource:a,children:e}},_fetchRepoRoot:function(a){if(!this._currentFolder)this._currentFolder=this.getSelectedFolder();
|
||||
this.repositoryManager&&this.getRepoChildren({inFolderId:this.rootFolderId,repositoryFilter:this.repositoryFilter},a)},_getObjectFromCache:function(a){return a&&a.length?this._cachedRepositoryObjects[a.find("a:first").attr("data-repo-obj")]:null},_onTreeNodeSelected:function(a,b){if(!b.args[0].context){var c=this._getObjectFromCache(b.rslt.obj);if(c)this._pagingOffset=0,this._clearSearch(),this._currentFolder=c,this._fetchItems(c);this.folderSelected(c)}},_createTree:function(a){var b=d('<div class="repository-browser-tree">'),
|
||||
c=d('<div class="repository-browser-tree-header repository-browser-grab-handle">'+this._i18n("Repository Browser")+"</div>");a.append(c,b);b.height(this.$_grid.height()-c.outerHeight(!0));b.bind("loaded.jstree",function(){d(this).find(">ul>li:first").css("padding-top",5);b.jstree("open_node",'li[rel="repository"]')});var e=this;b.bind("select_node.jstree",function(a,b){e._onTreeNodeSelected(a,b)});b.bind("open_node.jstree",function(a,b){e.folderOpened(b.rslt.obj)});b.bind("close_node.jstree",function(a,
|
||||
b){e.folderClosed(b.rslt.obj)});b.jstree({types:this.types,rootFolderId:this.rootFolderId,plugins:["themes","json_data","ui","types"],core:{animation:250},themes:{url:this.rootPath+"css/jstree.css",dots:!0,icons:!0,theme:"browser"},json_data:{data:function(a,b){e.repositoryManager?(e.jstree_callback=b,e._fetchSubnodes(a,b)):b()},correct_state:!0},ui:{select_limit:1}});return b},_createGrid:function(a){var b=d('<div class="repository-browser-grid\t\t\t\t repository-browser-shadow\t\t\t\t\t\t\t repository-browser-rounded-top">\t\t\t\t\t<div class="ui-layout-west"></div>\t\t\t\t\t<div class="ui-layout-center"></div>\t\t\t\t</div>');
|
||||
a.append(b);return b},_createList:function(a){var b=d('<table id="repository-browser-list-'+ ++g+'" class="repository-browser-list"></table>'),c=[{name:"id",sorttype:"int",firstsortorder:"asc",hidden:!0}],e=[""];d.each(this.columns,function(a,b){e.push(b.title||" ");c.push({name:a,width:b.width,sortable:b.sortable,sorttype:b.sorttype,resizable:b.resizable,fixed:b.fixed})});var f="repository-browser-list-page-"+ ++g;a.append(b,d('<div id="'+f+'">'));b.jqGrid({datatype:"local",width:a.width(),
|
||||
shrinkToFit:!0,colNames:e,colModel:c,caption:" ",altRows:!0,altclass:"repository-browser-list-altrow",resizeclass:"repository-browser-list-resizable",pager:"#"+f,viewrecords:!0,onPaging:function(){},loadError:function(){},ondblClickRow:function(){},gridComplete:function(){},loadComplete:function(){}});a.find(".ui-jqgrid-bdiv").height(this.$_grid.height()-(a.find(".ui-jqgrid-titlebar").height()+a.find(".ui-jqgrid-hdiv").height()+a.find(".ui-jqgrid-pager").height()));var h=this;b.click(function(){h.rowClicked.apply(h,
|
||||
arguments)});a.find(".ui-pg-button").unbind().find(">span.ui-icon").each(function(){var a=this.className.match(/ui\-icon\-seek\-([a-z]+)/)[1];h._pagingBtns[a]=d(this).parent().addClass("ui-state-disabled").click(function(){d(this).hasClass("ui-state-disabled")||h._doPaging(a)})});a.find(".ui-pg-input").parent().hide();a.find(".ui-separator").parent().css("opacity",0).first().hide();this._createTitlebar(a);var l=b[0].p;a.find(".ui-jqgrid-view tr:first th div").each(function(a){!1!==l.colModel[a].sortable&&
|
||||
(d(this).css("cursor","pointer"),d(this).unbind().click(function(b){b.stopPropagation();h._sortList(l.colModel[a],this)}))});return b},_clearSearch:function(){this.$_grid.find(".repository-browser-search-field").val(this._prefilledValue).addClass("repository-browser-search-field-empty");this._searchQuery=null},_createTitlebar:function(a){var a=a.find(".ui-jqgrid-titlebar"),b=d('<div class="repository-browser-btns">\t\t\t\t\t<input type="text" class="repository-browser-search-field" />\t\t\t\t\t<span class="repository-browser-btn repository-browser-search-btn">\t\t\t\t\t\t<span class="repository-browser-search-icon"></span>\t\t\t\t\t</span>\t\t\t\t\t<span class="repository-browser-btn repository-browser-close-btn">'+
|
||||
this._i18n("Close")+'</span>\t\t\t\t\t<div class="repository-browser-clear"></div>\t\t\t\t</div>'),c=this;a.addClass("repository-browser-grab-handle").append(b);a.find(".repository-browser-search-btn").html(this._i18n("Search")).click(function(){c._triggerSearch()});b=a.find(".repository-browser-search-field");this._clearSearch();b.keypress(function(a){13===a.keyCode&&c._triggerSearch()});b.focus(function(){d(this).val()===c._prefilledValue&&d(this).val("").removeClass("repository-browser-search-field-empty")});
|
||||
b.blur(function(){d(this).val()===""&&c._clearSearch()});a.find(".repository-browser-close-btn").click(function(){c.close()});a.find(".repository-browser-btn").mousedown(function(){d(this).addClass("repository-browser-pressed")}).mouseup(function(){d(this).removeClass("repository-browser-pressed")})},_triggerSearch:function(){var a=this.$_grid.find("input.repository-browser-search-field"),b=a.val();if(d(a).hasClass("aloha-browser-search-field-empty")||""===b)b=null;this._pagingOffset=0;this._searchQuery=
|
||||
b;this._fetchItems(this._currentFolder)},_sortList:function(a,b){this.$_grid.find("span.ui-grid-ico-sort").addClass("ui-state-disabled");a.sortorder="asc"===a.sortorder?"desc":"asc";d(b).find("span.s-ico").show().find(".ui-icon-"+a.sortorder).removeClass("ui-state-disabled");this._setSortOrder(a.name,a.sortorder);this._fetchItems(this._currentFolder)},_doPaging:function(a){switch(a){case "first":this._pagingOffset=0;break;case "end":this._pagingOffset=this._pagingCount%this.pageSize===0?this._pagingCount-
|
||||
this.pageSize:this._pagingCount-this._pagingCount%this.pageSize;break;case "next":this._pagingOffset+=this.pageSize;break;case "prev":if(this._pagingOffset-=this.pageSize,this._pagingOffset<0)this._pagingOffset=0}this._fetchItems(this._currentFolder)},_setSortOrder:function(a,b){var c={},d=!1,f=this._orderBy||[],h,g,i;c[a]=b||"asc";for(i=0;i<f.length;++i){h=f[i];for(g in h)if(h.hasOwnProperty(g)&&g===a){f.splice(i,1);f.unshift(c);d=!0;break}if(d)break}d&&f.unshift(c);this._orderBy=f},_listItems:function(a){var b=
|
||||
this.$_list.clearGridData(),c,e;for(c=0;c<a.length;c++)e=a[c].resource,b.addRowData(e.uid,d.extend({id:e.id},this.renderRowCols(e)))},handleTimeout:function(){},_processItems:function(a,b){this._pagingCount=b&&d.isNumeric(b.numItems)?b.numItems:null;this.$_grid.find(".loading").hide();this.$_list.show();this._listItems(a);var c=this._pagingBtns;this._pagingOffset<=0?c.first.add(c.prev).addClass("ui-state-disabled"):c.first.add(c.prev).removeClass("ui-state-disabled");d.isNumeric(this._pagingCount)?
|
||||
this._pagingOffset+this.pageSize>=this._pagingCount?c.end.add(c.next).addClass("ui-state-disabled"):c.end.add(c.next).removeClass("ui-state-disabled"):(c.end.addClass("ui-state-disabled"),a.length<=this.pageSize?c.next.addClass("ui-state-disabled"):c.next.removeClass("ui-state-disabled"));var e;0===a.length&&0===this._pagingOffset?e=c=0:(c=this._pagingOffset+1,e=c+a.length-1);this.$_grid.find(".ui-paging-info").html(this._i18n("Viewing")+" "+c+" - "+e+" "+this._i18n("of")+" "+(d.isNumeric(this._pagingCount)?
|
||||
this._pagingCount:this._i18n("numerous")));b&&b.timeout&&this.handleTimeout()},_createOverlay:function(){0===d(".repository-browser-modal-overlay").length&&d("body").append('<div class="repository-browser-modal-overlay" style="top: -99999px; z-index: 99999;"></div>');var a=this;d(".repository-browser-modal-overlay").click(function(){a.close()});var b=d('<div class="repository-browser-modal-window" style="top: -99999px; z-index: 99999;">');d("body").append(b);return b},_fetchSubnodes:function(a,b){if(-1===
|
||||
a)this._fetchRepoRoot(b);else{var c;for(c=0;c<a.length;c++){var d=this._getObjectFromCache(a.eq(c));d&&this.fetchChildren(d,b)}}},getRepoChildren:function(a,b){if(this.repositoryManager){var c=this;this.repositoryManager.getChildren(a,function(a){c._processRepoResponse(a,b)})}},queryRepository:function(a,b){if(this.repositoryManager){var c=this;this.repositoryManager.query(a,function(a){c._processRepoResponse(a.results>0?a.items:[],{numItems:a.numItems,hasMoreItems:a.hasMoreItems,timeout:a.timeout},
|
||||
b)})}},renderRowCols:function(a){var b={};d.each(this.columns,function(c){switch(c){case "icon":b.icon='<div class="repository-browser-icon repository-browser-icon-'+a.type+'"></div>';break;default:b[c]=a[c]||"--"}});return b},onSelect:function(){},fetchChildren:function(a,b){if((!0===a.hasMoreItems||"folder"===a.baseType)&&!1===a.loaded){var c=this;this.getRepoChildren({inFolderId:a.id,repositoryId:a.repositoryId},function(d){c._cachedRepositoryObjects[a.uid].loaded=!0;typeof b==="function"&&b(d)})}},
|
||||
rowClicked:function(a){a=d(a.target).parent("tr");return a.length?(a=this._cachedRepositoryObjects[a.attr("id")],this.onSelect(a),a):null},getFieldOfHeader:function(a){return a.find("div.ui-jqgrid-sortable").attr("id").replace("jqgh_","")},_fetchItems:function(a){if(a){var b=typeof this._searchQuery==="string";this.$_list.setCaption(typeof this._searchQuery==="string"?this._i18n("Searching for")+' "'+this._searchQuery+'" '+this._i18n("in")+" "+a.name:this._i18n("Browsing")+": "+a.name);this.$_list.hide();
|
||||
this.$_grid.find(".loading").show();var c=this;this.queryRepository({repositoryId:a.repositoryId,inFolderId:a.id,queryString:this._searchQuery,orderBy:this._orderBy,skipCount:this._pagingOffset,maxItems:this.pageSize,objectTypeFilter:this.objectTypeFilter,renditionFilter:this.renditionFilter,filter:this.filter,recursive:b},function(a,b){c._processItems(a,b)})}},setObjectTypeFilter:function(a){this.objectTypeFilter=typeof a==="string"?[a]:a},getObjectTypeFilter:function(){return this.objectTypeFilter},
|
||||
show:function(){this.open()},open:function(){if(!this._isOpened){this._isOpened=!0;var a=this.element;this.isFloating?(d(".repository-browser-modal-overlay").stop().css({top:0,left:0}).show(),a.stop().show(),this._onWindowResized(),this.$_grid.resize(),d(window),a.css({left:this.horizontalPadding/2,top:this.verticalPadding/2}).draggable({handle:a.find(".repository-browser-grab-handle")}),this.$_grid.css({marginTop:0,opacity:0}).animate({marginTop:0,opacity:1},1500,"easeOutExpo",function(){d.browser.msie&&
|
||||
d(this).add(a).css("filter","progid:DXImageTransform.Microsoft.gradient(enabled=false)")})):(a.stop().show().css({opacity:1,filter:"progid:DXImageTransform.Microsoft.gradient(enabled=false)"}),this._onWindowResized(),this.$_grid.resize());++k}},close:function(){if(this._isOpened)this._isOpened=!1,this.element.fadeOut(250,function(){d(this).css("top",0).hide();(0===k||0===--k)&&d(".repository-browser-modal-overlay").hide()})},refresh:function(){this._currentFolder&&this._fetchItems(this._currentFolder)},
|
||||
folderOpened:function(a){(a=this._getObjectFromCache(a))&&this.repositoryManager&&this.repositoryManager.folderOpened(a)},folderClosed:function(a){(a=this._getObjectFromCache(a))&&this.repositoryManager&&this.repositoryManager.folderClosed(a)},folderSelected:function(a){this.repositoryManager&&this.repositoryManager.folderSelected(a)},getSelectedFolder:function(){if(this.repositoryManager&&typeof this.repositoryManager.getSelectedFolder==="function")return this.repositoryManager.getSelectedFolder()},
|
||||
_adaptPageSize:function(){var a;return!this.adaptPageSize||!this.$_list||!this.rowHeight?!1:(a=this.$_grid.find(".ui-jqgrid-bdiv").innerHeight()-20)?(a=Math.floor(a/this.rowHeight),a<=0&&(a=1),a!==this.pageSize?(this.pageSize=a,!0):!1):!1}})});define("repository-browser-i18n-de",[],function(){return{Browsing:"Durchsuchen",Close:"Schließen","in":"in","Input search text...":"Suchtext einfügen...",numerous:"zahlreiche",of:"von","Repository Browser":"Repository Browser",Search:"Suchen","Searching for":"Suche nach",Viewing:"Anzeige","button.switch-metaview.tooltip":"Zwischen Metaansicht und normaler Ansicht umschalten"}});define("repository-browser-i18n-en",[],function(){return{Browsing:"Browsing",Close:"Close","in":"in","Input search text...":"Input search text...",numerous:"numerous",of:"of","Repository Browser":"Repository Browser",Search:"Search","Searching for":"Searching for",Viewing:"Viewing","button.switch-metaview.tooltip":"Switch between meta and normal view"}});
|
@@ -1,166 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
@@ -1,12 +0,0 @@
|
||||
Config example
|
||||
--------------
|
||||
|
||||
"align": {
|
||||
// Allow align left, center and justify only for all elements
|
||||
// 4 possibilities : left, center, right and justify
|
||||
config : {
|
||||
alignment: [ 'left','center','justify']
|
||||
}
|
||||
}
|
||||
|
||||
This plugin is release under the LGPL license.
|
@@ -1,38 +0,0 @@
|
||||
.aloha-character-picker-overlay {
|
||||
position: absolute;
|
||||
display: none;
|
||||
float: left;
|
||||
padding: 3px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 1px solid #afafaf;
|
||||
border-collapse: separate;
|
||||
background-color: #fff;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.aloha-character-picker-overlay {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
.aloha-character-picker-overlay td {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
border: 1px solid #afafaf;
|
||||
font-size: 0.8em;
|
||||
padding: 0.05em;
|
||||
}
|
||||
|
||||
.aloha-character-picker-overlay td.mouseover {
|
||||
border: 1px solid #fdea83;
|
||||
background-color: #fefce1;
|
||||
}
|
||||
|
||||
.aloha-character-picker-overlay td.focused {
|
||||
border: 1px solid #407bcf;
|
||||
background-color: #b9d6f9;
|
||||
}
|
||||
|
||||
.aloha-icon-characterpicker {
|
||||
background: url( '../img/icon.png' );
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
|
||||
# The AlohaEditor Image Plugin
|
||||
|
||||
Image Plugin for enabling basic images manipulations in Aloha Editor
|
||||
|
||||
## Features
|
||||
|
||||
* Insert image
|
||||
* Edit url and title
|
||||
* set align
|
||||
* Handles [DragnDropFiles Plugin](https://github.com/alohaeditor/Aloha-Plugin-DragAndDropFiles) events for image files dropped in current page.
|
||||
* css resize with controlbuttons or mousedrag
|
||||
* reset to natural size (DEV)
|
||||
* canvas crop (EXPERIMENTAL)
|
||||
|
||||
## Example conf
|
||||
|
||||
config: {
|
||||
'img': {
|
||||
'max_width': '50px',
|
||||
'max_height': '50px',
|
||||
//Image manipulation options - ONLY in default config section
|
||||
'ui': {
|
||||
'meta': true, // If imageResizeWidth and imageResizeHeight are displayed, then you will want to set this to true, so that the width and height text fields are updated automatically.
|
||||
'crop':true, // If imageCropButton is displayed, then you have to enable this.
|
||||
'resizable': true, //resizable ui-drag image
|
||||
},
|
||||
/**
|
||||
* crop callback is triggered after the user clicked accept to accept his crop
|
||||
* @param image jquery image object reference
|
||||
* @param props cropping properties
|
||||
*/
|
||||
'onCropped':function (image, props) {},
|
||||
/**
|
||||
* reset callback is triggered before the internal reset procedure is applied
|
||||
* if this function returns true, then the reset has been handled by the callback
|
||||
* which means that no other reset will be applied
|
||||
* if false is returned the internal reset procedure will be applied
|
||||
* @param image jquery image object reference
|
||||
* @return true if a reset has been applied, false otherwise
|
||||
*/
|
||||
'onReset': function (image) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
To show or hide specific Image plug-in buttons, please configure @Aloha.settings.toolbar@, look at the "Image tab" example in @src/plugins/common/ui/lib/settings.js@.
|
||||
|
||||
## TODO
|
||||
|
||||
* resize slider
|
||||
* canvas resize
|
||||
|
||||
Copyright (c) 2010-2011 Gentics Software GmbH, aloha@gentics.com
|
||||
|
||||
Author : [Nicolas Karageuzian](https://github.com/nka11)
|
||||
|
||||
Contributors :
|
||||
|
||||
* [Nils Dehl](https://github.com/mrsunshine)
|
||||
* [Benjamin Athur Lupton](https://github.com/balupton)
|
||||
* [Christopher Hlubek](https://github.com/chlu)
|
||||
* [Thomas Lete](https://github.com/bistory)
|
||||
* [Haymo Meran](https://github.com/draftkraft)
|
||||
* [Clemens Prerovsky](https://github.com/cprerovsky) (base of crop and resize feature is a borrow from cropnresize plugin)
|
||||
* [Norbert Pomaroli](https://github.com/npomaroli) (for his patience explaining Selection and Range)
|
||||
* [Kirk Austin](http://www.kirkaustin.com/) who gave the impulsion to dive into html5 canvas
|
@@ -1,76 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Aloha, World!</title>
|
||||
<script src="../../lib/require.js" data-main="../../lib/aloha.js" id="aloha-script-include" data-plugins="common/format,common/highlighteditables,common/list,common/undo,common/paste,common/image"></script>
|
||||
<link rel="stylesheet" href="../../css/aloha.css" id="aloha-style-include">
|
||||
<link rel="stylesheet" href="../../demo/common/index.css" type="text/css">
|
||||
<script type="text/javascript">
|
||||
if (window.Aloha === undefined || window.Aloha === null)
|
||||
Aloha = {};
|
||||
|
||||
Aloha.settings = {
|
||||
"plugins": {
|
||||
"com.gentics.aloha.plugins.Image": {
|
||||
onCropped : function (image, props) {
|
||||
// invoke the image cropper crop.php
|
||||
image
|
||||
.width(props.w) // set width
|
||||
.height(props.h) // and height to new values
|
||||
.attr("src", "crop.php?src=" // and adjust src to the cropped image
|
||||
+ image.attr('src')
|
||||
+ "&x=" + props.x
|
||||
+ "&y=" + props.y
|
||||
+ "&w=" + props.w
|
||||
+ "&h=" + props.h
|
||||
);
|
||||
jQuery("#info").append("<li>Cropped \"" + image.attr("src") + "\"</li>");
|
||||
},
|
||||
onResized : function (image) {
|
||||
// this is the point where you would add a server-side image-resizer
|
||||
jQuery("#info").append("<li>Resized \"" + image.attr("src") + "\"</li>");
|
||||
},
|
||||
onReset : function (image) {
|
||||
// handle resetting the image
|
||||
jQuery("#info").append("<li>Resetted \"" + image.attr("src") + "\" to it's initial state</li>");
|
||||
},
|
||||
aspectRatio : false, // if set to false the aspectRatio will not be maintained anymore when resizing
|
||||
maxHeight : 500, // supply a maximum height for resizing
|
||||
minHeight : 200, // and a minimum height
|
||||
maxWidth : 700, // maximum image width for resizing
|
||||
minWidth : 200, // and minimum width
|
||||
grid : 100 // snap to an invisible grid when resizing
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
require.ready(function() {
|
||||
// Prepare
|
||||
var $ = window.jQuery,
|
||||
$body = $('body');
|
||||
|
||||
$body.bind('aloha',function(){
|
||||
$('#title').aloha();
|
||||
$('#teaser').aloha();
|
||||
$('#content').aloha();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<h1 id="title">Aloha, Images! (Extended Version :)</h1>
|
||||
<div id="bodyContent">
|
||||
<div id="teaser" class="shorttext">
|
||||
<p>This <b>extended example</b> is intended for developers planning to use the the CropNResize plugin found at <a href="https://github.com/alohaeditor/Aloha-Plugin-CropNResize">https://github.com/alohaeditor/Aloha-Plugin-CropNResize</a>. It displays the whole set of configuration options currently available. Well, just take a look at the code.</p>
|
||||
</div>
|
||||
<div id="content" class="article">
|
||||
<p>Click the image to start resizing right away, as a resize handle will appear in it's south-east corner.</p>
|
||||
<p><img src="cropnresize.jpg" /></p>
|
||||
</div>
|
||||
</div>
|
||||
<ol id="info"></ol>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Simple, very basic image cropper for CropNResize plugin demonstration
|
||||
* @author Clemens Prerovsky
|
||||
*/
|
||||
header('Content-type: image/jpeg');
|
||||
|
||||
// load parameters from url
|
||||
$src = $_GET["src"];
|
||||
$x = intval($_GET["x"]);
|
||||
$y = intval($_GET["y"]);
|
||||
$w = intval($_GET["w"]);
|
||||
$h = intval($_GET["h"]);
|
||||
|
||||
// resize image
|
||||
$img = imagecreatefromjpeg($src) or die("Error: unknown src");
|
||||
$cropped = imagecreatetruecolor($w, $h);
|
||||
imagecopyresampled($cropped, $img, 0, 0, $x, $y, $w, $h, $w, $h);
|
||||
imagejpeg($cropped);
|
||||
imagedestroy($cropped);
|
||||
?>
|
Before Width: | Height: | Size: 74 KiB |
@@ -1,117 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Aloha, Images!</title>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
(function(window, undefined) {
|
||||
|
||||
function _onCropped(image, props) {
|
||||
|
||||
var canvas = document.createElement('canvas'),
|
||||
context = canvas.getContext("2d"),
|
||||
img = image.get(0),
|
||||
finalprops = {},
|
||||
ratio = {img:{}, disp: {}};
|
||||
|
||||
ratio.img.h = img.height;// image natural height
|
||||
ratio.img.w = img.width;// image natural width
|
||||
ratio.disp.h = image.height(); // image diplay heigth
|
||||
ratio.disp.w = image.width(); // image diplay width
|
||||
ratio.h = (ratio.img.h / ratio.disp.h);
|
||||
ratio.w = (ratio.img.w / ratio.disp.w);
|
||||
|
||||
/*
|
||||
var sourceX = 150;
|
||||
var sourceY = 0;
|
||||
var sourceWidth = 150;
|
||||
var sourceHeight = 150;
|
||||
var destWidth = sourceWidth;
|
||||
var destHeight = sourceHeight;
|
||||
var destX = canvas.width / 2 - destWidth / 2;
|
||||
var destY = canvas.height / 2 - destHeight / 2;
|
||||
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
|
||||
*/
|
||||
|
||||
// props are related to displayed size of image.
|
||||
// apply w/h ratio to props to get fprops which will be related to 'real' image dimensions
|
||||
finalprops.x = props.x * ratio.w;
|
||||
finalprops.y = props.y * ratio.h;
|
||||
finalprops.w = props.w * ratio.w;
|
||||
finalprops.h = props.h * ratio.h;
|
||||
context.drawImage(img,
|
||||
finalprops.x, finalprops.y,
|
||||
finalprops.w, finalprops.h,
|
||||
0,0,
|
||||
// props.x2, props.y2,
|
||||
props.w, props.h);
|
||||
$('body').append(canvas);
|
||||
}
|
||||
|
||||
if (window.Aloha === undefined || window.Aloha === null) {
|
||||
var Aloha = window.Aloha = {};
|
||||
}
|
||||
|
||||
Aloha.settings = {
|
||||
|
||||
logLevels: {'error': true, 'warn': true, 'info': true, 'debug': false},
|
||||
|
||||
'plugins': {
|
||||
'image': {
|
||||
'fixedAspectRatio': false,
|
||||
'maxWidth': 1024,
|
||||
'minWidth': 10,
|
||||
'maxHeight': 786,
|
||||
'minHeight': 10,
|
||||
'globalselector': '.global'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(window);
|
||||
</script>
|
||||
|
||||
<script src="../../../../lib/aloha.js" data-aloha-plugins="common/format, common/highlighteditables, common/image"></script>
|
||||
|
||||
<link rel="stylesheet" href="../../../../css/aloha.css" id="aloha-style-include" type="text/css">
|
||||
<link rel="stylesheet" href="../../../../demo/common/index.css" type="text/css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
|
||||
<div id="tree-div"></div>
|
||||
<h1 id="title">Aloha, Images!</h1>
|
||||
<div id="bodyContent">
|
||||
<div id="teaser" class="shorttext">
|
||||
<p>This example will show you how to use the Image plugin found at <a href="https://github.com/alohaeditor/Aloha-Plugin-Image">https://github.com/alohaeditor/Aloha-Plugin-Image</a>.</p>
|
||||
</div>
|
||||
<div id="content" class="article">
|
||||
|
||||
<p><img src="cropnresize.jpg"></p>
|
||||
<p>Click the image to start resizing right away, as a resize handle will appear in it's south-east corner.</p>
|
||||
|
||||
<p><em>Note:</em> This is a very simple example, that will not allow subsequent cropping actions, or cropping combined with resizing.</p>
|
||||
</div>
|
||||
|
||||
Outside of the editable
|
||||
<p><img class="global" src="cropnresize.jpg"></p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
Aloha.ready( function(){
|
||||
var $ = Aloha.jQuery;
|
||||
$('#title').aloha();
|
||||
$('#teaser').aloha();
|
||||
$('#content').aloha();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 635 B |
@@ -1,12 +0,0 @@
|
||||
#content {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-wrapper {
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
position: relative !important;
|
||||
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Aloha, Images!</title>
|
||||
|
||||
<script type="text/javascript" src="../../../../lib/vendor/jquery-1.6.1.js"></script>
|
||||
<script type="text/javascript" src="../vendor/ui/jquery-ui-1.8.10.custom.min.js"></script>
|
||||
<link href="../vendor/ui/ui-lightness/jquery-ui-1.8.10.cropnresize.css" rel="stylesheet" type="text/css" />
|
||||
<link rel="stylesheet" href="../../../../demo/common/index.css" type="text/css">
|
||||
<link rel="stylesheet" href="test.css" type="text/css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
$("#myimg").resizable({
|
||||
grid: 10,
|
||||
minHeight: 10,
|
||||
minWidth: 10,
|
||||
maxHeight: 800,
|
||||
maxWidth: 900,
|
||||
handles: 'ne, se, sw, nw',
|
||||
stop : function (event, ui) {
|
||||
console.log("stop");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="main">
|
||||
<div id="content">
|
||||
<img id="myimg" src="../demo/cropnresize.jpg" width="200px" height="135px">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -1,264 +0,0 @@
|
||||
/* delicious.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/**
|
||||
* Create the Repositories object. Namespace for Repositories
|
||||
* @hide
|
||||
*/
|
||||
if ( !GENTICS.Aloha.Repositories ) GENTICS.Aloha.Repositories = {};
|
||||
|
||||
/**
|
||||
* register the plugin with unique name
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious = new GENTICS.Aloha.Repository('delicious');
|
||||
|
||||
/**
|
||||
* If no username is given, the public respoitory is searched:
|
||||
* @property
|
||||
* @cfg
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious.settings.username = 'draftkraft';
|
||||
|
||||
/**
|
||||
* Defines the value to use for sorting the items. Allowed a values 0-0.75
|
||||
* We choose a low default weight 0.35
|
||||
* @property
|
||||
* @default 0.35
|
||||
* @cfg
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious.settings.weight = 0.35;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* init Delicious repository
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious.init = function() {
|
||||
var that = this;
|
||||
|
||||
// check weight
|
||||
if ( this.settings.weight + 0.15 > 1 ) {
|
||||
this.settings.weight = 1 - 0.15;
|
||||
}
|
||||
|
||||
// default delicious URL. Returns most popular links.
|
||||
this.deliciousURL = "http://feeds.delicious.com/v2/json/";
|
||||
|
||||
if ( this.settings.username ) {
|
||||
|
||||
// if a username is set use public user links
|
||||
this.deliciousURL += this.settings.username + '/';
|
||||
|
||||
// set the repository name
|
||||
this.repositoryName = 'deliciuos/' + this.settings.username;
|
||||
|
||||
// when a user is specified get his tags and store it local
|
||||
this.tags = [];
|
||||
|
||||
jQuery.ajax({ type: "GET",
|
||||
dataType: "jsonp",
|
||||
url: 'http://feeds.delicious.com/v2/json/tags/'+that.settings.username,
|
||||
success: function(data) {
|
||||
// convert data
|
||||
for (var tag in data) {
|
||||
that.tags.push(tag);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// set the repository name
|
||||
this.repositoryName = 'deliciuos/' + popular;
|
||||
|
||||
this.deliciousURL += 'tag/';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Searches a repository for items matching query if objectTypeFilter.
|
||||
* If none found it returns null.
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious.query = function( p, callback) {
|
||||
var that = this;
|
||||
|
||||
if ( p.objectTypeFilter && jQuery.inArray('website', p.objectTypeFilter) == -1) {
|
||||
|
||||
// return if no website type is requested
|
||||
callback.call( this, []);
|
||||
|
||||
} else {
|
||||
|
||||
// prepare tags
|
||||
var tags = [];
|
||||
if ( this.settings.username ) {
|
||||
|
||||
// search in user tags
|
||||
var queryTags = p.queryString ? p.queryString.split(' ') : [];
|
||||
for (var i = 0; i < queryTags.length; i++) {
|
||||
var queryTag = queryTags[i].trim();
|
||||
if ( jQuery.inArray(queryTag, that.tags) == -1 ) {
|
||||
var newtags = that.tags.filter(function(e, i, a) {
|
||||
var r = new RegExp(queryTag, 'i');
|
||||
return ( e.match(r) );
|
||||
});
|
||||
if ( newtags.length > 0 ) {
|
||||
tags.push(newtags[0]);
|
||||
}
|
||||
} else {
|
||||
tags.push(queryTag);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// handle each word as tag
|
||||
tags = p.queryString.split(' ');
|
||||
|
||||
}
|
||||
|
||||
// search in tree
|
||||
var folderTags = p.inFolderId ? p.inFolderId.split('+') : [];
|
||||
jQuery.extend(tags, folderTags);
|
||||
|
||||
// if we have a query and no tag matching return
|
||||
if ( p.queryString && tags.length == 0 ) {
|
||||
callback.call( that, []);
|
||||
return;
|
||||
}
|
||||
|
||||
jQuery.ajax({ type: "GET",
|
||||
dataType: "jsonp",
|
||||
url: that.deliciousURL + tags.join('+'),
|
||||
success: function(data) {
|
||||
var items = [];
|
||||
// convert data to Aloha objects
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (typeof data[i] != 'function' ) {
|
||||
items.push(new GENTICS.Aloha.Repository.Document ({
|
||||
id: data[i].u,
|
||||
name: data[i].d,
|
||||
repositoryId: that.repositoryId,
|
||||
type: 'website',
|
||||
url: data[i].u,
|
||||
weight: that.settings.weight + (15-1)/100
|
||||
}));
|
||||
}
|
||||
}
|
||||
callback.call( that, items);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all tags for username in a tree style way
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious.getChildren = function( p, callback) {
|
||||
var that = this;
|
||||
|
||||
// tags are only available when a username is available
|
||||
if ( this.settings.username ) {
|
||||
|
||||
// return all tags
|
||||
var items = [];
|
||||
if ( p.inFolderId == this.repositoryId ) {
|
||||
|
||||
for (var i = 0; i < this.tags.length; i++) {
|
||||
if (typeof this.tags[i] != 'function' ) {
|
||||
items.push(new GENTICS.Aloha.Repository.Folder ({
|
||||
id: this.tags[i],
|
||||
name: this.tags[i],
|
||||
repositoryId: this.repositoryId,
|
||||
type: 'tag',
|
||||
url: 'http://feeds.delicious.com/v2/rss/tags/'+that.settings.username+'/'+this.tags[i]
|
||||
}));
|
||||
}
|
||||
}
|
||||
callback.call( this, items);
|
||||
|
||||
} else {
|
||||
jQuery.ajax({ type: "GET",
|
||||
dataType: "jsonp",
|
||||
url: 'http://feeds.delicious.com/v2/json/tags/'+that.settings.username+'/'+p.inFolderId,
|
||||
success: function(data) {
|
||||
var items = [];
|
||||
// convert data
|
||||
for (var tag in data) {
|
||||
// the id is tag[+tag+...+tag]
|
||||
var id = (p.inFolderId)?p.inFolderId + '+' + tag:tag;
|
||||
if (typeof data[tag] != 'function' ) {
|
||||
items.push(new GENTICS.Aloha.Repository.Folder({
|
||||
id: id,
|
||||
name: tag,
|
||||
repositoryId: that.repositoryId,
|
||||
type: 'tag',
|
||||
url: 'http://feeds.delicious.com/v2/rss/tags/'+that.settings.username+'/'+id,
|
||||
hasMoreItems: true
|
||||
}));
|
||||
}
|
||||
}
|
||||
callback.call( that, items);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
} else {
|
||||
callback.call( this, []);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the repositoryItem with given id
|
||||
* @param itemId {String} id of the repository item to fetch
|
||||
* @param callback {function} callback function
|
||||
* @return {GENTICS.Aloha.Repository.Object} item with given id
|
||||
*/
|
||||
GENTICS.Aloha.Repositories.delicious.getObjectById = function ( itemId, callback ) {
|
||||
var that = this;
|
||||
|
||||
jQuery.ajax({
|
||||
type: 'GET',
|
||||
dataType: "jsonp",
|
||||
url: 'http://feeds.delicious.com/v2/json/urlinfo/' + jQuery.md5(itemId),
|
||||
success: function (data) {
|
||||
var items = [];
|
||||
// convert data to Aloha objects
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (typeof data[i] != 'function' ) {
|
||||
items.push(new GENTICS.Aloha.Repository.Document ({
|
||||
id: itemId,
|
||||
name: data[i].title,
|
||||
repositoryId: that.repositoryId,
|
||||
type: 'website',
|
||||
url: itemId,
|
||||
weight: that.settings.weight + (15-1)/100
|
||||
}));
|
||||
}
|
||||
}
|
||||
callback.call( that, items);
|
||||
}
|
||||
});
|
||||
};
|
@@ -1,247 +0,0 @@
|
||||
/* linklist.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/* Aloha Link List Repository
|
||||
* --------------------------
|
||||
* A simple demo repository of links.
|
||||
*/
|
||||
define(
|
||||
[ 'aloha', 'aloha/jquery' ],
|
||||
function ( Aloha, jQuery ) {
|
||||
|
||||
|
||||
/**
|
||||
* Internal data as array with following format:
|
||||
*
|
||||
* [
|
||||
* { name: 'Aloha Editor - The HTML5 Editor', url: 'http://aloha-editor.org', type: 'website' },
|
||||
* { name: 'Aloha Editor - Wiki', url: 'http://github.com/alohaeditor/Aloha-Editor/wiki', type: 'website' },
|
||||
* { name: 'Aloha Editor - GitHub', url: 'http://github.com/alohaeditor/Aloha-Editor', type: 'website' },
|
||||
* { name: 'Aloha Logo', url: 'http://www.aloha-editor.com/images/aloha-editor-logo.png', type: 'image' }
|
||||
* ];
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var urls = [
|
||||
{ name: 'Aloha Editor - The HTML5 Editor', url: 'http://aloha-editor.org', type: 'website' },
|
||||
{ name: 'Aloha Editor - Wiki', url: 'http://github.com/alohaeditor/Aloha-Editor/wiki', type: 'website' },
|
||||
{ name: 'Aloha Editor - GitHub', url: 'http://github.com/alohaeditor/Aloha-Editor', type: 'website' },
|
||||
{ name: 'Aloha Logo', url: 'http://www.aloha-editor.com/images/aloha-editor-logo.png', type: 'image' }
|
||||
];
|
||||
|
||||
new ( Aloha.AbstractRepository.extend( {
|
||||
|
||||
_constructor: function () {
|
||||
this._super( 'linklist' );
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {array.<?>} Internal folder structure.
|
||||
*/
|
||||
folder: [],
|
||||
|
||||
/**
|
||||
* Initalize LinkList, parse all links, build folder structure and add
|
||||
* additional properties to the items.
|
||||
*/
|
||||
init: function () {
|
||||
if ( Aloha.settings.repositories &&
|
||||
Aloha.settings.repositories.linklist &&
|
||||
Aloha.settings.repositories.linklist.data ) {
|
||||
urls = urls.concat(Aloha.settings.repositories.linklist.data);
|
||||
}
|
||||
|
||||
// Add ECMA262-5 Array method filter if not supported natively.
|
||||
// But we will be very conservative and add to this single array
|
||||
// object so that we do not tamper with the native Array prototype
|
||||
// object.
|
||||
if ( !( 'filter' in Array.prototype ) ) {
|
||||
urls.filter = function ( filter, that /*opt*/ ) {
|
||||
var other = [],
|
||||
v,
|
||||
i = 0,
|
||||
n = this.length;
|
||||
|
||||
for ( ; i < n; i++ ) {
|
||||
if ( i in this && filter.call( that, v = this[ i ], i, this ) ) {
|
||||
other.push( v );
|
||||
}
|
||||
}
|
||||
|
||||
return other;
|
||||
};
|
||||
}
|
||||
|
||||
var l = urls.length;
|
||||
|
||||
// generate folder structure
|
||||
for ( var i = 0; i < l; ++i ) {
|
||||
var e = urls[ i ];
|
||||
e.repositoryId = this.repositoryId;
|
||||
e.id = e.id ? e.id : e.url;
|
||||
|
||||
var u = e.uri = this.parseUri( e.url ),
|
||||
// add hostname as root folder
|
||||
path = this.addFolder( '', u.host ),
|
||||
pathparts = u.path.split( '/' );
|
||||
|
||||
for ( var j = 0; j < pathparts.length; j++ ) {
|
||||
if ( pathparts[ j ] &&
|
||||
// It's a file because it has an extension.
|
||||
// Could improve this one :)
|
||||
pathparts[ j ].lastIndexOf( '.' ) < 0 ) {
|
||||
path = this.addFolder( path, pathparts[ j ] );
|
||||
}
|
||||
}
|
||||
|
||||
e.parentId = path;
|
||||
|
||||
urls[ i ] = new Aloha.RepositoryDocument( e );
|
||||
}
|
||||
|
||||
this.repositoryName = 'Linklist';
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {String} path
|
||||
* @param {String} name
|
||||
* @return {String}
|
||||
*/
|
||||
addFolder: function ( path, name ) {
|
||||
var type = path ? 'folder' : 'hostname';
|
||||
var p = path ? path + '/' + name : name;
|
||||
|
||||
if ( name && !this.folder[ p ] ) {
|
||||
this.folder[ p ] = new Aloha.RepositoryFolder( {
|
||||
id: p,
|
||||
name: name || p,
|
||||
parentId: path,
|
||||
type: 'host',
|
||||
repositoryId: this.repositoryId
|
||||
} );
|
||||
}
|
||||
|
||||
return p;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches a repository for object items matching query if
|
||||
* objectTypeFilter. If none is found it returns null.
|
||||
*
|
||||
* @param {Object} p
|
||||
* @param {Function} callback
|
||||
*/
|
||||
query: function ( p, callback ) {
|
||||
// Not supported; filter, orderBy, maxItems, skipcount, renditionFilter
|
||||
var r = new RegExp( p.queryString, 'i' );
|
||||
var d = urls.filter( function ( e, i, a ) {
|
||||
return (
|
||||
( !p.queryString || e.name.match( r ) || e.url.match( r ) ) &&
|
||||
( !p.objectTypeFilter || ( !p.objectTypeFilter.length ) || jQuery.inArray( e.type, p.objectTypeFilter ) > -1 ) &&
|
||||
true //( !p.inFolderId || p.inFolderId == e.parentId )
|
||||
);
|
||||
} );
|
||||
|
||||
callback.call( this, d );
|
||||
},
|
||||
|
||||
/**
|
||||
* returns the folder structure as parsed at init
|
||||
*
|
||||
* @param {Object} p
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getChildren: function ( p, callback ) {
|
||||
var d = [], e;
|
||||
|
||||
for ( e in this.folder ) {
|
||||
var l = this.folder[ e ].parentId;
|
||||
if ( typeof this.folder[ e ] != 'function' && ( // extjs prevention
|
||||
this.folder[ e ].parentId == p.inFolderId || // all subfolders
|
||||
( !this.folder[ e ].parentId && p.inFolderId == this.repositoryId ) // the hostname
|
||||
) ) {
|
||||
d.push( this.folder[ e ] );
|
||||
}
|
||||
}
|
||||
|
||||
callback.call( this, d );
|
||||
},
|
||||
|
||||
//parseUri 1.2.2
|
||||
//(c) Steven Levithan <stevenlevithan.com>
|
||||
//MIT License
|
||||
//http://blog.stevenlevithan.com/archives/parseuri
|
||||
parseUri: function(str) {
|
||||
var o = {
|
||||
strictMode: false,
|
||||
key: [ "source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
|
||||
q: {
|
||||
name: "queryKey",
|
||||
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
||||
},
|
||||
parser: {
|
||||
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
||||
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
|
||||
}
|
||||
},
|
||||
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
|
||||
uri = {},
|
||||
i = 14;
|
||||
|
||||
while (i--) uri[o.key[i]] = m[i] || "";
|
||||
|
||||
uri[o.q.name] = {};
|
||||
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
|
||||
if ($1) uri[o.q.name][$1] = $2;
|
||||
});
|
||||
|
||||
return uri;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the repositoryItem with given id
|
||||
* Callback: {GENTICS.Aloha.Repository.Object} item with given id
|
||||
* @param itemId {String} id of the repository item to fetch
|
||||
* @param callback {function} callback function
|
||||
*/
|
||||
getObjectById: function ( itemId, callback ) {
|
||||
var i = 0,
|
||||
l = urls.length,
|
||||
d = [];
|
||||
|
||||
for ( ; i < l; i++ ) {
|
||||
if ( urls[ i ].id == itemId ) {
|
||||
d.push( urls[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
callback.call( this, d );
|
||||
}
|
||||
|
||||
}))();
|
||||
|
||||
});
|
@@ -1,247 +0,0 @@
|
||||
/* slowlinklist.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/* Aloha Link List Repository
|
||||
* --------------------------
|
||||
* A simple demo repository of links, which is deliberatly slow, in order to
|
||||
* simulate lags when querying repositories.
|
||||
*/
|
||||
define(
|
||||
[ 'aloha', 'jquery' ],
|
||||
function ( Aloha, jQuery ) {
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Internal data as array with following format:
|
||||
*
|
||||
* [
|
||||
* { name: 'Aloha Editor - The HTML5 Editor', url:'http://aloha-editor.com', type:'website' },
|
||||
* { name: 'Aloha Logo', url:'http://www.aloha-editor.com/images/aloha-editor-logo.png', type:'image' }
|
||||
* ];
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var urlset = [
|
||||
{ name: 'Aloha Test', url: '#alohatest', type: 'website' },
|
||||
{ name: 'Test One', url: '#test1', type: 'website' },
|
||||
{ name: 'Test Two', url: '#test2', type: 'website' },
|
||||
{ name: 'Test Three', url: '#test3', type: 'website' },
|
||||
{ name: 'Test Four', url: '#test4', type: 'image' }
|
||||
];
|
||||
|
||||
new ( Aloha.AbstractRepository.extend( {
|
||||
|
||||
_constructor: function () {
|
||||
this._super( 'slowlinklist' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal folder structure
|
||||
* @hide
|
||||
*/
|
||||
folder: [],
|
||||
|
||||
/**
|
||||
* initalize LinkList, parse all links, build folder structure and add
|
||||
* additional properties to the items
|
||||
*/
|
||||
init: function () {
|
||||
// Add ECMA262-5 Array method filter if not supported natively.
|
||||
// But we will be very conservative and add to this single array
|
||||
// object so that we do not tamper with the native Array prototype
|
||||
// object
|
||||
if ( !( 'filter' in Array.prototype ) ) {
|
||||
urlset.filter = function ( filter, that /*opt*/ ) {
|
||||
var other = [],
|
||||
v,
|
||||
i = 0,
|
||||
n = this.length;
|
||||
|
||||
for ( ; i < n; i++ ) {
|
||||
if ( i in this && filter.call( that, v = this[ i ], i, this ) ) {
|
||||
other.push( v );
|
||||
}
|
||||
}
|
||||
|
||||
return other;
|
||||
};
|
||||
}
|
||||
|
||||
var l = urlset.length;
|
||||
|
||||
// generate folder structure
|
||||
for ( var i = 0; i < l; ++i ) {
|
||||
var e = urlset[ i ];
|
||||
e.repositoryId = this.repositoryId;
|
||||
e.id = e.id ? e.id : e.url;
|
||||
|
||||
var u = e.uri = this.parseUri( e.url ),
|
||||
// add hostname as root folder
|
||||
path = this.addFolder( '', u.host ),
|
||||
pathparts = u.path.split( '/' );
|
||||
|
||||
for ( var j = 0; j < pathparts.length; j++ ) {
|
||||
if ( pathparts[ j ] &&
|
||||
// It's a file because it has an extension.
|
||||
// Could improve this one :)
|
||||
pathparts[ j ].lastIndexOf( '.' ) < 0 ) {
|
||||
path = this.addFolder( path, pathparts[ j ] );
|
||||
}
|
||||
}
|
||||
|
||||
e.parentId = path;
|
||||
|
||||
urlset[ i ] = new Aloha.RepositoryDocument( e );
|
||||
}
|
||||
|
||||
this.repositoryName = 'Linklist';
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {String} path
|
||||
* @param {String} name
|
||||
* @return {String}
|
||||
*/
|
||||
addFolder: function ( path, name ) {
|
||||
var type = path ? 'folder' : 'hostname',
|
||||
p = path ? path + '/' + name : name;
|
||||
|
||||
if ( name && !this.folder[ p ] ) {
|
||||
this.folder[ p ] = new Aloha.RepositoryFolder( {
|
||||
id: p,
|
||||
name: name || p,
|
||||
parentId: path,
|
||||
type: 'host',
|
||||
repositoryId: this.repositoryId
|
||||
} );
|
||||
}
|
||||
|
||||
return p;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches a repository for object items matching query if
|
||||
* objectTypeFilter. If none is found it returns null.
|
||||
*
|
||||
* @param {Object} p
|
||||
* @param {Function} callback
|
||||
*/
|
||||
query: function ( p, callback ) {
|
||||
// Not supported; filter, orderBy, maxItems, skipcount, renditionFilter
|
||||
var r = new RegExp( p.queryString, 'i' );
|
||||
|
||||
var d = urlset.filter( function ( e, i, a ) {
|
||||
return (
|
||||
( !p.queryString || e.name.match( r ) || e.url.match( r ) ) &&
|
||||
( !p.objectTypeFilter || ( !p.objectTypeFilter.length ) || jQuery.inArray( e.type, p.objectTypeFilter ) > -1 ) &&
|
||||
true //( !p.inFolderId || p.inFolderId == e.parentId )
|
||||
);
|
||||
} );
|
||||
|
||||
window.setTimeout( function () {
|
||||
callback.call( this, d );
|
||||
}, 2000 );
|
||||
},
|
||||
|
||||
/**
|
||||
* returns the folder structure as parsed at init
|
||||
*
|
||||
* @param {Object} p
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getChildren: function ( p, callback ) {
|
||||
var d = [],
|
||||
e;
|
||||
|
||||
for ( e in this.folder ) {
|
||||
var l = this.folder[ e ].parentId;
|
||||
if ( typeof this.folder[ e ] != 'function' && ( // extjs prevention
|
||||
this.folder[ e ].parentId == p.inFolderId || // all subfolders
|
||||
( !this.folder[ e ].parentId && p.inFolderId == this.repositoryId ) // the hostname
|
||||
) ) {
|
||||
d.push( this.folder[ e ] );
|
||||
}
|
||||
}
|
||||
|
||||
window.setTimeout( function () {
|
||||
callback.call( this, d );
|
||||
}, 2000 );
|
||||
},
|
||||
|
||||
//parseUri 1.2.2
|
||||
//(c) Steven Levithan <stevenlevithan.com>
|
||||
//MIT License
|
||||
//http://blog.stevenlevithan.com/archives/parseuri
|
||||
parseUri: function(str) {
|
||||
var o = {
|
||||
strictMode: false,
|
||||
key: [ "source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
|
||||
q: {
|
||||
name: "queryKey",
|
||||
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
||||
},
|
||||
parser: {
|
||||
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
||||
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
|
||||
}
|
||||
},
|
||||
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
|
||||
uri = {},
|
||||
i = 14;
|
||||
|
||||
while (i--) uri[o.key[i]] = m[i] || "";
|
||||
|
||||
uri[o.q.name] = {};
|
||||
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
|
||||
if ($1) uri[o.q.name][$1] = $2;
|
||||
});
|
||||
|
||||
return uri;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the repositoryItem with given id
|
||||
* Callback: {GENTICS.Aloha.Repository.Object} item with given id
|
||||
* @param itemId {String} id of the repository item to fetch
|
||||
* @param callback {function} callback function
|
||||
*/
|
||||
getObjectById: function ( itemId, callback ) {
|
||||
var i = 0,
|
||||
l = urlset.length,
|
||||
d = [];
|
||||
|
||||
for ( ; i < l; i++ ) {
|
||||
if ( urlset[ i ].id == itemId ) {
|
||||
d.push( urlset[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
callback.call( this, d );
|
||||
}
|
||||
|
||||
} ) )();
|
||||
|
||||
} );
|
Before Width: | Height: | Size: 5.3 KiB |
1
media/aloha-0.22.3/css/aloha-common-extra.css → media/aloha-0.22.7/css/aloha-common-extra.css
Normal file → Executable file
@@ -20,4 +20,5 @@
|
||||
@import "../plugins/extra/ribbon/css/ribbon.css";
|
||||
@import "../plugins/extra/headerids/css/headerids.css";
|
||||
@import "../plugins/extra/metaview/css/metaview.css";
|
||||
@import "../plugins/extra/textcolor/css/textcolor.css";
|
||||
|
Before Width: | Height: | Size: 770 B After Width: | Height: | Size: 770 B |
Before Width: | Height: | Size: 790 B After Width: | Height: | Size: 790 B |
Before Width: | Height: | Size: 719 B After Width: | Height: | Size: 719 B |
0
media/aloha-0.22.3/img/base-multi.png → media/aloha-0.22.7/img/base-multi.png
Normal file → Executable file
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
media/aloha-0.22.7/img/base.png
Executable file
After Width: | Height: | Size: 5.7 KiB |
0
media/aloha-0.22.3/img/bg.png → media/aloha-0.22.7/img/bg.png
Normal file → Executable file
Before Width: | Height: | Size: 509 KiB After Width: | Height: | Size: 509 KiB |
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 330 B |
0
media/aloha-0.22.3/img/gentics-logo.png → media/aloha-0.22.7/img/gentics-logo.png
Normal file → Executable file
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
0
media/aloha-0.22.3/img/grabhandle.png → media/aloha-0.22.7/img/grabhandle.png
Normal file → Executable file
Before Width: | Height: | Size: 112 B After Width: | Height: | Size: 112 B |
0
media/aloha-0.22.3/img/maximize.png → media/aloha-0.22.7/img/maximize.png
Normal file → Executable file
Before Width: | Height: | Size: 123 B After Width: | Height: | Size: 123 B |
0
media/aloha-0.22.3/img/multisplit-base.jpg → media/aloha-0.22.7/img/multisplit-base.jpg
Normal file → Executable file
Before Width: | Height: | Size: 929 B After Width: | Height: | Size: 929 B |
0
media/aloha-0.22.3/img/multisplit-close.gif → media/aloha-0.22.7/img/multisplit-close.gif
Normal file → Executable file
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 211 B |
0
media/aloha-0.22.3/img/multisplit-open.gif → media/aloha-0.22.7/img/multisplit-open.gif
Normal file → Executable file
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 211 B |
0
media/aloha-0.22.3/img/pin.png → media/aloha-0.22.7/img/pin.png
Normal file → Executable file
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 564 B |
0
media/aloha-0.22.3/img/removeformat.png → media/aloha-0.22.7/img/removeformat.png
Normal file → Executable file
Before Width: | Height: | Size: 193 B After Width: | Height: | Size: 193 B |
0
media/aloha-0.22.3/img/text_indent.png → media/aloha-0.22.7/img/text_indent.png
Normal file → Executable file
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 353 B |
0
media/aloha-0.22.3/img/text_indent_remove.png → media/aloha-0.22.7/img/text_indent_remove.png
Normal file → Executable file
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 351 B |
12
media/aloha-0.22.7/lib/aloha-jquery-noconflict.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// To be included in the compiled aloha-full.js (which includes
|
||||
// requirejs and jQuery) immediately after jQuery. This will prevent
|
||||
// Aloha's jQuery from polluting the global namespace.
|
||||
// TODO: requirejs shouldn't leak either
|
||||
// NB: this is only for aloha-full.js to preserve behaviour with the way
|
||||
// older builds of aloha were done. It is now always preferred to use
|
||||
// aloha-bare.js (which doesn't include either requirejs or jQuery) and
|
||||
// let the implementer worry exactly how to set up jQuery and requirejs
|
||||
// to suit his needs.
|
||||
Aloha = window.Aloha || {};
|
||||
Aloha.settings = Aloha.settings || {};
|
||||
Aloha.settings.jQuery = Aloha.settings.jQuery || jQuery.noConflict(true);
|
591
media/aloha-0.22.7/lib/aloha.js
Normal file
@@ -0,0 +1,591 @@
|
||||
/* aloha.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
(function (global) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Initialization facilities.
|
||||
*/
|
||||
var Initialization = {
|
||||
|
||||
/**
|
||||
* A list of all stages that are passed into the Initialization.start()
|
||||
* function. Unless failure happens, every single one of these phases
|
||||
* will be passed.
|
||||
*
|
||||
* @type {Array.<object>}
|
||||
*/
|
||||
phases: [],
|
||||
|
||||
/**
|
||||
* Completed phases.
|
||||
*
|
||||
* This array grows as the initialization process progresses through
|
||||
* the initialization phases. Each phases which is completed is pushed
|
||||
* to the bottom of the list.
|
||||
*
|
||||
* @type {Array.<object>}
|
||||
*/
|
||||
completed: [],
|
||||
|
||||
/**
|
||||
* Starts the initialization phases.
|
||||
*
|
||||
* @param {object.<object>} phases Initialization phases.
|
||||
* @param {function} callback Callback function to be invoked when
|
||||
* initialization is completed.
|
||||
*/
|
||||
start: function (phases, callback) {
|
||||
Initialization.phases = Initialization.phases.concat(phases);
|
||||
Initialization.proceed(0, phases, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Proceeds to next initialization phase.
|
||||
*
|
||||
* @param {number} index The current initialization phase, as an index
|
||||
* into `phases'.
|
||||
* @param {Array.<object>} phases
|
||||
* @param {function=} callback Callback function to invoke at the end
|
||||
* of the initialization phases.
|
||||
*/
|
||||
proceed: function (index, phases, callback) {
|
||||
if (index < phases.length) {
|
||||
var phase = phases[index];
|
||||
var next = function () {
|
||||
Initialization.proceed(++index, phases, callback);
|
||||
};
|
||||
var event = function () {
|
||||
Initialization.completed.push(phase);
|
||||
if (phase.event) {
|
||||
Aloha.trigger(phase.event);
|
||||
}
|
||||
};
|
||||
if (phase.fn) {
|
||||
phase.fn(event, next);
|
||||
} else {
|
||||
event();
|
||||
next();
|
||||
}
|
||||
} else if (callback) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retreives an phase object whose `event' property string matches the
|
||||
* given event name.
|
||||
*
|
||||
* @param {string} event The event name.
|
||||
* @return {object} A phase object or null.
|
||||
*/
|
||||
getPhaseByEvent: function (event) {
|
||||
var i;
|
||||
for (i = 0; i < Initialization.phases.length; i++) {
|
||||
if (event === Initialization.phases[i].event) {
|
||||
return Initialization.phases[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Given and the name of an event, returns a corresponding readiness
|
||||
* state concerning what should be done with that event at the current
|
||||
* stage in the initialization phase.
|
||||
*
|
||||
* @param {string} event Name of event.
|
||||
* @return {string} One of either "immediate", "deferred", or "noraml".
|
||||
*/
|
||||
getReadiness: function (event) {
|
||||
var i;
|
||||
for (i = 0; i < Initialization.completed.length; i++) {
|
||||
if (event === Initialization.completed[i].event) {
|
||||
return 'immediate';
|
||||
}
|
||||
}
|
||||
return Initialization.getPhaseByEvent(event) ? 'deferred'
|
||||
: 'normal';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the configuration for loading Aloha.
|
||||
*
|
||||
* If Aloha.settings.baseUrl is not specified, it will be taken from
|
||||
* the first script element that has a data-aloha-plugins attribute,
|
||||
* or, if there is no such script element, the first script element
|
||||
* of which the src attribute matches /\/aloha.js$/.
|
||||
*
|
||||
* If Aloha.settings.plugins.load is not specified, it will be taken
|
||||
* from the data-aloha-plugins attribute from the first script
|
||||
* element carrying this attribute.
|
||||
*
|
||||
* @return
|
||||
* A map with two properties:
|
||||
* baseUrl - the path to aloha.js (this file).
|
||||
* plugins - an array of plugins to load.
|
||||
*/
|
||||
function getLoadConfig() {
|
||||
var scripts,
|
||||
script,
|
||||
plugins = Aloha.settings.plugins && Aloha.settings.plugins.load,
|
||||
baseUrl = Aloha.settings.baseUrl,
|
||||
pluginsAttr,
|
||||
regexAlohaJs = /\/aloha.js(\?\S*)?$/,
|
||||
regexStripFilename = /\/[^\/]*\.js$/,
|
||||
i;
|
||||
|
||||
if (!plugins || !baseUrl) {
|
||||
scripts = document.getElementsByTagName('script');
|
||||
for (i = 0; i < scripts.length; i++) {
|
||||
script = scripts[i];
|
||||
pluginsAttr = script.getAttribute('data-aloha-plugins');
|
||||
if (null != pluginsAttr) {
|
||||
if (!plugins) {
|
||||
plugins = pluginsAttr;
|
||||
}
|
||||
if (!baseUrl) {
|
||||
baseUrl = script.src.replace(regexStripFilename, '');
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!baseUrl && regexAlohaJs.test(script.src)) {
|
||||
baseUrl = script.src.replace(regexAlohaJs, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof plugins === 'string' && plugins !== '') {
|
||||
plugins = plugins.replace(/\s+/g, '').split(',');
|
||||
}
|
||||
|
||||
return {
|
||||
baseUrl: baseUrl,
|
||||
plugins: plugins || []
|
||||
};
|
||||
}
|
||||
|
||||
function isDeferInit() {
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
var attr = scripts[i].getAttribute('data-aloha-defer-init');
|
||||
if ("true" === attr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the given map with plugin specific requirejs path configuration.
|
||||
*
|
||||
* plugin-name: bundle-path/plugin-name/lib
|
||||
* plugin-name/nls: bundle-path/plugin-name/nls
|
||||
* plugin-name/css: bundle-path/plugin-name/css
|
||||
* plugin-name/vendor: bundle-path/plugin-name/vendor
|
||||
* plugin-name/res: bundle-path/plugin-name/res
|
||||
*/
|
||||
function mergePluginPaths(paths, bundlePath, pluginName) {
|
||||
var resourceFolders = ['nls', 'css', 'vendor', 'res'],
|
||||
resourceFolder,
|
||||
i;
|
||||
paths[pluginName] = bundlePath + '/' + pluginName + '/lib';
|
||||
for (i = 0; i < resourceFolders.length; i++) {
|
||||
var resourceFolder = resourceFolders[i];
|
||||
paths[pluginName + '/' + resourceFolder]
|
||||
= bundlePath + '/' + pluginName + '/' + resourceFolder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration for loading the given plugins.
|
||||
*
|
||||
* The bundle-path for each given plugin is determined in the following manner:
|
||||
* Aloha.settings.basePath + (Aloha.settings.bundles[bundleName] || "../plugins/bundle-name")
|
||||
*
|
||||
* @param plugins
|
||||
* An array of plugins to get the configuration for in the
|
||||
* form "bundle-name/plugin-name"
|
||||
* @return
|
||||
* A map with the following properties:
|
||||
* paths - requirejs path configuration for each plugin (mergePluginPaths())
|
||||
* entryPoints - an array of requirejs entry points ("link/link-plugin")
|
||||
* baseUrlByName - ("link" => "bundle-path/link")
|
||||
* names - an array of plugin names (the same as the given
|
||||
* array with the bundle-name stripped)
|
||||
*/
|
||||
function getPluginLoadConfig(plugins) {
|
||||
var paths = {},
|
||||
entryPoints = [],
|
||||
names = [],
|
||||
baseUrlByName = {},
|
||||
map = {},
|
||||
parts,
|
||||
bundleName,
|
||||
pluginName,
|
||||
basePath = Aloha.settings.basePath || '',
|
||||
bundlePath,
|
||||
bundles = Aloha.settings.bundles || {},
|
||||
i;
|
||||
for (i = 0; i < plugins.length; i++) {
|
||||
parts = plugins[i].split('/');
|
||||
bundleName = parts[0];
|
||||
pluginName = parts[1];
|
||||
if (bundles[bundleName]) {
|
||||
bundlePath = basePath + bundles[bundleName];
|
||||
} else {
|
||||
bundlePath = basePath + '../plugins/' + bundleName;
|
||||
}
|
||||
mergePluginPaths(paths, bundlePath, pluginName);
|
||||
baseUrlByName[pluginName] = bundlePath + '/' + pluginName;
|
||||
entryPoints.push(pluginName + '/' + pluginName + '-plugin');
|
||||
map[pluginName] = {'jquery': 'aloha/jquery'};
|
||||
}
|
||||
return {
|
||||
paths: paths,
|
||||
entryPoints: entryPoints,
|
||||
baseUrlByName: baseUrlByName,
|
||||
names: names,
|
||||
map: map
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges properites of all given arguments into a new one.
|
||||
* Duplicate properties will be "seived" out.
|
||||
* Works in a similar way to jQuery.extend.
|
||||
* Necessary because we must not assume that jquery was already
|
||||
* loaded.
|
||||
*/
|
||||
function mergeObjects () {
|
||||
var clone = {};
|
||||
var objects = Array.prototype.slice.call(arguments);
|
||||
var name;
|
||||
var i;
|
||||
var obj;
|
||||
for (i = 0; i < objects.length; i++) {
|
||||
obj = objects[i];
|
||||
for (name in obj) {
|
||||
if (obj.hasOwnProperty(name)) {
|
||||
clone[name] = objects[i][name];
|
||||
}
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
function createDefine(name, module) {
|
||||
define(name, function () {
|
||||
return module;
|
||||
});
|
||||
}
|
||||
|
||||
function load() {
|
||||
Aloha.features = {};
|
||||
Aloha.defaults = {};
|
||||
Aloha.settings = Aloha.settings || {};
|
||||
Aloha.initialize = Initialization.start;
|
||||
|
||||
var loadConfig = getLoadConfig();
|
||||
var pluginConfig = getPluginLoadConfig(loadConfig.plugins);
|
||||
|
||||
Aloha.settings.baseUrl = loadConfig.baseUrl;
|
||||
Aloha.settings.loadedPlugins = pluginConfig.names;
|
||||
Aloha.settings._pluginBaseUrlByName = pluginConfig.baseUrlByName;
|
||||
|
||||
var coreMap = {
|
||||
'aloha': {'jquery': 'aloha/jquery'},
|
||||
'aloha/jquery': {'jquery': 'jquery'}, // avoid a circular dependency
|
||||
'jqueryui': {'jquery': 'aloha/jquery'},
|
||||
'vendor': {'jquery': 'aloha/jquery'},
|
||||
'util': {'jquery': 'aloha/jquery'},
|
||||
'RepositoryBrowser': {'jquery': 'aloha/jquery'},
|
||||
'jstree': {'jquery': 'aloha/jquery'},
|
||||
'jqgrid': {'jquery': 'aloha/jquery'},
|
||||
'jqgrid-locale-en': {'jquery': 'aloha/jquery'},
|
||||
'jqgrid-locale-de': {'jquery': 'aloha/jquery'},
|
||||
'jquery-layout': {'jquery': 'aloha/jquery'}
|
||||
};
|
||||
|
||||
/**
|
||||
* Map the 'jquery' module to the 'aloha/jquery' module. This
|
||||
* enforces Aloha modules to always use aloha/jquery instead of
|
||||
* jquery. One could also just write
|
||||
* define(['aloha/jquery']... to require Aloha's jquery, but
|
||||
* this is problematic in vendor files that don't know anything
|
||||
* about Aloha. Each key in the map is either the module name,
|
||||
* or the firs part of the module name. For example, the mapping
|
||||
* under the key 'aloha' will take effect for all modules with
|
||||
* names like aloha/xxx. When a new 'paths' entry is added
|
||||
* (browserPaths or other), an entry should also be added the
|
||||
* moduleMap to rename the jquery dependency.
|
||||
* See also define('aloha/jquery', ... below.
|
||||
*/
|
||||
var moduleMap = mergeObjects(coreMap, pluginConfig.map)
|
||||
|
||||
var defaultConfig = {
|
||||
context: 'aloha',
|
||||
locale: Aloha.settings.locale || 'en',
|
||||
baseUrl: Aloha.settings.baseUrl,
|
||||
map: moduleMap
|
||||
};
|
||||
|
||||
var DependencyManagement = global.__DEPS__ || (global.__DEPS__ = {});
|
||||
|
||||
DependencyManagement.lang = defaultConfig.locale;
|
||||
|
||||
var defaultPaths = {
|
||||
jquery: 'vendor/jquery-1.7.2',
|
||||
jqueryui: 'vendor/jquery-ui-1.9m6'
|
||||
};
|
||||
|
||||
var browserPaths = {
|
||||
PubSub: 'vendor/pubsub/js/pubsub-unminified',
|
||||
'Class': 'vendor/class',
|
||||
RepositoryBrowser: 'vendor/repository-browser/js/repository-browser-unminified',
|
||||
jstree: 'vendor/jquery.jstree', // Mutates jquery
|
||||
jqgrid: 'vendor/jquery.jqgrid', // Mutates jquery
|
||||
'jquery-layout': 'vendor/jquery.layout', // Mutates jquery
|
||||
'jqgrid-locale-en': 'vendor/grid.locale.en', // Mutates jqgrid
|
||||
'jqgrid-locale-de': 'vendor/grid.locale.de', // Mutates jqgrid
|
||||
'repository-browser-i18n-de': 'vendor/repository-browser/js/repository-browser-unminified',
|
||||
'repository-browser-i18n-en': 'vendor/repository-browser/js/repository-browser-unminified'
|
||||
};
|
||||
|
||||
var requireConfig = mergeObjects(
|
||||
defaultConfig,
|
||||
Aloha.settings.requireConfig
|
||||
);
|
||||
|
||||
requireConfig.paths = mergeObjects(
|
||||
defaultPaths,
|
||||
browserPaths,
|
||||
pluginConfig.paths,
|
||||
requireConfig.paths
|
||||
);
|
||||
|
||||
// Create define() wrappers that will provide the initialized objects
|
||||
// that the user passes into Aloha via require() calls.
|
||||
var predefinedModules = Aloha.settings.predefinedModules || {};
|
||||
|
||||
if (Aloha.settings.jQuery) {
|
||||
predefinedModules.jquery = Aloha.settings.jQuery;
|
||||
}
|
||||
|
||||
var moduleName;
|
||||
for (moduleName in predefinedModules) if (predefinedModules.hasOwnProperty(moduleName)) {
|
||||
createDefine(moduleName, predefinedModules[moduleName]);
|
||||
delete requireConfig.paths[moduleName];
|
||||
}
|
||||
|
||||
// Configure require and expose the Aloha.require.
|
||||
var alohaRequire = require.config(requireConfig);
|
||||
|
||||
Aloha.require = function (callback) {
|
||||
// Pass the Aloha object to the given callback.
|
||||
if (1 === arguments.length && typeof callback === 'function') {
|
||||
return alohaRequire(['aloha'], callback);
|
||||
}
|
||||
return alohaRequire.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} event Name of event
|
||||
* @param {function} fn Event handler
|
||||
*/
|
||||
Aloha.bind = function (event, fn) {
|
||||
Aloha.require(['aloha/jquery'], function ($) {
|
||||
// Because we will only need to load jQuery once
|
||||
Aloha.bind = function (event, fn) {
|
||||
switch(Initialization.getReadiness(event)) {
|
||||
case 'deferred':
|
||||
var phase = Initialization.getPhaseByEvent(event);
|
||||
if (!phase.deferred) {
|
||||
phase.deferred = $.Deferred();
|
||||
}
|
||||
phase.deferred.done(fn);
|
||||
break;
|
||||
case 'immediate':
|
||||
fn();
|
||||
break;
|
||||
case 'normal':
|
||||
$(Aloha, 'body').bind(event, fn);
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown readiness';
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Aloha.bind(event, fn);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
Aloha.trigger = function (type, data) {
|
||||
Aloha.require(['aloha/jquery'], function ($) {
|
||||
Aloha.trigger = function (type, data) {
|
||||
var phase = Initialization.getPhaseByEvent(type);
|
||||
if (phase) {
|
||||
if (phase.deferred) {
|
||||
$(phase.deferred.resolve);
|
||||
phase.deferred = null;
|
||||
}
|
||||
}
|
||||
$(Aloha, 'body').trigger(type, data);
|
||||
return this;
|
||||
};
|
||||
Aloha.trigger(type, data);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
Aloha.unbind = function (typeOrEvent) {
|
||||
Aloha.require(['aloha/jquery'], function ($) {
|
||||
Aloha.unbind = function (typeOrEvent) {
|
||||
$(Aloha, 'body').unbind(typeOrEvent);
|
||||
};
|
||||
Aloha.unbind(typeOrEvent);
|
||||
});
|
||||
};
|
||||
|
||||
Aloha.ready = function (fn) {
|
||||
this.bind('aloha-ready', fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* This makes sure that all Aloha modules will receive the same jQuery.
|
||||
*
|
||||
* This is a workaround for when a user includes his own
|
||||
* jQuery _after_ aloha.js has been loaded.
|
||||
*
|
||||
* If multiple 'jquery's are included in the page, each version
|
||||
* will make its own call to define(), and depending on when an
|
||||
* Aloha module is loaded, it may receive a different
|
||||
* 'jquery'. However, 'aloha/jquery' will not be redefined and
|
||||
* will therefore point always to only one particular version.
|
||||
*
|
||||
* !!Important!! to be certain that 'aloha/jquery' points to
|
||||
* the jQuery intended for Aloha, it can't be loaded
|
||||
* dynamically, because if a user loads his own jQuery after
|
||||
* aloha.js, then there is no way to tell whether it is the
|
||||
* user's jQuery or Aloha's jQuery that has finished
|
||||
* loading. Instead, jQuery must be loaded before aloha.js and
|
||||
* passed in to us.
|
||||
*/
|
||||
var jQueryThatWasPassedToUs = Aloha.settings.jQuery;
|
||||
define('aloha/jquery', ['jquery'], function ($) {
|
||||
// We prefer Aloha.settings.jQuery, since a dynamically loaded
|
||||
// jQuery may have been redefined by a user's jQuery.
|
||||
return jQueryThatWasPassedToUs || $;
|
||||
});
|
||||
|
||||
// Initialize this early so that the user doesn't have to use
|
||||
// Aloha.ready().
|
||||
Aloha.jQuery = jQueryThatWasPassedToUs;
|
||||
|
||||
define('aloha', [
|
||||
'aloha/jquery',
|
||||
'util/json2',
|
||||
'aloha/rangy-core',
|
||||
'util/class',
|
||||
'util/lang',
|
||||
'util/range',
|
||||
'util/dom',
|
||||
'aloha/core',
|
||||
'aloha/editable',
|
||||
'aloha/console',
|
||||
'aloha/markup',
|
||||
'aloha/plugin',
|
||||
'aloha/selection',
|
||||
'aloha/command',
|
||||
'aloha/jquery.aloha',
|
||||
'aloha/sidebar',
|
||||
'util/position',
|
||||
'aloha/repositorymanager',
|
||||
'aloha/repository',
|
||||
'aloha/repositoryobjects',
|
||||
'aloha/contenthandlermanager'
|
||||
], function($) {
|
||||
Aloha.features.jquery = true;
|
||||
|
||||
// Set it again in case jQuery was loaded asynchronously.
|
||||
Aloha.jQuery = $;
|
||||
|
||||
// Some core files provide default settings in Aloha.defaults.
|
||||
Aloha.settings = $.extendObjects(true, {}, Aloha.defaults,
|
||||
Aloha.settings);
|
||||
|
||||
return Aloha;
|
||||
});
|
||||
|
||||
// TODO aloha should not make the require call itself. Instead, user
|
||||
// code should require and initialize aloha.
|
||||
require(requireConfig, ['aloha', 'aloha/jquery'], function (Aloha, $) {
|
||||
require(requireConfig, pluginConfig.entryPoints, function () {
|
||||
$(function () {
|
||||
// Rangy must be initialized only after the body is
|
||||
// available since it accesses the body element during
|
||||
// initialization.
|
||||
window.rangy.init();
|
||||
|
||||
// The same for Aloha, but probably only because it depends
|
||||
// on rangy.
|
||||
Aloha.init();
|
||||
});
|
||||
});
|
||||
});
|
||||
} // end load()
|
||||
|
||||
global.Aloha = global.Aloha || {};
|
||||
if (global.Aloha.deferInit || isDeferInit()) {
|
||||
global.Aloha.deferInit = load;
|
||||
} else {
|
||||
// Unless init is deferred above, aloha mus be loaded
|
||||
// immediately in the development version, but later in the
|
||||
// compiled version. The reason loading must be delayed in the
|
||||
// compiled version is that the "include" directive in the r.js
|
||||
// build profile, which lists the plugins that will be compiled
|
||||
// into aloha.js, will include the plugins *after* this
|
||||
// file. Since the require() call that loads the plugins is in
|
||||
// this file, it will not see any of the plugin's defines that
|
||||
// come after this file. The call to Aloha._load is only made in
|
||||
// compiled mode in closure-end.frag. The call to load() below
|
||||
// is only made in development mode because the excludeStart and
|
||||
// excludeEnd r.js pragmas will exclude everything inbetween in
|
||||
// the compiled version.
|
||||
// TODO ideally the bootstrap file should not make the require
|
||||
// call at all. Instead, user code should require and
|
||||
// initialize aloha.
|
||||
Aloha._load = load;
|
||||
//>>excludeStart("alohaLoadInEndClosure", pragmas.alohaLoadInEndClosure);
|
||||
load();
|
||||
//>>excludeEnd("alohaLoadInEndClosure");
|
||||
}
|
||||
}(window));
|
151
media/aloha-0.22.7/lib/aloha/block-jump.js
Normal file
@@ -0,0 +1,151 @@
|
||||
/* block-jump.js is part of the Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/**
|
||||
* Implements some logic related to moving the cursor keys across blocks.
|
||||
*
|
||||
* In the following example
|
||||
*
|
||||
* "some text<span class="aloha-block ..." contenteditable="false" ...>...</span>[]some text"
|
||||
*
|
||||
* when one moves the cursor indicated by "[]" to the left, the entire
|
||||
* non-contenteditable block is skipped. The same for moving the cursor
|
||||
* right across the block.
|
||||
*
|
||||
* TODO: actually, the block shouldn't be skipped, it should be
|
||||
* selected/highlighted first.
|
||||
* TODO: this file currently doesn't contain all the code to implement
|
||||
* block jumping. Some of it is currently implemented in markup.js.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'jquery'
|
||||
], function (
|
||||
Aloha,
|
||||
$
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var zeroWidthNode = null;
|
||||
|
||||
/**
|
||||
* Replaces the text in given text with the given text.
|
||||
*
|
||||
* @param node
|
||||
* A text node attached to the DOM.
|
||||
* @param text
|
||||
* A string that is to replace the text of the given text node.
|
||||
*/
|
||||
function replaceMergeTextNode(node, text) {
|
||||
node.deleteData(0, node.length);
|
||||
if ('' !== text) {
|
||||
if (node.nextSibling && 3 === node.nextSibling.nodeType) {
|
||||
node.nextSibling.insertData(0, text);
|
||||
} else if (node.previousSibling && 3 === node.previousSibling.nodeType) {
|
||||
node.previousSibling.insertData(node.previousSibling.length, text);
|
||||
} else {
|
||||
node.insertData(0, text);
|
||||
}
|
||||
}
|
||||
// We don't remove the node immediately to avoid intefering with a
|
||||
// caller's range object that may have a start or end containers
|
||||
// equal to this node. Removing it in a timeout may still interfere
|
||||
// with the selection, but that was not a problem during testing.
|
||||
setTimeout(function () {
|
||||
if (0 === node.length) {
|
||||
$(node).remove();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a previously inserted zero width text node.
|
||||
* See insertZeroWidthTextNodeFix().
|
||||
*/
|
||||
function removeZeroWidthTextNodeFix() {
|
||||
if (!zeroWidthNode) {
|
||||
return;
|
||||
}
|
||||
// We want to only replace a single zero-width character to avoid
|
||||
// interfering with the other zero-width whitespace hack that makes
|
||||
// empty lines visible in IE7.
|
||||
var text = zeroWidthNode.nodeValue.replace(/\u200b/, '');
|
||||
if (text === zeroWidthNode.nodeValue) {
|
||||
console.warn('Expected to remove the zero width text node fix, but couldn\'t find it');
|
||||
}
|
||||
replaceMergeTextNode(zeroWidthNode, text);
|
||||
zeroWidthNode = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a zero width text node before or after a block.
|
||||
*
|
||||
* There is a problem where some browsers can't select the boundary
|
||||
* between some contenteditable content and non-contenteditable
|
||||
* content. For example, if in the example at the top of the file
|
||||
* the selection were one step to the right "...</span>s[]ome..."
|
||||
* and the left cursor key were pressed, then the selection would
|
||||
* just disappear or be stuck between the span and the text node.
|
||||
*
|
||||
* To work around this problem a zero width text node is inserted
|
||||
* before or after a block.
|
||||
*
|
||||
* The inserted zero width text node will be removed automatically
|
||||
* when it isn't necessary any more (on selection change or on
|
||||
* editable.getContents()).
|
||||
*
|
||||
* TODO: In retrospect, a better alternative may be to simply wrap
|
||||
* every inlin-block with an editable span.
|
||||
* @param block
|
||||
* The DOM element for a block before or after which the zero
|
||||
* width text node will be inserted.
|
||||
* @param isGoingLeft
|
||||
* True if the zero width text node is to be inserted after
|
||||
* the block element, or false if the zero width text node is
|
||||
* to be inserted before the block element.
|
||||
* @return
|
||||
* The text node that was inserted.
|
||||
*/
|
||||
function insertZeroWidthTextNodeFix(block, isGoingLeft) {
|
||||
removeZeroWidthTextNodeFix();
|
||||
zeroWidthNode = document.createTextNode("\u200b");
|
||||
if (isGoingLeft) {
|
||||
$(block).after(zeroWidthNode);
|
||||
} else {
|
||||
$(block).before(zeroWidthNode);
|
||||
}
|
||||
Aloha.bind('aloha-selection-changed', function (event) {
|
||||
removeZeroWidthTextNodeFix();
|
||||
Aloha.unbind(event);
|
||||
});
|
||||
return zeroWidthNode;
|
||||
}
|
||||
|
||||
return {
|
||||
removeZeroWidthTextNodeFix: removeZeroWidthTextNodeFix,
|
||||
insertZeroWidthTextNodeFix: insertZeroWidthTextNodeFix
|
||||
};
|
||||
});
|
283
media/aloha-0.22.7/lib/aloha/command.js
Normal file
@@ -0,0 +1,283 @@
|
||||
/* command.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'aloha/registry',
|
||||
'aloha/engine',
|
||||
'util/dom',
|
||||
'aloha/contenthandlermanager'
|
||||
], function (
|
||||
Aloha,
|
||||
Registry,
|
||||
Engine,
|
||||
Dom,
|
||||
ContentHandlerManager
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
// Action: What the command does when executed via execCommand(). Every command defined
|
||||
// in CommandManager specification has an action defined for it in the relevant section. For example,
|
||||
// the bold command's action generally makes the current selection bold, or removes bold if
|
||||
// the selection is already bold. An editing toolbar might provide buttons that execute the
|
||||
// action for a command if clicked, or a script might run an action without user interaction
|
||||
// to achieve some particular effect.
|
||||
//
|
||||
// Indeterminate: A boolean value returned by queryCommandIndeterm(), depending on the
|
||||
// current state of the document. Generally, a command that has a state defined will be
|
||||
// indeterminate if the state is true for part but not all of the current selection, and a
|
||||
// command that has a value defined will be indeterminate if different parts of the
|
||||
// selection have different values. An editing toolbar might display a button or control
|
||||
// in a special way if the command is indeterminate, like showing a "bold" button as
|
||||
// partially depressed, or leaving a font size selector blank instead of showing the font
|
||||
// size of the current selection. As a rule, a command can only be indeterminate if its
|
||||
// state is false, supposing it has a state.
|
||||
//
|
||||
// State: A boolean value returned by queryCommandState(), depending on the current state
|
||||
// of the document. The state of a command is true if it is already in effect, in some
|
||||
// sense specific to the command. Most commands that have a state defined will take opposite
|
||||
// actions depending on whether the state is true or false, such as making the selection
|
||||
// bold if the state is false and removing bold if the state is true. Others will just
|
||||
// have no effect if the state is true, like the justifyCenter command. Still others will
|
||||
// have the same effect regardless, like the styleWithCss command. An editing toolbar might
|
||||
// display a button or control differently depending on the state and indeterminacy of the
|
||||
// command.
|
||||
//
|
||||
// Value: A string returned by queryCommandValue(), depending on the current state of the
|
||||
// document. A command usually has a value instead of a state if the property it modifies
|
||||
// can take more than two different values, like the foreColor command. If the command is
|
||||
// indeterminate, its value is generally based on the start of the selection. Otherwise,
|
||||
// in most cases the value holds true for the entire selection, but see the justifyCenter
|
||||
// command and its three companions for an exception. An editing toolbar might display the
|
||||
// value of a command as selected in a drop-down or filled in in a text box, if the command
|
||||
// isn't indeterminate.
|
||||
//
|
||||
// Relevant CSS property: CommandManager is defined for certain inline formatting commands, and
|
||||
// is used in algorithms specific to those commands. It is an implementation detail, and
|
||||
// is not exposed to authors. If a command does not have a relevant CSS property
|
||||
// specified, it defaults to null.
|
||||
|
||||
var CommandManager = {
|
||||
|
||||
execCommand: function (commandId, showUi, value, range) {
|
||||
var evtObj = {
|
||||
commandId: commandId,
|
||||
preventDefault: false
|
||||
};
|
||||
Aloha.trigger('aloha-command-will-execute', evtObj);
|
||||
|
||||
if (evtObj.preventDefault === true) {
|
||||
return;
|
||||
}
|
||||
// Read current selection if not passed
|
||||
if (!range) {
|
||||
if (!Aloha.getSelection().getRangeCount()) {
|
||||
return;
|
||||
}
|
||||
range = Aloha.getSelection().getRangeAt(0);
|
||||
}
|
||||
|
||||
// For the insertHTML command we provide contenthandler API
|
||||
if (commandId.toLowerCase() === 'inserthtml') {
|
||||
//if (typeof Aloha.settings.contentHandler.insertHtml === 'undefined') {
|
||||
// use all registered content handler; used for copy & paste atm (or write log message)
|
||||
// Aloha.settings.contentHandler.insertHtml = Aloha.defaults.contentHandler.insertHtml;
|
||||
//}
|
||||
value = ContentHandlerManager.handleContent(value, {
|
||||
contenthandler: Aloha.settings.contentHandler.insertHtml,
|
||||
command: 'insertHtml'
|
||||
});
|
||||
}
|
||||
|
||||
Engine.execCommand(commandId, showUi, value, range);
|
||||
|
||||
if (Aloha.getSelection().getRangeCount()) {
|
||||
// Read range after engine modification
|
||||
range = Aloha.getSelection().getRangeAt(0);
|
||||
|
||||
// FIX: doCleanup should work with W3C range
|
||||
var startnode = range.commonAncestorContainer;
|
||||
if (startnode.parentNode) {
|
||||
startnode = startnode.parentNode;
|
||||
}
|
||||
var rangeObject = new window.GENTICS.Utils.RangeObject();
|
||||
rangeObject.startContainer = range.startContainer;
|
||||
rangeObject.startOffset = range.startOffset;
|
||||
rangeObject.endContainer = range.endContainer;
|
||||
rangeObject.endOffset = range.endOffset;
|
||||
Dom.doCleanup({
|
||||
merge: true,
|
||||
removeempty: false
|
||||
}, rangeObject, startnode);
|
||||
rangeObject.select();
|
||||
}
|
||||
|
||||
Aloha.trigger('aloha-command-executed', commandId);
|
||||
},
|
||||
|
||||
// If command is available and not disabled or the active range is not null
|
||||
// the command is enabled
|
||||
queryCommandEnabled: function (commandId, range) {
|
||||
|
||||
// Take current selection if not passed
|
||||
if (!range) {
|
||||
if (!Aloha.getSelection().getRangeCount()) {
|
||||
return;
|
||||
}
|
||||
range = Aloha.getSelection().getRangeAt(0);
|
||||
}
|
||||
return Engine.queryCommandEnabled(commandId, range);
|
||||
},
|
||||
|
||||
// "Return true if command is indeterminate, otherwise false."
|
||||
queryCommandIndeterm: function (commandId, range) {
|
||||
|
||||
// Take current selection if not passed
|
||||
if (!range) {
|
||||
if (!Aloha.getSelection().getRangeCount()) {
|
||||
return;
|
||||
}
|
||||
range = Aloha.getSelection().getRangeAt(0);
|
||||
}
|
||||
return Engine.queryCommandIndeterm(commandId, range);
|
||||
|
||||
},
|
||||
|
||||
queryCommandState: function (commandId, range) {
|
||||
|
||||
// Take current selection if not passed
|
||||
if (!range) {
|
||||
if (!Aloha.getSelection().getRangeCount()) {
|
||||
return;
|
||||
}
|
||||
range = Aloha.getSelection().getRangeAt(0);
|
||||
}
|
||||
return Engine.queryCommandState(commandId, range);
|
||||
|
||||
},
|
||||
|
||||
// "When the queryCommandSupported(command) method on the HTMLDocument
|
||||
// interface is invoked, the user agent must return true if command is
|
||||
// supported, and false otherwise."
|
||||
queryCommandSupported: function (commandId) {
|
||||
|
||||
return Engine.queryCommandSupported(commandId);
|
||||
},
|
||||
|
||||
queryCommandValue: function (commandId, range) {
|
||||
|
||||
// Take current selection if not passed
|
||||
if (!range) {
|
||||
if (!Aloha.getSelection().getRangeCount()) {
|
||||
return;
|
||||
}
|
||||
range = Aloha.getSelection().getRangeAt(0);
|
||||
}
|
||||
|
||||
// "Return command's value."
|
||||
return Engine.queryCommandValue(commandId, range);
|
||||
},
|
||||
querySupportedCommands: function () {
|
||||
|
||||
var commands = [],
|
||||
command;
|
||||
|
||||
for (command in Engine.commands) {
|
||||
if (Engine.commands.hasOwnProperty(command)) {
|
||||
commands.push(command);
|
||||
}
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
};
|
||||
|
||||
// create an instance
|
||||
CommandManager = new (Registry.extend(CommandManager))();
|
||||
|
||||
/**
|
||||
* Executes a registered command.
|
||||
* http://aryeh.name/spec/editing/editing.html#methods-of-the-htmldocument-interface
|
||||
* @method
|
||||
* @param command name of the command
|
||||
* @param showUI has no effect for Aloha Editor and is only here because in spec...
|
||||
* @param value depends on the used command and it impementation
|
||||
* @range optional a range on which the command will be executed if not specified
|
||||
* the current selection will be used as range
|
||||
*/
|
||||
Aloha.execCommand = CommandManager.execCommand;
|
||||
|
||||
/**
|
||||
* Check wheater the command in enabled.
|
||||
* If command is not supported, raise a NOT_SUPPORTED_ERR exception.
|
||||
* @param command name of the command
|
||||
* @return true if command is enabled, false otherwise.
|
||||
*/
|
||||
Aloha.queryCommandEnabled = CommandManager.queryCommandEnabled;
|
||||
|
||||
/**
|
||||
* Check if the command has an indetermed state.
|
||||
* If command is not supported, a NOT_SUPPORTED_ERR exception is thrown
|
||||
* If command has no indeterminacy, INVALID_ACCESS_ERR exception is thrown
|
||||
* If command is not enabled, return false.
|
||||
* @param command name of the command
|
||||
* @range optional a range on which the command will be executed if not specified
|
||||
* the current selection will be used as range
|
||||
* @return true if command is indeterminate, otherwise false.
|
||||
*/
|
||||
Aloha.queryCommandIndeterm = CommandManager.queryCommandIndeterm;
|
||||
|
||||
/**
|
||||
* Returns the state of a given command
|
||||
* If command is not supported, a NOT_SUPPORTED_ERR exception is thrown
|
||||
* If command has no state, an INVALID_ACCESS_ERR exception is thrown
|
||||
* If command is not enabled, return false
|
||||
* If the state override for command is set, it returns the state
|
||||
* @param command name of the command
|
||||
* @return state override or true if command's state is true, otherwise false.
|
||||
*/
|
||||
Aloha.queryCommandState = CommandManager.queryCommandState;
|
||||
|
||||
/**
|
||||
* Check if a given command is supported
|
||||
* @return true if command is supported, and false otherwise.
|
||||
*/
|
||||
Aloha.queryCommandSupported = CommandManager.queryCommandSupported;
|
||||
|
||||
/**
|
||||
* Returns the Value of a given Command
|
||||
* If command is not supported, a NOT_SUPPORTED_ERR exception is thrown
|
||||
* If command is not enabled, returns an empty string
|
||||
* If command is "fontSize" and its value override is set, an integer
|
||||
* number of pixels is returned as font size for the result.
|
||||
* If the value override for command is set, it returns that.
|
||||
* @return command's value.
|
||||
*/
|
||||
Aloha.queryCommandValue = CommandManager.queryCommandValue;
|
||||
|
||||
Aloha.querySupportedCommands = CommandManager.querySupportedCommands;
|
||||
|
||||
return CommandManager;
|
||||
});
|
347
media/aloha-0.22.7/lib/aloha/console.js
Executable file
@@ -0,0 +1,347 @@
|
||||
/* console.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'util/class',
|
||||
'jquery'
|
||||
], function (
|
||||
Aloha,
|
||||
Class,
|
||||
jQuery
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* This is the aloha Log
|
||||
* @namespace Aloha
|
||||
* @class Log
|
||||
* @singleton
|
||||
*/
|
||||
var AlohaConsole = Class.extend({
|
||||
/**
|
||||
* Initialize the logging
|
||||
* @hide
|
||||
*/
|
||||
init: function () {
|
||||
|
||||
// initialize the logging settings (if not present)
|
||||
if (typeof Aloha.settings.logLevels === 'undefined' || !Aloha.settings.logLevels) {
|
||||
Aloha.settings.logLevels = {
|
||||
'error': true,
|
||||
'warn': true
|
||||
};
|
||||
}
|
||||
|
||||
// initialize the logHistory settings (if not present)
|
||||
if (typeof Aloha.settings.logHistory === 'undefined' || !Aloha.settings.logHistory) {
|
||||
Aloha.settings.logHistory = {};
|
||||
}
|
||||
// set the default values for the loghistory
|
||||
if (!Aloha.settings.logHistory.maxEntries) {
|
||||
Aloha.settings.logHistory.maxEntries = 100;
|
||||
}
|
||||
if (!Aloha.settings.logHistory.highWaterMark) {
|
||||
Aloha.settings.logHistory.highWaterMark = 90;
|
||||
}
|
||||
if (!Aloha.settings.logHistory.levels) {
|
||||
Aloha.settings.logHistory.levels = {
|
||||
'error': true,
|
||||
'warn': true
|
||||
};
|
||||
}
|
||||
this.flushLogHistory();
|
||||
|
||||
Aloha.trigger('aloha-logger-ready');
|
||||
},
|
||||
|
||||
/**
|
||||
* Log History as array of Message Objects. Every object has the properties
|
||||
* 'level', 'component' and 'message'
|
||||
* @property
|
||||
* @type Array
|
||||
* @hide
|
||||
*/
|
||||
logHistory: [],
|
||||
|
||||
/**
|
||||
* Flag, which is set as soon as the highWaterMark for the log history is reached.
|
||||
* This flag is reset on every call of flushLogHistory()
|
||||
* @hide
|
||||
*/
|
||||
highWaterMarkReached: false,
|
||||
|
||||
/**
|
||||
* Logs a message to the console
|
||||
* @method
|
||||
* @param {String} level Level of the log ('error', 'warn' or 'info', 'debug')
|
||||
* @param {String} component Component that calls the log
|
||||
* @param {String} message log message
|
||||
*/
|
||||
log: function (level, component, message) {
|
||||
|
||||
|
||||
// log ('Logging message');
|
||||
if (typeof component === 'undefined') {
|
||||
message = level;
|
||||
}
|
||||
if (typeof component !== 'string' && component && component.toString) {
|
||||
component = component.toString();
|
||||
}
|
||||
|
||||
// log ('warn', 'Warning message');
|
||||
if (typeof message === 'undefined') {
|
||||
message = component;
|
||||
component = undefined;
|
||||
}
|
||||
|
||||
if (typeof level === 'undefined' || !level) {
|
||||
level = 'log';
|
||||
}
|
||||
|
||||
level = level.toLowerCase();
|
||||
|
||||
if (typeof Aloha.settings.logLevels === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
// now check whether the log level is activated
|
||||
if (!Aloha.settings.logLevels[level]) {
|
||||
return;
|
||||
}
|
||||
|
||||
component = component || "Unkown Aloha Component";
|
||||
|
||||
this.addToLogHistory({
|
||||
'level': level,
|
||||
'component': component,
|
||||
'message': message,
|
||||
'date': new Date()
|
||||
});
|
||||
|
||||
var console = window.console;
|
||||
|
||||
switch (level) {
|
||||
case 'error':
|
||||
if (window.console && console.error) {
|
||||
// FIXME:
|
||||
// Using console.error rather than throwing an error is very
|
||||
// problematic because we get not stack.
|
||||
// We ought to consider doing the following:
|
||||
// throw component + ': ' + message;
|
||||
if (!component && !message) {
|
||||
console.error("Error occured without message and component");
|
||||
} else {
|
||||
console.error(component + ': ' + message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'warn':
|
||||
if (window.console && console.warn) {
|
||||
console.warn(component + ': ' + message);
|
||||
}
|
||||
break;
|
||||
case 'info':
|
||||
if (window.console && console.info) {
|
||||
console.info(component + ': ' + message);
|
||||
}
|
||||
break;
|
||||
case 'debug':
|
||||
if (window.console && console.log) {
|
||||
console.log(component + ' [' + level + ']: ' + message);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (window.console && console.log) {
|
||||
console.log(component + ' [' + level + ']: ' + message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a message of log level 'error'
|
||||
* @method
|
||||
* @param {String} component Component that calls the log
|
||||
* @param {String} message log message
|
||||
*/
|
||||
error: function (component, message) {
|
||||
this.log('error', component, message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a message of log level 'warn'
|
||||
* @method
|
||||
* @param {String} component Component that calls the log
|
||||
* @param {String} message log message
|
||||
*/
|
||||
warn: function (component, message) {
|
||||
this.log('warn', component, message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a message of log level 'info'
|
||||
* @method
|
||||
* @param {String} component Component that calls the log
|
||||
* @param {String} message log message
|
||||
*/
|
||||
info: function (component, message) {
|
||||
this.log('info', component, message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a message of log level 'debug'
|
||||
* @param {String} component Component that calls the log
|
||||
* @param {String} message log message
|
||||
*/
|
||||
debug: function (component, message) {
|
||||
this.log('debug', component, message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Methods to mark function as deprecated for developers.
|
||||
* @param {String} component String that calls the log
|
||||
* @param {String} message log message
|
||||
*/
|
||||
deprecated: function (component, message) {
|
||||
this.log('warn', component, message);
|
||||
// help the developer to locate the call.
|
||||
if (Aloha.settings.logLevels.deprecated) {
|
||||
throw new Error(message);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether the given log level is currently enabled
|
||||
* @param {String} level
|
||||
* @return true when log level is enabled, false if not
|
||||
*/
|
||||
isLogLevelEnabled: function (level) {
|
||||
return Aloha.settings && Aloha.settings.logLevels && Aloha.settings.logLevels[level];
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether error logging is enabled
|
||||
* @return true if error logging is enabled, false if not
|
||||
*/
|
||||
isErrorEnabled: function () {
|
||||
return this.isLogLevelEnabled('error');
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether warn logging is enabled
|
||||
* @return true if warn logging is enabled, false if not
|
||||
*/
|
||||
isWarnEnabled: function () {
|
||||
return this.isLogLevelEnabled('warn');
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether info logging is enabled
|
||||
* @return true if info logging is enabled, false if not
|
||||
*/
|
||||
isInfoEnabled: function () {
|
||||
return this.isLogLevelEnabled('info');
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether debug logging is enabled
|
||||
* @return true if debug logging is enabled, false if not
|
||||
*/
|
||||
isDebugEnabled: function () {
|
||||
return this.isLogLevelEnabled('debug');
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the given entry to the log history. Check whether the highWaterMark has been reached, and fire an event if yes.
|
||||
* @param {Object} entry entry to be added to the log history
|
||||
* @hide
|
||||
*/
|
||||
addToLogHistory: function (entry) {
|
||||
|
||||
if (!Aloha.settings.logHistory) {
|
||||
this.init();
|
||||
}
|
||||
|
||||
// when maxEntries is set to something illegal, we do nothing (log history is disabled)
|
||||
// check whether the level is one we like to have logged
|
||||
if (Aloha.settings.logHistory.maxEntries <= 0 || !Aloha.settings.logHistory.levels[entry.level]) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// first add the entry as last element to the history array
|
||||
this.logHistory.push(entry);
|
||||
|
||||
// check whether the highWaterMark was reached, if so, fire an event
|
||||
if (!this.highWaterMarkReached) {
|
||||
|
||||
if (this.logHistory.length >= Aloha.settings.logHistory.maxEntries * Aloha.settings.logHistory.highWaterMark / 100) {
|
||||
|
||||
// fire the event
|
||||
Aloha.trigger('aloha-log-full');
|
||||
// set the flag (so we will not fire the event again until the logHistory is flushed)
|
||||
this.highWaterMarkReached = true;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether the log is full and eventually remove the oldest entries
|
||||
// @todo remove old entries when aloha-log-full event is triggered
|
||||
while (this.logHistory.length > Aloha.settings.logHistory.maxEntries) {
|
||||
this.logHistory.shift();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the log history
|
||||
* @return log history as array of objects
|
||||
* @hide
|
||||
*/
|
||||
getLogHistory: function () {
|
||||
return this.logHistory;
|
||||
},
|
||||
|
||||
/**
|
||||
* Flush the log history. Remove all log entries and reset the flag for the highWaterMark
|
||||
* @return void
|
||||
* @hide
|
||||
*/
|
||||
flushLogHistory: function () {
|
||||
this.logHistory = [];
|
||||
this.highWaterMarkReached = false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Create the Log object
|
||||
* @hide
|
||||
*/
|
||||
AlohaConsole = new AlohaConsole();
|
||||
|
||||
// add to log namespace for compatiblility.
|
||||
Aloha.Log = Aloha.Console = AlohaConsole;
|
||||
return AlohaConsole;
|
||||
});
|
101
media/aloha-0.22.7/lib/aloha/contenthandlermanager.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/* contenthandlermanager.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'aloha/registry',
|
||||
'util/class',
|
||||
'aloha/console'
|
||||
], function (
|
||||
Registry,
|
||||
Class,
|
||||
console
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Create an contentHandler from the given definition. Acts as a factory
|
||||
* method for contentHandler.
|
||||
*
|
||||
* @param {ContentHandlerManager} definition
|
||||
*/
|
||||
var ContentHandlerManager = Registry.extend({
|
||||
|
||||
createHandler: function (definition) {
|
||||
if (typeof definition.handleContent !== 'function') {
|
||||
throw 'ContentHandler has no function handleContent().';
|
||||
}
|
||||
var AbstractContentHandler = Class.extend({
|
||||
handleContent: function (content) {
|
||||
// Implement in subclass!
|
||||
}
|
||||
}, definition);
|
||||
return new AbstractContentHandler();
|
||||
},
|
||||
|
||||
/**
|
||||
* Manipulates the given contents of an editable by invoking content
|
||||
* handlers over the contents.
|
||||
*
|
||||
* @param {string} content The contents of an editable which will be
|
||||
* handled.
|
||||
* @param {object} options Used to filter limit which content handlers
|
||||
* should be used.
|
||||
* @param {Aloha.Editable} The editable whose content is being handled.
|
||||
* @return {string} The handled content.
|
||||
*/
|
||||
handleContent: function (content, options, editable) {
|
||||
var manager = this;
|
||||
|
||||
// Because if no options is specified to indicate which content
|
||||
// handler to use, then all that are available are used.
|
||||
var handlers = options ? options.contenthandler : manager.getIds();
|
||||
|
||||
if (!handlers) {
|
||||
return content;
|
||||
}
|
||||
|
||||
var i;
|
||||
var handler;
|
||||
for (i = 0; i < handlers.length; i++) {
|
||||
handler = manager.get(handlers[i]);
|
||||
if (handler) {
|
||||
content = handler.handleContent(content, options,
|
||||
editable || Aloha.activeEditable);
|
||||
}
|
||||
|
||||
// FIME: Is it ever valid for content to be null? This breaks
|
||||
// the handleContent(string):string contract.
|
||||
if (null === content) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
});
|
||||
|
||||
return new ContentHandlerManager();
|
||||
});
|
108
media/aloha-0.22.7/lib/aloha/copypaste.js
Normal file
@@ -0,0 +1,108 @@
|
||||
/* copypaste.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/**
|
||||
* @overview:
|
||||
* Various utility functions that are useful when working with selections, and
|
||||
* ranges for copy/paste functionality.
|
||||
*/
|
||||
define('aloha/copypaste', [
|
||||
'jquery',
|
||||
'aloha/core'
|
||||
], function (
|
||||
$,
|
||||
Aloha
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Retrieve the editable host in which the given range is contained.
|
||||
*
|
||||
* @param {WrappedRange} range
|
||||
* @return {jQuery.<HTMLElement>|null} The editable host element, null if
|
||||
* non can be determinded from the given
|
||||
* range.
|
||||
*/
|
||||
function getEditableAt(range) {
|
||||
if (!range || !range.commonAncestorContainer) {
|
||||
return null;
|
||||
}
|
||||
var $container = $(range.commonAncestorContainer);
|
||||
return $container.length ? Aloha.getEditableHost($container) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current range.
|
||||
*
|
||||
* @return {WrappedRange|null} Range at current selection or null of non
|
||||
* exists.
|
||||
*/
|
||||
function getRange() {
|
||||
var selection = Aloha.getSelection();
|
||||
return selection.getRangeCount() ? selection.getRangeAt(0) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selection to the given range
|
||||
*
|
||||
* @param {object} range An object that must container the following
|
||||
* essential range properties: ~ startContainer
|
||||
* ~ endContainer
|
||||
* ~ startOffset
|
||||
* ~ endOffset
|
||||
*/
|
||||
function setSelectionAt(range) {
|
||||
var newRange = Aloha.createRange();
|
||||
var selection = Aloha.getSelection();
|
||||
newRange.setStart(range.startContainer, range.startOffset);
|
||||
newRange.setEnd(range.endContainer, range.endOffset);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(newRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a selection that encompasses the contents of the given element.
|
||||
*
|
||||
* @param {HTMLElement} element Editable DOM element.
|
||||
*/
|
||||
function selectAllOf(element) {
|
||||
setSelectionAt({
|
||||
startContainer: element,
|
||||
endContainer: element,
|
||||
startOffset: 0,
|
||||
endOffset: element.childNodes ? element.childNodes.length
|
||||
: element.length
|
||||
});
|
||||
$(element).focus();
|
||||
}
|
||||
|
||||
return {
|
||||
getEditableAt: getEditableAt,
|
||||
getRange: getRange,
|
||||
selectAllOf: selectAllOf,
|
||||
setSelectionAt: setSelectionAt
|
||||
};
|
||||
});
|
615
media/aloha-0.22.7/lib/aloha/core.js
Executable file
@@ -0,0 +1,615 @@
|
||||
/*core.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'aloha/pluginmanager'
|
||||
], function (
|
||||
$,
|
||||
PluginManager
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var Aloha = window.Aloha;
|
||||
|
||||
/**
|
||||
* Checks whether the current user agent is supported.
|
||||
*
|
||||
* @return {boolean} True if Aloha supports the current browser.
|
||||
*/
|
||||
function isBrowserSupported() {
|
||||
var browser = $.browser;
|
||||
var version = browser.version;
|
||||
return !(
|
||||
// Chrome/Safari 4
|
||||
(browser.webkit && parseFloat(version) < 532.5) ||
|
||||
// FF 3.5
|
||||
(browser.mozilla && parseFloat(version) < 1.9) ||
|
||||
// IE 7
|
||||
(browser.msie && version < 7) ||
|
||||
// Right now Opera needs some work
|
||||
(browser.opera && version < 11)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given jQuery event originates from an Aloha dialog
|
||||
* element.
|
||||
*
|
||||
* This is used to facilitate a hackish way of preventing blurring
|
||||
* editables when interacting with Aloha UI modals.
|
||||
*
|
||||
* @param {jQuery<Event>} $event
|
||||
* @return {boolean} True if $event is initiated from within an Aloha
|
||||
* dialog element.
|
||||
*/
|
||||
function originatesFromDialog($event) {
|
||||
var $target = $($event.target);
|
||||
return $target.is('.aloha-dialog') ||
|
||||
0 < $target.closest('.aloha-dialog').length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers events on the documents to cause editables to be blurred when
|
||||
* clicking outside of editables.
|
||||
*
|
||||
* Hack: Except when the click originates from a modal dialog.
|
||||
*/
|
||||
function registerEvents() {
|
||||
$('html').mousedown(function ($event) {
|
||||
if (Aloha.activeEditable && !Aloha.eventHandled
|
||||
&& !originatesFromDialog($event)) {
|
||||
Aloha.deactivateEditable();
|
||||
}
|
||||
}).mouseup(function () {
|
||||
Aloha.eventHandled = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Aloha.
|
||||
*
|
||||
* @param {function} next Function to call after initialization.
|
||||
*/
|
||||
function initAloha(event, next) {
|
||||
if (!isBrowserSupported()) {
|
||||
var console = window.console;
|
||||
if (console) {
|
||||
var fn = console.error ? 'error' : console.log ? 'log' : null;
|
||||
if (fn) {
|
||||
console[fn]('This browser is not supported');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Because different css is to be applied based on what the user-agent
|
||||
// supports. For example: outlines do not render in IE7.
|
||||
if ($.browser.webkit) {
|
||||
$('html').addClass('aloha-webkit');
|
||||
} else if ($.browser.opera) {
|
||||
$('html').addClass('aloha-opera');
|
||||
} else if ($.browser.msie) {
|
||||
$('html').addClass('aloha-ie' + parseInt($.browser.version, 10));
|
||||
} else if ($.browser.mozilla) {
|
||||
$('html').addClass('aloha-mozilla');
|
||||
}
|
||||
|
||||
if (navigator.appVersion.indexOf('Win') !== -1) {
|
||||
Aloha.OSName = 'Win';
|
||||
} else if (navigator.appVersion.indexOf('Mac') !== -1) {
|
||||
Aloha.OSName = 'Mac';
|
||||
} else if (navigator.appVersion.indexOf('X11') !== -1) {
|
||||
Aloha.OSName = 'Unix';
|
||||
} else if (navigator.appVersion.indexOf('Linux') !== -1) {
|
||||
Aloha.OSName = 'Linux';
|
||||
}
|
||||
|
||||
registerEvents();
|
||||
Aloha.settings.base = Aloha.getAlohaUrl();
|
||||
Aloha.Log.init();
|
||||
|
||||
// Initialize error handler for general javascript errors.
|
||||
if (Aloha.settings.errorhandling) {
|
||||
window.onerror = function (msg, url, line) {
|
||||
Aloha.Log.error(Aloha, 'Error message: ' + msg + '\nURL: ' +
|
||||
url + '\nLine Number: ' + line);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
event();
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize managers
|
||||
*/
|
||||
function initRepositoryManager(event, next) {
|
||||
Aloha.RepositoryManager.init();
|
||||
event();
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Aloha plugins.
|
||||
*
|
||||
* @param {function} onPluginsInitialized Callback that will be invoked
|
||||
* after all plugins have been
|
||||
* initialized. Whereas plugins are
|
||||
* loaded synchronously, plugins may
|
||||
* initialize asynchronously.
|
||||
*/
|
||||
function initPluginManager(event, next) {
|
||||
// Because if there are no loadedPlugins specified, then the default is
|
||||
// to initialized all available plugins.
|
||||
if (0 === Aloha.loadedPlugins.length) {
|
||||
var plugins = PluginManager.plugins;
|
||||
var plugin;
|
||||
for (plugin in plugins) {
|
||||
if (plugins.hasOwnProperty(plugin)) {
|
||||
Aloha.loadedPlugins.push(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fired = false;
|
||||
|
||||
PluginManager.init(function () {
|
||||
if (!fired) {
|
||||
event();
|
||||
fired = true;
|
||||
}
|
||||
next();
|
||||
}, Aloha.loadedPlugins);
|
||||
|
||||
if (!fired) {
|
||||
event();
|
||||
fired = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin initialize editables.
|
||||
*/
|
||||
function initEditables(event, next) {
|
||||
var i;
|
||||
for (i = 0; i < Aloha.editables.length; i++) {
|
||||
if (!Aloha.editables[i].ready) {
|
||||
Aloha.editables[i].init();
|
||||
}
|
||||
}
|
||||
event();
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization phases.
|
||||
*
|
||||
* These stages denote the initialization states which Aloha will go
|
||||
* through from loading to ready.
|
||||
*
|
||||
* Each phase object contains the following properties:
|
||||
* fn : The process that is to be invoked during this phase.
|
||||
* Will take two functions: event() and next().
|
||||
* event : The event name, which if provided, will be fired after the
|
||||
* phase has been started (optional).
|
||||
* deferred : A $.Deferred() object to hold event handlers until that
|
||||
* initialization phase has been done (optional).
|
||||
*
|
||||
* @type {Array.<phase>}
|
||||
*/
|
||||
var phases = [
|
||||
// Phase 0: Waiting for initialization to begin. This is the state at
|
||||
// load-time.
|
||||
{
|
||||
fn: null,
|
||||
event: null,
|
||||
deferred: null
|
||||
},
|
||||
|
||||
// Phase 1: DOM is ready; performing compatibility checks, registering
|
||||
// basic events, and initializing logging.
|
||||
{
|
||||
fn: initAloha,
|
||||
event: null,
|
||||
deferred: null
|
||||
},
|
||||
|
||||
// Phase 2: Initial checks have passed; Initializing repository manger.
|
||||
{
|
||||
fn: initRepositoryManager,
|
||||
event: null,
|
||||
deferred: null
|
||||
},
|
||||
|
||||
// Phase 3: Repository manager is ready for use; commence
|
||||
// initialization of configured or default plugins.
|
||||
{
|
||||
fn: initPluginManager,
|
||||
event: 'aloha-plugins-loaded',
|
||||
deferred: null
|
||||
},
|
||||
|
||||
// Phase 4: Plugins have all begun their initialization process, but it
|
||||
// is not necessary that they have completed. Start
|
||||
// initializing editable, along with their scaffolding UI.
|
||||
// Editables will not be fully initialized however, until
|
||||
// plugins have finished initialization.
|
||||
{
|
||||
fn: initEditables,
|
||||
event: null,
|
||||
deferred: null
|
||||
},
|
||||
|
||||
// Phase 5: The "ready" state. Notify the system that Aloha is fully
|
||||
// loaded, and ready for use.
|
||||
{
|
||||
fn: null,
|
||||
event: 'aloha-ready',
|
||||
deferred: null
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Base Aloha Object
|
||||
* @namespace Aloha
|
||||
* @class Aloha The Aloha base object, which contains all the core functionality
|
||||
* @singleton
|
||||
*/
|
||||
$.extend(true, Aloha, {
|
||||
|
||||
/**
|
||||
* The Aloha Editor Version we are using
|
||||
* It should be set by us and updated for the particular branch
|
||||
* @property
|
||||
*/
|
||||
version: '${version}',
|
||||
|
||||
/**
|
||||
* Array of editables that are managed by Aloha
|
||||
* @property
|
||||
* @type Array
|
||||
*/
|
||||
editables: [],
|
||||
|
||||
/**
|
||||
* The currently active editable is referenced here
|
||||
* @property
|
||||
* @type Aloha.Editable
|
||||
*/
|
||||
activeEditable: null,
|
||||
|
||||
/**
|
||||
* settings object, which will contain all Aloha settings
|
||||
* @cfg {Object} object Aloha's settings
|
||||
*/
|
||||
settings: {},
|
||||
|
||||
/**
|
||||
* defaults object, which will contain all Aloha defaults
|
||||
* @cfg {Object} object Aloha's settings
|
||||
*/
|
||||
defaults: {},
|
||||
|
||||
/**
|
||||
* Namespace for ui components
|
||||
*/
|
||||
ui: {},
|
||||
|
||||
/**
|
||||
* This represents the name of the users OS. Could be:
|
||||
* 'Mac', 'Linux', 'Win', 'Unix', 'Unknown'
|
||||
* @property
|
||||
* @type string
|
||||
*/
|
||||
OSName: 'Unknown',
|
||||
|
||||
/**
|
||||
* A list of loaded plugin names, available after the STAGES.PLUGINS
|
||||
* initialization phase.
|
||||
*
|
||||
* @type {Array.<string>}
|
||||
* @internal
|
||||
*/
|
||||
loadedPlugins: [],
|
||||
|
||||
/**
|
||||
* Maps names of plugins (link) to the base URL (../plugins/common/link).
|
||||
*/
|
||||
_pluginBaseUrlByName: {},
|
||||
|
||||
/**
|
||||
* Start the initialization process.
|
||||
*/
|
||||
init: function () {
|
||||
Aloha.initialize(phases);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns list of loaded plugins (without Bundle name)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
getLoadedPlugins: function () {
|
||||
return this.loadedPlugins;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if a certain plugin is loaded, false otherwise.
|
||||
*
|
||||
* @param {string} plugin Name of plugin
|
||||
* @return {boolean} True if plugin with given name is load.
|
||||
*/
|
||||
isPluginLoaded: function (name) {
|
||||
var loaded = false;
|
||||
$.each(this.loadedPlugins, function (i, plugin) {
|
||||
if (name === plugin.toString()) {
|
||||
loaded = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return loaded;
|
||||
},
|
||||
|
||||
/**
|
||||
* Activates editable and deactivates all other Editables.
|
||||
*
|
||||
* @param {Editable} editable the Editable to be activated
|
||||
*/
|
||||
activateEditable: function (editable) {
|
||||
// Because editables may be removed on blur, Aloha.editables.length
|
||||
// is not cached.
|
||||
var editables = Aloha.editables;
|
||||
var i;
|
||||
for (i = 0; i < editables.length; i++) {
|
||||
if (editables[i] !== editable && editables[i].isActive) {
|
||||
editables[i].blur();
|
||||
}
|
||||
}
|
||||
Aloha.activeEditable = editable;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current Editable
|
||||
* @return {Editable} returns the active Editable
|
||||
*/
|
||||
getActiveEditable: function () {
|
||||
return Aloha.activeEditable;
|
||||
},
|
||||
|
||||
/**
|
||||
* Deactivates the active Editable.
|
||||
*
|
||||
* TODO: Would be better named "deactivateActiveEditable".
|
||||
*/
|
||||
deactivateEditable: function () {
|
||||
if (Aloha.activeEditable) {
|
||||
Aloha.activeEditable.blur();
|
||||
Aloha.activeEditable = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets an editable by an ID or null if no Editable with that ID
|
||||
* registered.
|
||||
*
|
||||
* @param {string} id The element id to look for.
|
||||
* @return {Aloha.Editable|null} An editable, or null if none if found
|
||||
* for the given id.
|
||||
*/
|
||||
getEditableById: function (id) {
|
||||
// Because if the element is a textarea, then it's necessary to
|
||||
// route to the editable div.
|
||||
var $editable = $('#' + id);
|
||||
if ($editable.length
|
||||
&& 'textarea' === $editable[0].nodeName.toLowerCase()) {
|
||||
id = id + '-aloha';
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < Aloha.editables.length; i++) {
|
||||
if (Aloha.editables[i].getId() === id) {
|
||||
return Aloha.editables[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether an object is a registered Aloha Editable.
|
||||
* @param {jQuery} obj the jQuery object to be checked.
|
||||
* @return {boolean}
|
||||
*/
|
||||
isEditable: function (obj) {
|
||||
var i, editablesLength;
|
||||
|
||||
for (i = 0, editablesLength = Aloha.editables.length; i < editablesLength; i++) {
|
||||
if (Aloha.editables[i].originalObj.get(0) === obj) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the nearest editable parent of the DOM element contained in the
|
||||
* given jQuery object.
|
||||
*
|
||||
* @param {jQuery} $element jQuery unit set containing DOM element.
|
||||
* @return {Aloha.Editable} Editable, or null if none found.
|
||||
*/
|
||||
getEditableHost: (function () {
|
||||
var getEditableOf = function (editable) {
|
||||
var i;
|
||||
for (i = 0; i < Aloha.editables.length; i++) {
|
||||
if (Aloha.editables[i].originalObj[0] === editable) {
|
||||
return Aloha.editables[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return function ($element) {
|
||||
if (!$element || 0 === $element.length) {
|
||||
return null;
|
||||
}
|
||||
var editable = getEditableOf($element[0]);
|
||||
if (!editable) {
|
||||
$element.parents().each(function (__unused__, node) {
|
||||
editable = getEditableOf(node);
|
||||
if (editable) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return editable;
|
||||
};
|
||||
}()),
|
||||
|
||||
/**
|
||||
* Logs a message to the console.
|
||||
*
|
||||
* @param {string} level Level of the log
|
||||
* ("error", "warn" or "info", "debug").
|
||||
* @param {object} component Component that calls the log.
|
||||
* @param {string} message Log message.
|
||||
* @hide
|
||||
*/
|
||||
log: function (level, component, message) {
|
||||
if (typeof Aloha.Log !== 'undefined') {
|
||||
Aloha.Log.log(level, component, message);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Register the given editable.
|
||||
*
|
||||
* @param {Editable} editable to register.
|
||||
* @hide
|
||||
*/
|
||||
registerEditable: function (editable) {
|
||||
Aloha.editables.push(editable);
|
||||
},
|
||||
|
||||
/**
|
||||
* Unregister the given editable. It will be deactivated and removed
|
||||
* from editables.
|
||||
*
|
||||
* @param {Editable} editable The editable to unregister.
|
||||
* @hide
|
||||
*/
|
||||
unregisterEditable: function (editable) {
|
||||
var index = $.inArray(editable, Aloha.editables);
|
||||
if (index !== -1) {
|
||||
Aloha.editables.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether at least one editable was modified.
|
||||
*
|
||||
* @return {boolean} True when at least one editable was modified,
|
||||
* false otherwise.
|
||||
*/
|
||||
isModified: function () {
|
||||
var i;
|
||||
for (i = 0; i < Aloha.editables.length; i++) {
|
||||
if (Aloha.editables[i].isModified
|
||||
&& Aloha.editables[i].isModified()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines the Aloha Url.
|
||||
*
|
||||
* @return {String} Aloha's baseUrl setting or "" if not set.
|
||||
*/
|
||||
getAlohaUrl: function (suffix) {
|
||||
return Aloha.settings.baseUrl || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the plugin's url.
|
||||
*
|
||||
* @param {string} name The name with which the plugin was registered
|
||||
* with.
|
||||
* @return {string} The fully qualified url of this plugin.
|
||||
*/
|
||||
getPluginUrl: function (name) {
|
||||
if (name) {
|
||||
return null;
|
||||
}
|
||||
var url = Aloha.settings._pluginBaseUrlByName[name];
|
||||
if (url) {
|
||||
// Check if url is absolute and attach base url if it is not.
|
||||
if (!url.match("^(\/|http[s]?:).*")) {
|
||||
url = Aloha.getAlohaUrl() + '/' + url;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable object resizing by executing command 'enableObjectResizing',
|
||||
* if the browser supports this.
|
||||
*/
|
||||
disableObjectResizing: function () {
|
||||
try {
|
||||
// This will disable browsers image resizing facilities in
|
||||
// order disable resize handles.
|
||||
var supported;
|
||||
try {
|
||||
supported = document.queryCommandSupported('enableObjectResizing');
|
||||
} catch (e) {
|
||||
supported = false;
|
||||
Aloha.Log.log('enableObjectResizing is not supported.');
|
||||
}
|
||||
if (supported) {
|
||||
document.execCommand('enableObjectResizing', false, false);
|
||||
Aloha.Log.log('enableObjectResizing disabled.');
|
||||
}
|
||||
} catch (e2) {
|
||||
Aloha.Log.error(e2, 'Could not disable enableObjectResizing');
|
||||
// this is just for others, who will not support disabling enableObjectResizing
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Human-readable string representation of this.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
toString: function () {
|
||||
return 'Aloha';
|
||||
}
|
||||
});
|
||||
|
||||
return Aloha;
|
||||
});
|
326
media/aloha-0.22.7/lib/aloha/ecma5shims.js
Normal file
@@ -0,0 +1,326 @@
|
||||
/**
|
||||
* ecma5schims.js - Shim for ECMA5 compatibility
|
||||
* (http://en.wikipedia.org/wiki/Shim_%28computing%29)
|
||||
*
|
||||
* A shim library that implements common functions that are missing on some
|
||||
* environments in order to complete ECMA5 compatibility across all major
|
||||
* browsers.
|
||||
*
|
||||
* TODO: This code needs to be refactored so as to conform to Aloha coding
|
||||
* standards. It is also severly lacking in documentation. Please take
|
||||
* note of: https://github.com/alohaeditor/Aloha-Editor/wiki/Commit-Checklist .
|
||||
*/
|
||||
|
||||
define([], function () {
|
||||
'use strict';
|
||||
var $_;
|
||||
|
||||
var shims = {
|
||||
// Function bind
|
||||
bind: function (owner) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Function.prototype.bind;
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
if (native_method) {
|
||||
return native_method.apply(obj, arguments);
|
||||
}
|
||||
return function () {
|
||||
return obj.apply(owner, arguments.length === 0 ? args : args.concat(Array.prototype.slice.call(arguments)));
|
||||
};
|
||||
},
|
||||
|
||||
// String trim
|
||||
trim: function () {
|
||||
var obj = this.obj || this;
|
||||
var native_method = String.prototype.trim;
|
||||
|
||||
if (native_method) {
|
||||
return native_method.call(obj);
|
||||
}
|
||||
return obj.replace(/^\s+/, '').replace(/\s+$/, '');
|
||||
},
|
||||
|
||||
// Array methods
|
||||
// i optional
|
||||
indexOf: function (find, i) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Array.prototype.indexOf;
|
||||
|
||||
if (native_method) {
|
||||
return native_method.call(obj, find, i);
|
||||
}
|
||||
if (i === undefined) {
|
||||
i = 0;
|
||||
}
|
||||
if (i < 0) {
|
||||
i += obj.length;
|
||||
}
|
||||
if (i < 0) {
|
||||
i = 0;
|
||||
}
|
||||
var n;
|
||||
for (n = obj.length; i < n; i++) {
|
||||
if (undefined !== obj[i] && obj[i] === find) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
// that optional
|
||||
forEach: function (action, that) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Array.prototype.forEach;
|
||||
|
||||
if (native_method) {
|
||||
return native_method.call(obj, action, that);
|
||||
}
|
||||
var i, n;
|
||||
for (i = 0, n = obj.length; i < n; i++) {
|
||||
if (undefined !== obj[i]) {
|
||||
action.call(that, obj[i], i, obj);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// that optional
|
||||
// chain optional
|
||||
map: function (mapper, that, chain) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Array.prototype.map;
|
||||
var returnWrapper = (typeof arguments[arguments.length - 1] == "boolean") ? Array.prototype.pop.call(arguments) : false;
|
||||
var result = [];
|
||||
|
||||
if (native_method) {
|
||||
result = native_method.call(obj, mapper, that);
|
||||
} else {
|
||||
var other = [];
|
||||
var i, n;
|
||||
for (i = 0, n = obj.length; i < n; i++) {
|
||||
if (undefined !== obj[i]) {
|
||||
other[i] = mapper.call(that, obj[i], i, obj);
|
||||
}
|
||||
}
|
||||
result = other;
|
||||
}
|
||||
|
||||
return returnWrapper ? $_(result) : result;
|
||||
},
|
||||
|
||||
// that optional
|
||||
// chain optional
|
||||
filter: function (filterFunc, that, chain) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Array.prototype.filter;
|
||||
var returnWrapper = (typeof arguments[arguments.length - 1] == "boolean") ? Array.prototype.pop.call(arguments) : false;
|
||||
var result = [];
|
||||
|
||||
if (native_method) {
|
||||
result = native_method.call(obj, filterFunc, that);
|
||||
} else {
|
||||
var other = [],
|
||||
v,
|
||||
i,
|
||||
n;
|
||||
for (i = 0, n = obj.length; i < n; i++) {
|
||||
if (undefined !== obj[i] && filterFunc.call(that, v = obj[i], i, obj)) {
|
||||
other.push(v);
|
||||
}
|
||||
}
|
||||
result = other;
|
||||
}
|
||||
|
||||
return returnWrapper ? $_(result) : result;
|
||||
},
|
||||
|
||||
// that optional
|
||||
every: function (tester, that) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Array.prototype.every;
|
||||
|
||||
if (native_method) {
|
||||
return native_method.call(obj, tester, that);
|
||||
}
|
||||
var i, n;
|
||||
for (i = 0, n = obj.length; i < n; i++) {
|
||||
if (undefined !== obj[i] && !tester.call(that, obj[i], i, obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
// that optional
|
||||
some: function (tester, that) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = Array.prototype.some;
|
||||
|
||||
if (native_method) {
|
||||
return native_method.call(obj, tester, that);
|
||||
}
|
||||
var i, n;
|
||||
for (i = 0, n = obj.length; i < n; i++) {
|
||||
if (undefined !== obj[i] && tester.call(that, obj[i], i, obj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Since IE7 doesn't support 'hasAttribute' method on nodes
|
||||
// TODO: raise an exception if the object is not an node
|
||||
hasAttribute: function (attr) {
|
||||
var obj = this.obj || this;
|
||||
var native_method = obj.hasAttribute;
|
||||
|
||||
if (native_method) {
|
||||
return obj.hasAttribute(attr);
|
||||
}
|
||||
return !!obj.getAttribute(attr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$_ = function (obj) {
|
||||
var Wrapper = function () {};
|
||||
Wrapper.prototype = shims;
|
||||
|
||||
var wrapper_instance = new Wrapper();
|
||||
wrapper_instance.obj = obj;
|
||||
return wrapper_instance;
|
||||
};
|
||||
|
||||
var shim;
|
||||
for (shim in shims) {
|
||||
if (shims.hasOwnProperty(shim)) {
|
||||
$_[shim] = shims[shim];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Node constants
|
||||
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1841493061
|
||||
if (typeof window.Node != 'undefined') {
|
||||
$_.Node = window.Node;
|
||||
} else {
|
||||
$_.Node = {
|
||||
'ELEMENT_NODE': 1,
|
||||
'ATTRIBUTE_NODE': 2,
|
||||
'TEXT_NODE': 3,
|
||||
'CDATA_SECTION_NODE': 4,
|
||||
'ENTITY_REFERENCE_NODE': 5,
|
||||
'ENTITY_NODE': 6,
|
||||
'PROCESSING_INSTRUCTION_NODE': 7,
|
||||
'COMMENT_NODE': 8,
|
||||
'DOCUMENT_NODE': 9,
|
||||
'DOCUMENT_TYPE_NODE': 10,
|
||||
'DOCUMENT_FRAGMENT_NODE': 11,
|
||||
'NOTATION_NODE': 12,
|
||||
//The two nodes are disconnected. Order between disconnected nodes is always implementation-specific.
|
||||
'DOCUMENT_POSITION_DISCONNECTED': 0x01,
|
||||
//The second node precedes the reference node.
|
||||
'DOCUMENT_POSITION_PRECEDING': 0x02,
|
||||
//The node follows the reference node.
|
||||
'DOCUMENT_POSITION_FOLLOWING': 0x04,
|
||||
//The node contains the reference node. A node which contains is always preceding, too.
|
||||
'DOCUMENT_POSITION_CONTAINS': 0x08,
|
||||
//The node is contained by the reference node. A node which is contained is always following, too.
|
||||
'DOCUMENT_POSITION_CONTAINED_BY': 0x10,
|
||||
//The determination of preceding versus following is implementation-specific.
|
||||
'DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC': 0x20
|
||||
};
|
||||
}
|
||||
|
||||
//node.ownerDocument gives the document object, which isn't the right info for a disconnect
|
||||
function getRootParent(node) {
|
||||
var parent = null;
|
||||
|
||||
if (node) {
|
||||
do {
|
||||
parent = node;
|
||||
} while (null != (node = node.parentNode));
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
//Compare Position - MIT Licensed, John Resig; http://ejohn.org/blog/comparing-document-position/
|
||||
//Already checked for equality and disconnect
|
||||
function comparePosition(node1, node2) {
|
||||
return (node1.contains(node2) && 16) + (node2.contains(node1) && 8) + (node1.sourceIndex >= 0 && node2.sourceIndex >= 0 ? (node1.sourceIndex < node2.sourceIndex && 4) + (node1.sourceIndex > node2.sourceIndex && 2) : 1);
|
||||
}
|
||||
|
||||
//get a node with a sourceIndex to use
|
||||
function getUseNode(node) {
|
||||
//if the node already has a sourceIndex, use that node
|
||||
if (null != node.sourceIndex) {
|
||||
return node;
|
||||
}
|
||||
//otherwise, insert a comment (which has a sourceIndex but minimal DOM impact) before the node and use that
|
||||
return node.parentNode.insertBefore(document.createComment(""), node);
|
||||
}
|
||||
|
||||
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-compareDocumentPosition
|
||||
// FIXME: Check if the DOMNode prototype can be set.
|
||||
$_.compareDocumentPosition = function (node1, node2) {
|
||||
|
||||
if (document.documentElement.compareDocumentPosition) {
|
||||
return node1.compareDocumentPosition(node2);
|
||||
}
|
||||
|
||||
if (!document.documentElement.contains) {
|
||||
throw 'neither compareDocumentPosition nor contains is supported by this browser.';
|
||||
}
|
||||
|
||||
if (node1 == node2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if they don't have the same parent, there's a disconnect
|
||||
if (getRootParent(node1) != getRootParent(node2)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
//use this if both nodes have a sourceIndex (text nodes don't)
|
||||
if (null != node1.sourceIndex && null != node2.sourceIndex) {
|
||||
return comparePosition(node1, node2);
|
||||
}
|
||||
|
||||
//document will definitely contain the other node
|
||||
if (node1 == document) {
|
||||
return 20;
|
||||
}
|
||||
if (node2 == document) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
//get sourceIndexes to use for both nodes
|
||||
var useNode1 = getUseNode(node1),
|
||||
useNode2 = getUseNode(node2);
|
||||
|
||||
//call this function again to get the result
|
||||
var result = comparePosition(useNode1, useNode2);
|
||||
|
||||
//clean up if needed
|
||||
if (node1 != useNode1) {
|
||||
useNode1.parentNode.removeChild(useNode1);
|
||||
}
|
||||
if (node2 != useNode2) {
|
||||
useNode2.parentNode.removeChild(useNode2);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
$_.getComputedStyle = function (node, style) {
|
||||
if (window.getComputedStyle) {
|
||||
return window.getComputedStyle(node, style);
|
||||
}
|
||||
if (node.currentStyle) {
|
||||
return node.currentStyle;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return $_;
|
||||
});
|
1032
media/aloha-0.22.7/lib/aloha/editable.js
Normal file
8488
media/aloha-0.22.7/lib/aloha/engine.js
Normal file
456
media/aloha-0.22.7/lib/aloha/ephemera.js
Normal file
@@ -0,0 +1,456 @@
|
||||
/* ephemera.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/**
|
||||
* Provides functions to mark the contents of editables as ephemeral. An
|
||||
* editable's ephemeral content will be pruned before it is being
|
||||
* returned by editable.getContents().
|
||||
*
|
||||
* It is planned to replace most instances of makeClean() with this
|
||||
* implementation for improved performance and more importantly, in
|
||||
* order to have a centralized place that has the control over all
|
||||
* ephemeral content, which can be leveraged by plugins to provide more
|
||||
* advanced functionality.
|
||||
*
|
||||
* Some examples that would be possible:
|
||||
* * a HTML source code text box, an interactive tree structure, or
|
||||
* other kind of DOM visualization, next to the editable, that
|
||||
* contains just the content of the editable (without ephemeral data)
|
||||
* and which is updated efficiently in real time after each keystroke.
|
||||
*
|
||||
* * change detection algorithms that are able to intelligently ignore
|
||||
* ephemeral data and which would not trigger unless non-ephemeral
|
||||
* data is added to the editable.
|
||||
*
|
||||
* * When a plugin provides very general functionality over all nodes of
|
||||
* the DOM, somtimes the plugin may not know what is and what isn't
|
||||
* supposed to be real content. The functionality provided here makes
|
||||
* it possible for the plugin to exaclty distinguish real content from
|
||||
* ephemeral content.
|
||||
*
|
||||
* TODO: currently only simple transformations are suppored, like
|
||||
* marking classes, attributes and elements as ephemeral and removing
|
||||
* them during the pruning process.
|
||||
* In the future, support for the block-plugin and custom pruning
|
||||
* functions should be added. This may be done by letting implementations
|
||||
* completely control the pruning of a DOM element through a
|
||||
* function that takes the content+ephemeral-data and returns only
|
||||
* content - similar to make clean, but for single elements to reduce
|
||||
* overhead.
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'aloha/core',
|
||||
'aloha/console',
|
||||
'util/strings',
|
||||
'util/trees',
|
||||
'util/arrays',
|
||||
'util/maps',
|
||||
'util/dom2',
|
||||
'util/functions',
|
||||
'util/misc',
|
||||
'PubSub'
|
||||
], function (
|
||||
$,
|
||||
Aloha,
|
||||
console,
|
||||
Strings,
|
||||
Trees,
|
||||
Arrays,
|
||||
Maps,
|
||||
Dom,
|
||||
Functions,
|
||||
Misc,
|
||||
PubSub
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var ephemeraMap = {
|
||||
classMap: {
|
||||
'aloha-cleanme': true,
|
||||
'aloha-ui-wrapper': true,
|
||||
'aloha-ui-filler': true,
|
||||
'aloha-ui-attr': true
|
||||
},
|
||||
attrMap: {
|
||||
'hidefocus': true,
|
||||
'hideFocus': true,
|
||||
'tabindex': true,
|
||||
'tabIndex': true,
|
||||
'TABLE.contenteditable': true,
|
||||
'TABLE.contentEditable': true
|
||||
},
|
||||
attrRxs: [/^(?:nodeIndex|sizcache|sizset|jquery)[\w\d]*$/i],
|
||||
pruneFns: []
|
||||
};
|
||||
|
||||
var commonClsSubstr = 'aloha-';
|
||||
|
||||
/**
|
||||
* Checks whether the given classes contain the substring common to
|
||||
* all ephemeral classes. If the check fails, an warning will be
|
||||
* logged and the substring will be set to the empty string which
|
||||
* voids the performance improvement the common substring would
|
||||
* otherwise have gained.
|
||||
*/
|
||||
function checkCommonSubstr(clss) {
|
||||
var i, len;
|
||||
for (i = 0, len = clss.length; i < len; i++) {
|
||||
if (-1 === clss[i].indexOf(commonClsSubstr)) {
|
||||
console.warn('Class "' + clss[i] + '" was set to be ephemeral,' + 'which hurts peformance.' + ' Add the common substring "' + commonClsSubstr + '" to the class to fix this problem.');
|
||||
commonClsSubstr = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers ephemeral classes.
|
||||
*
|
||||
* An ephemeral class is a non-content class that will be pruned
|
||||
* from the from the result of editable.getContents().
|
||||
*
|
||||
* The given classes should contain the string 'aloha-' to get the
|
||||
* benefit of a performance optimization.
|
||||
*
|
||||
* Returns a map that contains all classes that were ever registered
|
||||
* with this function.
|
||||
*
|
||||
* Multiple classes may be specified. If none are specified, just
|
||||
* returns the current ephemeral classes map without modifying it.
|
||||
*
|
||||
* Also see ephemera().
|
||||
*/
|
||||
function classes() {
|
||||
var clss = Array.prototype.slice.call(arguments);
|
||||
Maps.fillKeys(ephemeraMap.classMap, clss, true);
|
||||
checkCommonSubstr(clss);
|
||||
PubSub.pub('aloha.ephemera.classes', {
|
||||
ephemera: ephemeraMap,
|
||||
newClasses: clss
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers ephemeral attributes by attribute name.
|
||||
*
|
||||
* Similar to classes() except applies to entire attributes instead
|
||||
* of individual classes in the class attribute.
|
||||
*/
|
||||
function attributes() {
|
||||
var attrs = Array.prototype.slice.call(arguments);
|
||||
Maps.fillKeys(ephemeraMap.attrMap, attrs, true);
|
||||
PubSub.pub('aloha.ephemera.attributes', {
|
||||
ephemera: ephemeraMap,
|
||||
newAttributes: attrs
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a map containing values to identify ephemeral content into
|
||||
* a global registry.
|
||||
*
|
||||
* The given map may have the following entries
|
||||
* classMap - a map from class name to the value true
|
||||
* attrMap - a map from attribute name to the value true; attribute
|
||||
* names may be optionally prefixed with "ELEMENT.",
|
||||
* where ELEMENT is the name of an element in uppercase,
|
||||
* to prune only from specific elements. An element name prefix
|
||||
* should always be specified if it is known, and if
|
||||
* multiple are known, multiple entries with separate
|
||||
* element prefixes should be made instead of a single
|
||||
* entry without - preserve information for refactoring.
|
||||
* attrRxs - an array of regexes in object form (/[a-z].../ and not "[a-z]...")
|
||||
* pruneFns - an array of functions that will be called at each pruning step.
|
||||
*
|
||||
* Returns the global registry, which has the same structure as above.
|
||||
*
|
||||
* When a DOM tree is pruned with prune(elem) without an emap
|
||||
* argument, the global registry maintained with classes()
|
||||
* attributes() and ephemera() is used as a default map. If an emap
|
||||
* argument is specified, the global registry will be ignored and
|
||||
* the emap argument will be used instead.
|
||||
*
|
||||
* When a DOM tree is pruned with prune()
|
||||
* * classes specified by classMap will be removed
|
||||
* * attributes specified by attrMap or attrRxs will be removed
|
||||
* * functions specified by pruneFns will be called as the DOM tree
|
||||
* is descended into (pre-order), with each node (element, text,
|
||||
* etc.) as a single argument. The function is free to modify the
|
||||
* element and return it, or return a new element which will
|
||||
* replace the given element in the pruned tree. If null or
|
||||
* undefined is returned, the element will be removed from the
|
||||
* tree. As per contract of Maps.walkDomInplace, it is allowed to
|
||||
* insert/remove children in the parent node as long as the given
|
||||
* node is not removed.
|
||||
*
|
||||
* Also see classes() and attributes().
|
||||
*
|
||||
* Note that removal of attributes doesn't always work on IE7 (in
|
||||
* rare special cases). The dom-to-xhtml plugin can reliably remove
|
||||
* ephemeral attributes during the serialization step.
|
||||
*/
|
||||
function ephemera(emap) {
|
||||
if (emap) {
|
||||
if (emap.classMap) {
|
||||
$.extend(ephemeraMap.classMap, emap.classMap);
|
||||
}
|
||||
if (emap.attrMap) {
|
||||
$.extend(ephemeraMap.attrMap, emap.attrMap);
|
||||
}
|
||||
if (emap.attrRxs) {
|
||||
ephemeraMap.attrRxs = ephemeraMap.attrRxs.concat(emap.attrRxs);
|
||||
}
|
||||
if (emap.pruneFns) {
|
||||
ephemeraMap.pruneFns = ephemeraMap.pruneFns.concat(emap.pruneFns);
|
||||
}
|
||||
PubSub.pub('aloha.ephemera', {
|
||||
ephemera: ephemeraMap,
|
||||
newEphemera: emap
|
||||
});
|
||||
}
|
||||
return ephemeraMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks an element as ephemeral.
|
||||
*
|
||||
* The element will be completely removed when the prune function is
|
||||
* called on it.
|
||||
*/
|
||||
function markElement(elem) {
|
||||
$(elem).addClass('aloha-cleanme');
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the attribute of an element as ephemeral.
|
||||
*
|
||||
* The attribute will be removed from the element when the prune
|
||||
* function is called on it.
|
||||
*
|
||||
* Multiple attributes can be passed at the same time be separating
|
||||
* them with a space.
|
||||
*/
|
||||
function markAttribute(elem, attr) {
|
||||
elem = $(elem);
|
||||
var data = elem.attr('data-aloha-ui-attr');
|
||||
data = (null == data || '' === data ? attr : data + ' ' + attr);
|
||||
elem.attr('data-aloha-ui-attr', data);
|
||||
elem.addClass('aloha-ui-attr');
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks an element as a ephemeral, excluding subnodes.
|
||||
*
|
||||
* The element will be removed when the prune function is called on
|
||||
* it, but any children of the wrapper element will remain in its
|
||||
* place.
|
||||
*
|
||||
* A wrapper is an element that wraps a single non-ephemeral
|
||||
* element. A filler is an element that is wrapped by a single
|
||||
* non-ephemeral element. This distinction is not important for the
|
||||
* prune function, which behave the same for both wrappers and
|
||||
* fillers, but it makes it easier to build more advanced content
|
||||
* inspection algorithms (also see note at the header of ephemeral.js).
|
||||
*
|
||||
* NB: a wrapper element must not wrap a filler element. Wrappers
|
||||
* and fillers are ephermeral. A wrapper must always wrap a
|
||||
* single _non-ephemeral_ element, and a filler must always fill
|
||||
* a single _non-ephemeral_ element.
|
||||
*/
|
||||
function markWrapper(elem) {
|
||||
$(elem).addClass('aloha-ui-wrapper');
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks an element as ephemeral, excluding subnodes.
|
||||
*
|
||||
* See wrapper()
|
||||
*/
|
||||
function markFiller(elem) {
|
||||
$(elem).addClass('aloha-ui-filler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes attributes marked as ephemeral with Ephemera.attributes()
|
||||
* from the given element.
|
||||
*/
|
||||
function pruneMarkedAttrs(elem) {
|
||||
var $elem = $(elem);
|
||||
var data = $elem.attr('data-aloha-ui-attr');
|
||||
var i;
|
||||
var attrs;
|
||||
$elem.removeAttr('data-aloha-ui-attr');
|
||||
if (typeof data === 'string') {
|
||||
attrs = Strings.words(data);
|
||||
for (i = 0; i < attrs.length; i++) {
|
||||
$elem.removeAttr(attrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given attribute of the given element is
|
||||
* ephemeral according to the given emap.
|
||||
* See Ephemera.ephemera() for an explanation of attrMap and attrRxs.
|
||||
*/
|
||||
function isAttrEphemeral(elem, attrName, attrMap, attrRxs) {
|
||||
return attrMap[attrName] || Misc.anyRx(attrRxs, attrName) || attrMap[elem.nodeName + '.' + attrName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes attributes specified with either emap.attrMap or emap.attrRxs.
|
||||
* See ephemera().
|
||||
*/
|
||||
function pruneEmapAttrs(elem, emap) {
|
||||
var $elem = null,
|
||||
attrs = Dom.attrNames(elem),
|
||||
name,
|
||||
i,
|
||||
len;
|
||||
for (i = 0, len = attrs.length; i < len; i++) {
|
||||
name = attrs[i];
|
||||
if (isAttrEphemeral(elem, name, emap.attrMap, emap.attrRxs)) {
|
||||
$elem = $elem || $(elem);
|
||||
$elem.removeAttr(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes an element of attributes and classes or removes the
|
||||
* element by returning false.
|
||||
*
|
||||
* Elements attributes and classes can either be marked as
|
||||
* ephemeral, in which case the element itself will contain the
|
||||
* prune-info, or they can be specified as ephemeral with the given
|
||||
* emap.
|
||||
*
|
||||
* See ephemera() for an explanation of the emap argument.
|
||||
*/
|
||||
function pruneElem(elem, emap) {
|
||||
var className = elem.className;
|
||||
if (className && -1 !== className.indexOf(commonClsSubstr)) {
|
||||
var classes = Strings.words(className);
|
||||
|
||||
// Ephemera.markElement()
|
||||
if (-1 !== Arrays.indexOf(classes, 'aloha-cleanme')) {
|
||||
$.removeData(elem); // avoids memory leak
|
||||
return false; // removes the element
|
||||
}
|
||||
|
||||
// Ephemera.markWrapper() and Ephemera.markFiller()
|
||||
if (-1 !== Arrays.indexOf(classes, 'aloha-ui-wrapper') || -1 !== Arrays.indexOf(classes, 'aloha-ui-filler')) {
|
||||
Dom.moveNextAll(elem.parentNode, elem.firstChild, elem.nextSibling);
|
||||
$.removeData(elem);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ephemera.markAttribute()
|
||||
if (-1 !== Arrays.indexOf(classes, 'aloha-ui-attr')) {
|
||||
pruneMarkedAttrs(elem);
|
||||
}
|
||||
|
||||
// Ephemera.classes() and Ehpemera.ephemera({ classMap: {} })
|
||||
var persistentClasses = Arrays.filter(classes, function (cls) {
|
||||
return !emap.classMap[cls];
|
||||
});
|
||||
if (persistentClasses.length !== classes.length) {
|
||||
if (0 === persistentClasses.length) {
|
||||
// Removing the attributes is dangerous. Aloha has a
|
||||
// jquery patch in place to fix some issue.
|
||||
$(elem).removeAttr('class');
|
||||
} else {
|
||||
elem.className = persistentClasses.join(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ephemera.attributes() and Ephemera.ephemera({ attrMap: {}, attrRxs: {} })
|
||||
pruneEmapAttrs(elem, emap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for each node during the pruning of a DOM tree.
|
||||
*/
|
||||
function pruneStep(emap, step, node) {
|
||||
if (1 === node.nodeType) {
|
||||
if (!pruneElem(node, emap)) {
|
||||
return [];
|
||||
}
|
||||
node = Trees.walkDomInplace(node, step);
|
||||
}
|
||||
|
||||
// Ephemera.ephemera({ pruneFns: [] })
|
||||
node = Arrays.reduce(emap.pruneFns, node, Arrays.applyNotNull);
|
||||
if (!node) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [node];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes the given element of all ephemeral data.
|
||||
*
|
||||
* Elements marked with Ephemera.markElement() will be removed.
|
||||
* Attributes marked with Ephemera.markAttribute() will be removed.
|
||||
* Elements marked with Ephemera.markWrapper() or
|
||||
* Ephemera.markFiller() will be replaced with their children.
|
||||
*
|
||||
* See ephemera() for an explanation of the emap argument.
|
||||
*
|
||||
* All properties of emap, if specified, are required, but may be
|
||||
* empty.
|
||||
*
|
||||
* The element is modified in-place and returned.
|
||||
*/
|
||||
function prune(elem, emap) {
|
||||
emap = emap || ephemeraMap;
|
||||
|
||||
function pruneStepClosure(node) {
|
||||
return pruneStep(emap, pruneStepClosure, node);
|
||||
}
|
||||
return pruneStepClosure(elem)[0];
|
||||
}
|
||||
|
||||
if (Aloha.settings.ephemera) {
|
||||
ephemera(Aloha.settings.ephemera);
|
||||
}
|
||||
|
||||
return {
|
||||
ephemera: ephemera,
|
||||
classes: classes,
|
||||
attributes: attributes,
|
||||
markElement: markElement,
|
||||
markAttribute: markAttribute,
|
||||
markWrapper: markWrapper,
|
||||
markFiller: markFiller,
|
||||
prune: prune,
|
||||
isAttrEphemeral: isAttrEphemeral
|
||||
};
|
||||
});
|
29
media/aloha-0.22.7/lib/aloha/ierange-m2.js
Executable file
@@ -0,0 +1,29 @@
|
||||
/* ierange-m2.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define(['vendor/ierange-m2'], function () {
|
||||
'use strict';
|
||||
});
|
525
media/aloha-0.22.7/lib/aloha/jquery.aloha.js
Executable file
@@ -0,0 +1,525 @@
|
||||
/* jquery.aloha.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/**
|
||||
* IMPORTANT!
|
||||
* Don't add any more custom jquery extensions here.
|
||||
* Instead use the define(...) mechanism to define a module and to
|
||||
* import it where you need it.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'aloha/selection',
|
||||
'jquery',
|
||||
'aloha/console'
|
||||
], function (
|
||||
Aloha,
|
||||
Selection,
|
||||
jQuery,
|
||||
console
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var XMLSerializer = window.XMLSerializer;
|
||||
|
||||
/**
|
||||
* jQuery between Extension
|
||||
*
|
||||
* insert either html code, a dom object OR a jQuery object inside of an existing text node.
|
||||
* if the chained jQuery object is not a text node, nothing will happen.
|
||||
*
|
||||
* @param content HTML Code, DOM object or jQuery object to be inserted
|
||||
* @param offset character offset from the start where the content should be inserted
|
||||
*/
|
||||
jQuery.fn.between = function (content, offset) {
|
||||
var offSize, fullText;
|
||||
|
||||
if (this[0].nodeType !== 3) {
|
||||
// we are not in a text node, just insert the element at the corresponding position
|
||||
offSize = this.children().size();
|
||||
if (offset > offSize) {
|
||||
offset = offSize;
|
||||
}
|
||||
if (offset <= 0) {
|
||||
this.prepend(content);
|
||||
} else {
|
||||
this.children().eq(offset - 1).after(content);
|
||||
}
|
||||
} else {
|
||||
// we are in a text node so we have to split it at the correct position
|
||||
if (offset <= 0) {
|
||||
this.before(content);
|
||||
} else if (offset >= this[0].length) {
|
||||
this.after(content);
|
||||
} else {
|
||||
fullText = this[0].data;
|
||||
this[0].data = fullText.substring(0, offset);
|
||||
this.after(fullText.substring(offset, fullText.length));
|
||||
this.after(content);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the object contenteditable. Care about browser version (name of contenteditable attribute depends on it)
|
||||
*/
|
||||
jQuery.fn.contentEditable = function (b) {
|
||||
// ie does not understand contenteditable but contentEditable
|
||||
// contentEditable is not xhtml compatible.
|
||||
var $el = jQuery(this);
|
||||
var ce = 'contenteditable';
|
||||
|
||||
// Check
|
||||
if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) == 7) {
|
||||
ce = 'contentEditable';
|
||||
}
|
||||
|
||||
if (typeof b === 'undefined') {
|
||||
|
||||
// For chrome use this specific attribute. The old ce will only
|
||||
// return 'inherit' for nested elements of a contenteditable.
|
||||
// The isContentEditable is a w3c standard compliant property which works in IE7,8,FF36+, Chrome 12+
|
||||
if (typeof $el[0] === 'undefined') {
|
||||
console.warn('The jquery object did not contain any valid elements.'); // die silent
|
||||
return undefined;
|
||||
}
|
||||
if (typeof $el[0].isContentEditable === 'undefined') {
|
||||
console.warn('Could not determine whether the is editable or not. I assume it is.');
|
||||
return true;
|
||||
}
|
||||
|
||||
return $el[0].isContentEditable;
|
||||
}
|
||||
|
||||
if (b === '') {
|
||||
$el.removeAttr(ce);
|
||||
} else {
|
||||
if (b && b !== 'false') {
|
||||
b = 'true';
|
||||
} else {
|
||||
b = 'false';
|
||||
}
|
||||
$el.attr(ce, b);
|
||||
}
|
||||
|
||||
return $el;
|
||||
};
|
||||
|
||||
/**
|
||||
* jQuery Aloha Plugin.
|
||||
*
|
||||
* Makes the elements in a jQuery selection set Aloha editables.
|
||||
*
|
||||
* @return jQuery container of holding DOM elements that have been
|
||||
* aloha()fied.
|
||||
* @api
|
||||
*/
|
||||
jQuery.fn.aloha = function () {
|
||||
var $elements = this;
|
||||
Aloha.bind('aloha-plugins-loaded', function () {
|
||||
$elements.each(function (_, elem) {
|
||||
if (!Aloha.isEditable(elem)) {
|
||||
new Aloha.Editable(jQuery(elem)).init();
|
||||
}
|
||||
});
|
||||
});
|
||||
return $elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* jQuery destroy elements as editable
|
||||
*
|
||||
* destroy all mached elements editable capabilities
|
||||
* @return jQuery object for the matched elements
|
||||
* @api
|
||||
*/
|
||||
jQuery.fn.mahalo = function () {
|
||||
return this.each(function () {
|
||||
if (Aloha.isEditable(this)) {
|
||||
Aloha.getEditableById(jQuery(this).attr('id')).destroy();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* jQuery Extension
|
||||
* new Event which is triggered whenever a selection (length >= 0) is made in
|
||||
* an Aloha Editable element
|
||||
*/
|
||||
jQuery.fn.contentEditableSelectionChange = function (callback) {
|
||||
var that = this;
|
||||
|
||||
// update selection when keys are pressed
|
||||
this.keyup(function (event) {
|
||||
var rangeObject = Selection.getRangeObject();
|
||||
callback(event);
|
||||
});
|
||||
|
||||
// update selection on doubleclick (especially important for the first automatic selection, when the Editable is not active yet, but is at the same time activated as the selection occurs
|
||||
this.dblclick(function (event) {
|
||||
callback(event);
|
||||
});
|
||||
|
||||
// update selection when text is selected
|
||||
this.mousedown(function (event) {
|
||||
// remember that a selection was started
|
||||
that.selectionStarted = true;
|
||||
});
|
||||
|
||||
jQuery(document).mouseup(function (event) {
|
||||
Selection.eventOriginalTarget = that;
|
||||
if (that.selectionStarted) {
|
||||
callback(event);
|
||||
}
|
||||
Selection.eventOriginalTarget = false;
|
||||
that.selectionStarted = false;
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the outerHTML of an Element
|
||||
* @version 1.0.0
|
||||
* @date February 01, 2011
|
||||
* @package jquery-sparkle {@link http://www.balupton/projects/jquery-sparkle}
|
||||
* @author Benjamin Arthur Lupton {@link http://balupton.com}
|
||||
* @copyright 2011 Benjamin Arthur Lupton {@link http://balupton.com}
|
||||
* @license MIT License {@link http://creativecommons.org/licenses/MIT/}
|
||||
* @return {String} outerHtml
|
||||
*/
|
||||
jQuery.fn.outerHtml = jQuery.fn.outerHtml || function () {
|
||||
var $el = jQuery(this),
|
||||
el = $el.get(0);
|
||||
if (typeof el.outerHTML != 'undefined') {
|
||||
return el.outerHTML;
|
||||
}
|
||||
try {
|
||||
// Gecko-based browsers, Safari, Opera.
|
||||
return (new XMLSerializer()).serializeToString(el);
|
||||
} catch (e) {
|
||||
try {
|
||||
// Internet Explorer.
|
||||
return el.xml;
|
||||
} catch (e2) {}
|
||||
}
|
||||
};
|
||||
|
||||
jQuery.fn.zap = function () {
|
||||
return this.each(function () {
|
||||
jQuery(this.childNodes).insertBefore(this);
|
||||
}).remove();
|
||||
};
|
||||
|
||||
jQuery.fn.textNodes = function (excludeBreaks, includeEmptyTextNodes) {
|
||||
var ret = [],
|
||||
doSomething = function (el) {
|
||||
var i, childLength;
|
||||
if ((el.nodeType === 3 && jQuery.trim(el.data) && !includeEmptyTextNodes) || (el.nodeType === 3 && includeEmptyTextNodes) || (el.nodeName == "BR" && !excludeBreaks)) {
|
||||
ret.push(el);
|
||||
} else {
|
||||
for (i = 0, childLength = el.childNodes.length; i < childLength; ++i) {
|
||||
doSomething(el.childNodes[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
doSomething(this[0]);
|
||||
|
||||
return jQuery(ret);
|
||||
};
|
||||
|
||||
/**
|
||||
* extendObjects is like jQuery.extend, but it does not extend arrays
|
||||
*/
|
||||
jQuery.extendObjects = jQuery.fn.extendObjects = function (arg1, arg2) {
|
||||
var options, name, src, copy, copyIsArray, clone,
|
||||
start = 1,
|
||||
target = arg1 || {},
|
||||
length = arguments.length,
|
||||
deep = false,
|
||||
i;
|
||||
|
||||
|
||||
// Handle a deep copy situation
|
||||
if (typeof target === "boolean") {
|
||||
deep = target;
|
||||
target = arg2 || {};
|
||||
// skip the boolean and the target
|
||||
start = 2;
|
||||
}
|
||||
|
||||
// Handle case when target is a string or something (possible in deep copy)
|
||||
if (typeof target !== "object" && !jQuery.isFunction(target)) {
|
||||
target = {};
|
||||
}
|
||||
|
||||
// extend jQuery itself if only one argument is passed
|
||||
if (length === start) {
|
||||
target = this;
|
||||
--start;
|
||||
}
|
||||
|
||||
for (i = start; i < length; i++) {
|
||||
// Only deal with non-null/undefined values
|
||||
if ((options = arguments[i]) != null) {
|
||||
// Extend the base object
|
||||
for (name in options) {
|
||||
if (options.hasOwnProperty(name)) {
|
||||
|
||||
src = target[name];
|
||||
copy = options[name];
|
||||
|
||||
// Prevent never-ending loop
|
||||
if (target === copy) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Recurse if we're merging plain objects or arrays
|
||||
if (deep && copy && (jQuery.isPlainObject(copy) || true === (copyIsArray = jQuery.isArray(copy)))) {
|
||||
if (copyIsArray) {
|
||||
copyIsArray = false;
|
||||
clone = src && jQuery.isArray(src) ? src : [];
|
||||
|
||||
} else {
|
||||
clone = src && jQuery.isPlainObject(src) ? src : {};
|
||||
}
|
||||
|
||||
// Never move original objects, clone them
|
||||
if (jQuery.isArray(copy)) {
|
||||
// don't extend arrays
|
||||
target[name] = copy;
|
||||
} else {
|
||||
target[name] = jQuery.extendObjects(deep, clone, copy);
|
||||
}
|
||||
|
||||
// Don't bring in undefined values
|
||||
} else if (copy !== undefined) {
|
||||
target[name] = copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the modified object
|
||||
return target;
|
||||
};
|
||||
|
||||
/*
|
||||
* jQuery Hotkeys Plugin
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Based upon the plugin by Tzury Bar Yochay:
|
||||
* http://github.com/tzuryby/hotkeys
|
||||
*
|
||||
* Original idea by:
|
||||
* Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
*/
|
||||
|
||||
jQuery.hotkeys = {
|
||||
version: "0.8",
|
||||
|
||||
specialKeys: {
|
||||
8: "backspace",
|
||||
9: "tab",
|
||||
13: "return",
|
||||
16: "shift",
|
||||
17: "ctrl",
|
||||
18: "alt",
|
||||
19: "pause",
|
||||
20: "capslock",
|
||||
27: "esc",
|
||||
32: "space",
|
||||
33: "pageup",
|
||||
34: "pagedown",
|
||||
35: "end",
|
||||
36: "home",
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
40: "down",
|
||||
45: "insert",
|
||||
46: "del",
|
||||
96: "0",
|
||||
97: "1",
|
||||
98: "2",
|
||||
99: "3",
|
||||
100: "4",
|
||||
101: "5",
|
||||
102: "6",
|
||||
103: "7",
|
||||
104: "8",
|
||||
105: "9",
|
||||
106: "*",
|
||||
107: "+",
|
||||
109: "-",
|
||||
110: ".",
|
||||
111: "/",
|
||||
112: "f1",
|
||||
113: "f2",
|
||||
114: "f3",
|
||||
115: "f4",
|
||||
116: "f5",
|
||||
117: "f6",
|
||||
118: "f7",
|
||||
119: "f8",
|
||||
120: "f9",
|
||||
121: "f10",
|
||||
122: "f11",
|
||||
123: "f12",
|
||||
144: "numlock",
|
||||
145: "scroll",
|
||||
191: "/",
|
||||
224: "meta"
|
||||
},
|
||||
|
||||
shiftNums: {
|
||||
"`": "~",
|
||||
"1": "!",
|
||||
"2": "@",
|
||||
"3": "#",
|
||||
"4": "$",
|
||||
"5": "%",
|
||||
"6": "^",
|
||||
"7": "&",
|
||||
"8": "*",
|
||||
"9": "(",
|
||||
"0": ")",
|
||||
"-": "_",
|
||||
"=": "+",
|
||||
";": ": ",
|
||||
"'": "\"",
|
||||
",": "<",
|
||||
".": ">",
|
||||
"/": "?",
|
||||
"\\": "|"
|
||||
}
|
||||
};
|
||||
|
||||
function applyKeyHandler(handler, context, args, event) {
|
||||
// Don't fire in text-accepting inputs that we didn't directly bind to
|
||||
if (context !== event.target && (/textarea|input|select/i.test(event.target.nodeName) || event.target.type === "text")) {
|
||||
return;
|
||||
}
|
||||
return handler.apply(context, args);
|
||||
}
|
||||
|
||||
function keyHandler(handleObj) {
|
||||
var origHandler, keys, handle, i;
|
||||
|
||||
// Only care when a possible input has been specified
|
||||
if (typeof handleObj.data !== "string") {
|
||||
return;
|
||||
}
|
||||
|
||||
origHandler = handleObj.handler;
|
||||
keys = handleObj.data.toLowerCase().split(" ");
|
||||
handle = {};
|
||||
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
handle[keys[i]] = true;
|
||||
}
|
||||
|
||||
handleObj.handler = function (event) {
|
||||
// The original comment that was added with this condition says:
|
||||
// "Don't fire in contentEditable true elements"
|
||||
// But this is incorrect.
|
||||
// What this condition does is it skips hotkey events for
|
||||
// any target unless it is directly bound.
|
||||
// The condition event.target.contentEditable !== true will
|
||||
// always be true, because contentEditable is a string
|
||||
// attribute that is never strictly equal true.
|
||||
//if (this !== event.target && event.target.contentEditable !== true) {
|
||||
//return;
|
||||
//}
|
||||
// Below is what this condition really does. Ideally, I'd
|
||||
// like to remove this condition since it was not there in
|
||||
// the original implementation by John Resig and it could
|
||||
// interfere with other plugins, but when I removed it, I
|
||||
// was unable to input any space characters into an
|
||||
// editable.
|
||||
// TODO figure out a way to safely remove this
|
||||
if (this !== event.target) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Keypress represents characters, not special keys
|
||||
var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[event.which],
|
||||
modif = "",
|
||||
character;
|
||||
|
||||
// check combinations (alt|ctrl|shift+anything)
|
||||
if (event.altKey && special !== "alt") {
|
||||
modif += "alt+";
|
||||
}
|
||||
|
||||
if (event.ctrlKey && special !== "ctrl") {
|
||||
modif += "ctrl+";
|
||||
}
|
||||
|
||||
// TODO: Need to make sure this works consistently across platforms
|
||||
if (event.metaKey && !event.ctrlKey && special !== "meta") {
|
||||
modif += "meta+";
|
||||
}
|
||||
|
||||
if (event.shiftKey && special !== "shift") {
|
||||
modif += "shift+";
|
||||
}
|
||||
|
||||
if (special) {
|
||||
if (handle[modif + special]) {
|
||||
return applyKeyHandler(origHandler, this, arguments, event);
|
||||
}
|
||||
} else {
|
||||
character = String.fromCharCode(event.which).toLowerCase();
|
||||
|
||||
if (handle[modif + character]) {
|
||||
return applyKeyHandler(origHandler, this, arguments, event);
|
||||
}
|
||||
|
||||
if (handle[modif + jQuery.hotkeys.shiftNums[character]]) {
|
||||
return applyKeyHandler(origHandler, this, arguments, event);
|
||||
}
|
||||
|
||||
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
|
||||
if (modif === "shift+") {
|
||||
if (handle[jQuery.hotkeys.shiftNums[character]]) {
|
||||
return applyKeyHandler(origHandler, this, arguments, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
jQuery.each(['keydown', 'keyup', 'keypress'], function () {
|
||||
jQuery.event.special[this] = {
|
||||
add: keyHandler
|
||||
};
|
||||
});
|
||||
|
||||
});
|
1272
media/aloha-0.22.7/lib/aloha/markup.js
Executable file
11
media/aloha-0.22.7/lib/aloha/nls/ca/i18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
define({
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Abreviació",
|
||||
"floatingmenu.tab.format": "Format",
|
||||
"floatingmenu.tab.insert": "Insereix",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
"cancel": "Cancel·la",
|
||||
"repository.no_item_found": "No s\'ha trobat cap element.",
|
||||
"repository.loading": "S\'està carregant",
|
||||
"repository.no_items_found_yet": "Encara no s\'ha trobat cap element..."
|
||||
});
|
11
media/aloha-0.22.7/lib/aloha/nls/de/i18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
define({
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Abkürzung",
|
||||
"floatingmenu.tab.format": "Formatieren",
|
||||
"floatingmenu.tab.insert": "Einfügen",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"cancel": "Abbrechen",
|
||||
"repository.no_item_found": "Keinen Eintrag gefunden.",
|
||||
"repository.loading": "Es wird geladen ...",
|
||||
"repository.no_items_found_yet": "Suche nach Einträgen ..."
|
||||
});
|
20
media/aloha-0.22.7/lib/aloha/nls/i18n.js
Normal file
@@ -0,0 +1,20 @@
|
||||
define({
|
||||
"root": {
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Abbreviation",
|
||||
"floatingmenu.tab.format": "Format",
|
||||
"floatingmenu.tab.insert": "Insert",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"cancel": "Cancel",
|
||||
"repository.no_item_found": "No item found.",
|
||||
"repository.loading": "Loading",
|
||||
"repository.no_items_found_yet": "No items found yet..."
|
||||
},
|
||||
"ca": true,
|
||||
"de": true,
|
||||
"mk": true,
|
||||
"pt-br": true,
|
||||
"ru": true,
|
||||
"uk": true,
|
||||
"zh-hans": true
|
||||
});
|
11
media/aloha-0.22.7/lib/aloha/nls/mk/i18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
define({
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Кратенка",
|
||||
"floatingmenu.tab.format": "Изглед",
|
||||
"floatingmenu.tab.insert": "Вметни",
|
||||
"yes": "Да",
|
||||
"no": "Не",
|
||||
"cancel": "Откажи",
|
||||
"repository.no_item_found": "Не е најдено.",
|
||||
"repository.loading": "Се вчитува",
|
||||
"repository.no_items_found_yet": "Сеуште ништо не е најдено..."
|
||||
});
|
11
media/aloha-0.22.7/lib/aloha/nls/pt-br/i18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
define({
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Abreviação",
|
||||
"floatingmenu.tab.format": "Formatar",
|
||||
"floatingmenu.tab.insert": "Inserir",
|
||||
"yes": "Sim",
|
||||
"no": "Não",
|
||||
"cancel": "Cancelar",
|
||||
"repository.no_item_found": "Nenhum item encontrado.",
|
||||
"repository.loading": "Carregando",
|
||||
"repository.no_items_found_yet": "Nenhum item encontrado ainda..."
|
||||
});
|
11
media/aloha-0.22.7/lib/aloha/nls/ru/i18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
define({
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Аббревиатура",
|
||||
"floatingmenu.tab.format": "Форматирование",
|
||||
"floatingmenu.tab.insert": "Вставить",
|
||||
"yes": "Да",
|
||||
"no": "Нет",
|
||||
"cancel": "Отмена",
|
||||
"repository.no_item_found": "Объект не найден",
|
||||
"repository.loading": "Загрузка",
|
||||
"repository.no_items_found_yet": "Пока что ничего не найдено..."
|
||||
});
|
11
media/aloha-0.22.7/lib/aloha/nls/uk/i18n.js
Normal file
@@ -0,0 +1,11 @@
|
||||
define({
|
||||
"plugin.abbr.floatingmenu.tab.abbr": "Абревіатура",
|
||||
"floatingmenu.tab.format": "Форматування",
|
||||
"floatingmenu.tab.insert": "Вставити",
|
||||
"yes": "Так",
|
||||
"no": "Ні",
|
||||
"cancel": "Відмінити",
|
||||
"repository.no_item_found": "Нічого не знайдено",
|
||||
"repository.loading": "Завантаження",
|
||||
"repository.no_items_found_yet": "Поки що нічого не знайдено..."
|
||||
});
|
114
media/aloha-0.22.7/lib/aloha/observable.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/* observable.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'jquery'
|
||||
], function (
|
||||
jQuery,
|
||||
undefined
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
var $ = jQuery;
|
||||
|
||||
return {
|
||||
_eventHandlers: null,
|
||||
|
||||
/**
|
||||
* Attach a handler to an event
|
||||
*
|
||||
* @param {String} eventType A string containing the event name to bind to
|
||||
* @param {Function} handler A function to execute each time the event is triggered
|
||||
* @param {Object} scope Optional. Set the scope in which handler is executed
|
||||
*/
|
||||
bind: function (eventType, handler, scope) {
|
||||
this._eventHandlers = this._eventHandlers || {};
|
||||
if (!this._eventHandlers[eventType]) {
|
||||
this._eventHandlers[eventType] = [];
|
||||
}
|
||||
this._eventHandlers[eventType].push({
|
||||
handler: handler,
|
||||
scope: (scope || window)
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a previously-attached event handler
|
||||
*
|
||||
* @param {String} eventType A string containing the event name to unbind
|
||||
* @param {Function} handler The function that is to be no longer executed. Optional. If not given, unregisters all functions for the given event.
|
||||
*/
|
||||
unbind: function (eventType, handler) {
|
||||
this._eventHandlers = this._eventHandlers || {};
|
||||
if (!this._eventHandlers[eventType]) {
|
||||
return;
|
||||
}
|
||||
if (!handler) {
|
||||
// No handler function given, unbind all event handlers for the eventType
|
||||
this._eventHandlers[eventType] = [];
|
||||
} else {
|
||||
this._eventHandlers[eventType] = $.grep(this._eventHandlers[eventType], function (element) {
|
||||
if (element.handler === handler) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute all handlers attached to the given event type.
|
||||
* All arguments except the eventType are directly passed to the callback function.
|
||||
*
|
||||
* @param (String} eventType A string containing the event name for which the event handlers should be invoked.
|
||||
*/
|
||||
trigger: function (eventType) {
|
||||
this._eventHandlers = this._eventHandlers || {};
|
||||
if (!this._eventHandlers[eventType]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// preparedArguments contains all arguments except the first one.
|
||||
var preparedArguments = [];
|
||||
$.each(arguments, function (i, argument) {
|
||||
if (i > 0) {
|
||||
preparedArguments.push(argument);
|
||||
}
|
||||
});
|
||||
|
||||
$.each(this._eventHandlers[eventType], function (index, element) {
|
||||
element.handler.apply(element.scope, preparedArguments);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears all event handlers. Call this method when cleaning up.
|
||||
*/
|
||||
unbindAll: function () {
|
||||
this._eventHandlers = null;
|
||||
}
|
||||
};
|
||||
});
|
281
media/aloha-0.22.7/lib/aloha/plugin.js
Executable file
@@ -0,0 +1,281 @@
|
||||
/* plugin.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'jquery',
|
||||
'util/class',
|
||||
'aloha/pluginmanager',
|
||||
'aloha/console'
|
||||
], function (
|
||||
Aloha,
|
||||
jQuery,
|
||||
Class,
|
||||
PluginManager,
|
||||
console
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Abstract Plugin Object
|
||||
* @namespace Aloha
|
||||
* @class Plugin
|
||||
* @constructor
|
||||
* @param {String} pluginPrefix unique plugin prefix
|
||||
*/
|
||||
var Plugin = Class.extend({
|
||||
|
||||
name: null,
|
||||
|
||||
/**
|
||||
* contains the plugin's default settings object
|
||||
* @cfg {Object} default settings for the plugin
|
||||
*/
|
||||
defaults: {},
|
||||
|
||||
/**
|
||||
* contains the plugin's settings object
|
||||
* @cfg {Object} settings the plugins settings stored in an object
|
||||
*/
|
||||
settings: {},
|
||||
|
||||
/**
|
||||
* Names of other plugins which must be loaded in order for this plugin to
|
||||
* function.
|
||||
* @cfg {Array}
|
||||
*/
|
||||
dependencies: [],
|
||||
|
||||
_constructor: function (name) {
|
||||
/**
|
||||
* Settings of the plugin
|
||||
*/
|
||||
if (typeof name !== "string") {
|
||||
console.error('Cannot initialise unnamed plugin, skipping');
|
||||
} else {
|
||||
this.name = name;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @return true if dependencies satisfied, false otherwise
|
||||
*/
|
||||
checkDependencies: function () {
|
||||
var plugin = this;
|
||||
var satisfied = true;
|
||||
jQuery.each(plugin.dependencies, function (i, dependency) {
|
||||
if (!Aloha.isPluginLoaded(dependency.toString())) {
|
||||
satisfied = false;
|
||||
console.error('plugin.' + plugin.name,
|
||||
'Required plugin "' + dependency + '" not found.');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return satisfied;
|
||||
},
|
||||
|
||||
/**
|
||||
* Init method of the plugin. Called from Aloha Core to initialize this plugin
|
||||
* @return void
|
||||
* @hide
|
||||
*/
|
||||
init: function () {},
|
||||
|
||||
/**
|
||||
* Get the configuration settings for an editable obj.
|
||||
* Handles both conf arrays or conf objects
|
||||
* <ul>
|
||||
* <li>Array configuration parameters are:
|
||||
* <pre>
|
||||
* "list": {
|
||||
* config : [ 'b', 'h1' ],
|
||||
* editables : {
|
||||
* '#title' : [ ],
|
||||
* 'div' : [ 'b', 'i' ],
|
||||
* '.article' : [ 'h1' ]
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* The hash keys of the editables are css selectors. For a
|
||||
*
|
||||
* <pre>
|
||||
* <div class="article">content</div>
|
||||
* </pre>
|
||||
*
|
||||
* the selectors 'div' and '.article' match and the returned configuration is
|
||||
*
|
||||
* <pre>
|
||||
* [ 'b', 'i', 'h1']
|
||||
* </pre>
|
||||
*
|
||||
* The '#title' object would return an empty configuration.
|
||||
*
|
||||
* <pre>
|
||||
* [ ]
|
||||
* </pre>
|
||||
*
|
||||
* All other objects would get the 'config' configuration. If config is not set
|
||||
* the plugin default configuration is returned.
|
||||
*
|
||||
* <pre>
|
||||
* [ 'b', 'h1']
|
||||
* </pre></li>
|
||||
* <li>Object configuration parameters are :
|
||||
* <pre>
|
||||
* "image": {
|
||||
* config : { 'img': { 'max_width': '50px',
|
||||
* 'max_height': '50px' }},
|
||||
* editables : {
|
||||
* '#title': {},
|
||||
* 'div': {'img': {}},
|
||||
* '.article': {'img': { 'max_width': '150px',
|
||||
* 'max_height': '150px' }}
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* The '#title' object would return an empty configuration.<br/>
|
||||
* The 'div' object would return the default configuration.<br/>
|
||||
* the '.article' would return :
|
||||
* <pre>
|
||||
* {'img': { 'max_width': '150px',
|
||||
* 'max_height': '150px' }}
|
||||
* </pre>
|
||||
* </li>
|
||||
*
|
||||
* @param {jQuery} obj jQuery object of an Editable Object
|
||||
* @return {Array} config A Array with configuration entries
|
||||
*/
|
||||
getEditableConfig: function (obj) {
|
||||
var configObj = null,
|
||||
configSpecified = false,
|
||||
that = this;
|
||||
|
||||
if (this.settings.editables) {
|
||||
// check if the editable's selector matches and if so add its configuration to object configuration
|
||||
jQuery.each(this.settings.editables, function (selector, selectorConfig) {
|
||||
var k;
|
||||
if (obj.is(selector)) {
|
||||
configSpecified = true;
|
||||
if (selectorConfig instanceof Array) {
|
||||
configObj = [];
|
||||
configObj = jQuery.merge(configObj, selectorConfig);
|
||||
} else if (typeof selectorConfig === "object") {
|
||||
configObj = {};
|
||||
configObj['aloha-editable-selector'] = selector;
|
||||
for (k in selectorConfig) {
|
||||
if (selectorConfig.hasOwnProperty(k)) {
|
||||
if (selectorConfig[k] instanceof Array) {
|
||||
//configObj[k] = [];
|
||||
//configObj[k] = jQuery.extend(true, configObj[k], that.config[k], selectorConfig[k]);
|
||||
configObj[k] = selectorConfig[k];
|
||||
} else if (typeof selectorConfig[k] === "object") {
|
||||
configObj[k] = {};
|
||||
configObj[k] = jQuery.extend(true, configObj[k], that.config[k], selectorConfig[k]);
|
||||
} else {
|
||||
configObj[k] = selectorConfig[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
configObj = selectorConfig;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// fall back to default configuration
|
||||
if (!configSpecified) {
|
||||
if (typeof this.settings.config === 'undefined' || !this.settings.config) {
|
||||
configObj = this.config;
|
||||
} else {
|
||||
configObj = this.settings.config;
|
||||
}
|
||||
}
|
||||
|
||||
return configObj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Make the given jQuery object (representing an editable) clean for saving
|
||||
* @param obj jQuery object to make clean
|
||||
* @return void
|
||||
*/
|
||||
makeClean: function (obj) {},
|
||||
|
||||
/**
|
||||
* Make a system-wide unique id out of a plugin-wide unique id by prefixing it with the plugin prefix
|
||||
* @param id plugin-wide unique id
|
||||
* @return system-wide unique id
|
||||
* @hide
|
||||
* @deprecated
|
||||
*/
|
||||
getUID: function (id) {
|
||||
console.deprecated('plugin', 'getUID() is deprecated. Use plugin.name instead.');
|
||||
return this.name;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return string representation of the plugin, which is the prefix
|
||||
* @return name
|
||||
* @hide
|
||||
* @deprecated
|
||||
*/
|
||||
toString: function () {
|
||||
return this.name;
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a plugin message to the logger
|
||||
* @param level log level
|
||||
* @param message log message
|
||||
* @return void
|
||||
* @hide
|
||||
* @deprecated
|
||||
*/
|
||||
log: function (level, message) {
|
||||
console.deprecated('plugin', 'log() is deprecated. Use Aloha.console instead.');
|
||||
console.log(level, this, message);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Static method used as factory to create plugins.
|
||||
*
|
||||
* @param {String} pluginName name of the plugin
|
||||
* @param {Object} definition definition of the plugin, should have at least an "init" and "destroy" method.
|
||||
*/
|
||||
Plugin.create = function (pluginName, definition) {
|
||||
|
||||
var pluginInstance = new (Plugin.extend(definition))(pluginName);
|
||||
pluginInstance.settings = jQuery.extendObjects(true, pluginInstance.defaults, Aloha.settings[pluginName]);
|
||||
PluginManager.register(pluginInstance);
|
||||
|
||||
return pluginInstance;
|
||||
};
|
||||
|
||||
return Plugin;
|
||||
});
|
195
media/aloha-0.22.7/lib/aloha/pluginmanager.js
Normal file
@@ -0,0 +1,195 @@
|
||||
/* pluginmanager.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
// Do not add dependencies that require depend on aloha/core
|
||||
define([
|
||||
'jquery',
|
||||
'util/class'
|
||||
], function (
|
||||
$,
|
||||
Class
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var Aloha = window.Aloha;
|
||||
|
||||
/**
|
||||
* For each plugin setting, assigns it into its corresponding plugin.
|
||||
*
|
||||
* @param {Array.<Plugin>} plugins
|
||||
* @param {object<string, object>} settings
|
||||
*/
|
||||
function mapSettingsIntoPlugins(plugins, settings) {
|
||||
var plugin;
|
||||
for (plugin in settings) {
|
||||
if (settings.hasOwnProperty(plugin) && plugins[plugin]) {
|
||||
plugins[plugin].settings = settings[plugin] || {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a set of plugins or the given `names' list, from among those
|
||||
* specified in `plugins'.
|
||||
*
|
||||
* @param {object<string, object>} plugins
|
||||
* @param {Array.<string>} names List of plugins names.
|
||||
* @return {Array.<Plugins>} List of available plugins.
|
||||
*/
|
||||
function getPlugins(plugins, names) {
|
||||
var available = [];
|
||||
var plugin;
|
||||
var i;
|
||||
for (i = 0; i < names.length; i++) {
|
||||
plugin = plugins[names[i]];
|
||||
if (plugin) {
|
||||
available.push(plugin);
|
||||
}
|
||||
}
|
||||
return available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the plugins in the given list.
|
||||
*
|
||||
* @param {Array.<Plugins>} plugins Plugins to initialize.
|
||||
* @param {function} callback Function to invoke once all plugins have been
|
||||
* successfully initialized.
|
||||
*/
|
||||
function initializePlugins(plugins, callback) {
|
||||
var numToEnable = plugins.length;
|
||||
var onInit = function () {
|
||||
if (0 === --numToEnable && callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
var i;
|
||||
var ret;
|
||||
var plugin;
|
||||
for (i = 0; i < plugins.length; i++) {
|
||||
plugin = plugins[i];
|
||||
plugin.settings = plugin.settings || {};
|
||||
if (typeof plugin.settings.enabled === 'undefined') {
|
||||
plugin.settings.enabled = true;
|
||||
}
|
||||
if (plugin.settings.enabled && plugin.checkDependencies()) {
|
||||
ret = plugin.init();
|
||||
if (ret && typeof ret.done === 'function') {
|
||||
ret.done(onInit);
|
||||
} else {
|
||||
onInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Plugin Manager controls the lifecycle of all Aloha Plugins.
|
||||
*
|
||||
* @namespace Aloha
|
||||
* @class PluginManager
|
||||
* @singleton
|
||||
*/
|
||||
return new (Class.extend({
|
||||
|
||||
plugins: {},
|
||||
|
||||
/**
|
||||
* Initialize all registered plugins.
|
||||
*
|
||||
* @param {function} next Callback to invoke after plugins have
|
||||
* succefully initialized.
|
||||
* @param {Array.<string>} enabled A list of plugin names which are to
|
||||
* be enable.
|
||||
*/
|
||||
init: function (next, enabled) {
|
||||
var manager = this;
|
||||
var plugins = manager.plugins;
|
||||
|
||||
mapSettingsIntoPlugins(plugins,
|
||||
Aloha && Aloha.settings && Aloha.settings.plugins);
|
||||
|
||||
// Because all plugins are enabled by default if specific plugins
|
||||
// are not specified.
|
||||
var plugin;
|
||||
if (!plugins || 0 === enabled.length) {
|
||||
enabled = [];
|
||||
for (plugin in plugins) {
|
||||
if (plugins.hasOwnProperty(plugin)) {
|
||||
enabled.push(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initializePlugins(getPlugins(plugins, enabled), next);
|
||||
},
|
||||
|
||||
/**
|
||||
* Register a plugin
|
||||
* @param {Plugin} plugin plugin to register
|
||||
*/
|
||||
register: function (plugin) {
|
||||
|
||||
if (!plugin.name) {
|
||||
throw new Error('Plugin does not have an name.');
|
||||
}
|
||||
|
||||
if (this.plugins[plugin.name]) {
|
||||
throw new Error('Already registered the plugin "' + plugin.name + '"!');
|
||||
}
|
||||
|
||||
this.plugins[plugin.name] = plugin;
|
||||
},
|
||||
|
||||
/**
|
||||
* Pass the given jQuery object, which represents an editable to all plugins, so that they can make the content clean (prepare for saving)
|
||||
* @param obj jQuery object representing an editable
|
||||
* @return void
|
||||
* @hide
|
||||
*/
|
||||
makeClean: function (obj) {
|
||||
var i, plugin;
|
||||
// iterate through all registered plugins
|
||||
for (plugin in this.plugins) {
|
||||
if (this.plugins.hasOwnProperty(plugin)) {
|
||||
if (Aloha.Log.isDebugEnabled()) {
|
||||
Aloha.Log.debug(this, 'Passing contents of HTML Element with id { ' + obj.attr('id') + ' } for cleaning to plugin { ' + plugin + ' }');
|
||||
}
|
||||
this.plugins[plugin].makeClean(obj);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Expose a nice name for the Plugin Manager
|
||||
* @hide
|
||||
*/
|
||||
toString: function () {
|
||||
return 'pluginmanager';
|
||||
}
|
||||
|
||||
}))();
|
||||
});
|
30
media/aloha-0.22.7/lib/aloha/rangy-core.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/* rangy-core.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define('aloha/rangy-core', ['jquery', 'vendor/rangy-core'], function (jQuery) {
|
||||
'use strict';
|
||||
return window.rangy;
|
||||
});
|
137
media/aloha-0.22.7/lib/aloha/registry.js
Normal file
@@ -0,0 +1,137 @@
|
||||
/* registry.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
/*global define:true */
|
||||
/**
|
||||
* Registry base class.
|
||||
* TODO: document that it also contains Observable.
|
||||
*
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'aloha/observable',
|
||||
'util/class'
|
||||
], function (
|
||||
jQuery,
|
||||
Observable,
|
||||
Class
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
return Class.extend(Observable, {
|
||||
|
||||
/**
|
||||
* Object containing the registered entries by key.
|
||||
*/
|
||||
_entries: null,
|
||||
|
||||
/**
|
||||
* Array containing the registered ids in order
|
||||
* of registry
|
||||
*/
|
||||
_ids: null,
|
||||
|
||||
_constructor: function () {
|
||||
this._entries = {};
|
||||
this._ids = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Register an entry with an id
|
||||
*
|
||||
* @event register
|
||||
* @param id id of the registered entry
|
||||
* @param entry registered entry
|
||||
*/
|
||||
register: function (id, entry) {
|
||||
// TODO check whether an entry with the id is already registered
|
||||
this._entries[id] = entry;
|
||||
this._ids.push(id);
|
||||
this.trigger('register', entry, id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Unregister the entry with given id
|
||||
*
|
||||
* @event unregister
|
||||
* @param id id of the registered entry
|
||||
*/
|
||||
unregister: function (id) {
|
||||
// TODO check whether an entry was registered
|
||||
var i, oldEntry = this._entries[id];
|
||||
delete this._entries[id];
|
||||
for (i in this._ids) {
|
||||
if (this._ids.hasOwnProperty(i) && this._ids[i] === id) {
|
||||
this._ids.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.trigger('unregister', oldEntry, id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the entry registered with the given id
|
||||
*
|
||||
* @param id id of the registered entry
|
||||
* @return registered entry
|
||||
*/
|
||||
get: function (id) {
|
||||
return this._entries[id];
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether an entry was registered with given id
|
||||
*
|
||||
* @param id id to check
|
||||
* @return true if an entry was registered, false if not
|
||||
*/
|
||||
has: function (id) {
|
||||
return (this._entries[id] ? true : false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an object mapping the ids (properties) to the registered entries
|
||||
* Note, that iterating over the properties of the returned object
|
||||
* will return the entries in an unspecified order
|
||||
*
|
||||
* @return object containing the registered entries
|
||||
*/
|
||||
getEntries: function () {
|
||||
// clone the entries so the user does not accidentally modify our _entries object.
|
||||
return jQuery.extend({}, this._entries);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the ids of the registered objects as array.
|
||||
* The array will contain the ids in order of registry
|
||||
*
|
||||
* @return array if registered ids
|
||||
*/
|
||||
getIds: function () {
|
||||
return jQuery.extend([], this._ids);
|
||||
}
|
||||
});
|
||||
});
|
255
media/aloha-0.22.7/lib/aloha/repository.js
Executable file
@@ -0,0 +1,255 @@
|
||||
/* repository.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'util/class',
|
||||
'aloha/repositorymanager'
|
||||
], function (
|
||||
Aloha,
|
||||
Class,
|
||||
RepositoryManager
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
// var
|
||||
// $ = jQuery,
|
||||
// GENTICS = window.GENTICS,
|
||||
// Aloha = window.Aloha,
|
||||
// Class = window.Class;
|
||||
|
||||
/**
|
||||
* Abstract Repository Class. Implement that class for your own repository.
|
||||
* @namespace Aloha.Repository
|
||||
* @class Repository
|
||||
* @constructor
|
||||
* @param {String} repositoryId unique repository identifier
|
||||
* @param {String} repositoryName (optional) is the displyed name for this Repository instance
|
||||
*/
|
||||
var AbstractRepository = Class.extend({
|
||||
_constructor: function (repositoryId, repositoryName) {
|
||||
/**
|
||||
* @property repositoryId is the unique Id for this Repository instance
|
||||
*/
|
||||
this.repositoryId = repositoryId;
|
||||
|
||||
/**
|
||||
* contains the repository's settings object
|
||||
* @property settings {Object} the repository's settings stored in an object
|
||||
*/
|
||||
this.settings = {};
|
||||
|
||||
/**
|
||||
* @property repositoryName is the name for this Repository instance
|
||||
*/
|
||||
this.repositoryName = repositoryName || repositoryId;
|
||||
|
||||
RepositoryManager.register(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Init method of the repository. Called from Aloha Core to initialize this repository
|
||||
* @return void
|
||||
* @hide
|
||||
*/
|
||||
init: function () {},
|
||||
|
||||
/**
|
||||
* Searches a repository for object items matching queryString if none found returns null.
|
||||
* The returned object items must be an array of Aloha.Repository.Object
|
||||
*
|
||||
<pre><code>
|
||||
// simple delicious implementation
|
||||
Aloha.Repositories.myRepository.query = function (params, callback) {
|
||||
|
||||
// make local var of this to use in ajax function
|
||||
var that = this;
|
||||
|
||||
// handle each word as tag
|
||||
var tags = p.queryString.split(' ');
|
||||
|
||||
// if we have a query and no tag matching return
|
||||
if ( p.queryString && tags.length == 0 ) {
|
||||
callback.call( that, []);
|
||||
return;
|
||||
}
|
||||
|
||||
// no handling of objectTypeFilter, filter, inFolderId, etc...
|
||||
// in real implementation you should handle all parameters
|
||||
|
||||
jQuery.ajax({ type: "GET",
|
||||
dataType: "jsonp",
|
||||
url: 'http://feeds.delicious.com/v2/json/' + tags.join('+'),
|
||||
success: function(data) {
|
||||
var items = [];
|
||||
// convert data to Aloha objects
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (typeof data[i] != 'function' ) {
|
||||
items.push(new Aloha.Repository.Document ({
|
||||
id: data[i].u,
|
||||
name: data[i].d,
|
||||
repositoryId: that.repositoryId,
|
||||
type: 'website',
|
||||
url: data[i].u
|
||||
}));
|
||||
}
|
||||
}
|
||||
callback.call( that, items);
|
||||
}
|
||||
});
|
||||
};
|
||||
</code></pre>
|
||||
*
|
||||
* @param {object} params object with properties
|
||||
* <div class="mdetail-params"><ul>
|
||||
* <li><code> queryString</code> : String <div class="sub-desc">The query string for full text search</div></li>
|
||||
* <li><code> objectTypeFilter</code> : array (optional) <div class="sub-desc">Object types that will be returned.</div></li>
|
||||
* <li><code> filter</code> : array (optional) <div class="sub-desc">Attributes that will be returned.</div></li>
|
||||
* <li><code> inFolderId</code> : boolean (optional) <div class="sub-desc">This is indicates whether or not a candidate object is a child-object of the folder object identified by the given inFolderId (objectId).</div></li>
|
||||
* <li><code> inTreeId</code> : boolean (optional) <div class="sub-desc">This indicates whether or not a candidate object is a descendant-object of the folder object identified by the given inTreeId (objectId).</div></li>
|
||||
* <li><code> orderBy</code> : array (optional) <div class="sub-desc">ex. [{lastModificationDate:’DESC’, name:’ASC’}]</div></li>
|
||||
* <li><code> maxItems</code> : Integer (optional) <div class="sub-desc">number items to return as result</div></li>
|
||||
* <li><code> skipCount</code> : Integer (optional) <div class="sub-desc">This is tricky in a merged multi repository scenario</div></li>
|
||||
* <li><code> renditionFilter</code> : array (optional) <div class="sub-desc">Instead of termlist an array of kind or mimetype is expected. If null or array.length == 0 all renditions are returned. See http://docs.oasis-open.org/cmis/CMIS/v1.0/cd04/cmis-spec-v1.0.html#_Ref237323310 for renditionFilter</div></li>
|
||||
* </ul></div>
|
||||
* @param {function} callback this method must be called with all result items</div></li>
|
||||
*/
|
||||
query: null,
|
||||
/*
|
||||
query: function( params, callback ) {
|
||||
if (typeof callback === 'function') {
|
||||
callback([]);
|
||||
}
|
||||
},
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns all children of a given motherId.
|
||||
*
|
||||
* @param {object} params object with properties
|
||||
* <div class="mdetail-params"><ul>
|
||||
* <li><code> objectTypeFilter</code> : array (optional) <div class="sub-desc">Object types that will be returned.</div></li>
|
||||
* <li><code> filter</code> : array (optional) <div class="sub-desc">Attributes that will be returned.</div></li>
|
||||
* <li><code> inFolderId</code> : boolean (optional) <div class="sub-desc">This indicates whether or not a candidate object is a child-object of the folder object identified by the given inFolderId (objectId).</div></li>
|
||||
* <li><code> orderBy</code> : array (optional) <div class="sub-desc">ex. [{lastModificationDate:’DESC’, name:’ASC’}]</div></li>
|
||||
* <li><code> maxItems</code> : Integer (optional) <div class="sub-desc">number items to return as result</div></li>
|
||||
* <li><code> skipCount</code> : Integer (optional) <div class="sub-desc">This is tricky in a merged multi repository scenario</div></li>
|
||||
* <li><code> renditionFilter</code> : array (optional) <div class="sub-desc">Instead of termlist an array of kind or mimetype is expected. If null or array.length == 0 all renditions are returned. See http://docs.oasis-open.org/cmis/CMIS/v1.0/cd04/cmis-spec-v1.0.html#_Ref237323310 for renditionFilter</div></li>
|
||||
* </ul></div>
|
||||
* @param {function} callback this method must be called with all result items
|
||||
*/
|
||||
getChildren: null,
|
||||
/*
|
||||
getChildren: function( params, callback ) {
|
||||
if (typeof callback === 'function') {
|
||||
callback([]);
|
||||
}
|
||||
},
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make the given jQuery object (representing an object marked as object of this type)
|
||||
* clean. All attributes needed for handling should be removed.
|
||||
*
|
||||
<pre><code>
|
||||
Aloha.Repositories.myRepository.makeClean = function (obj) {
|
||||
obj.removeAttr('data-myRepository-name');
|
||||
};
|
||||
</code></pre>
|
||||
* @param {jQuery} obj jQuery object to make clean
|
||||
* @return void
|
||||
*/
|
||||
makeClean: function (obj) {},
|
||||
|
||||
/**
|
||||
* This method will be called when a user chooses an item from a repository and wants
|
||||
* to insert this item in his content.
|
||||
* Mark or modify an object as needed by that repository for handling, processing or identification.
|
||||
* Objects can be any DOM object as A, SPAN, ABBR, etc. or
|
||||
* special objects such as aloha-aloha_block elements.
|
||||
* (see http://dev.w3.org/html5/spec/elements.html#embedding-custom-non-visible-data)
|
||||
*
|
||||
<pre><code>
|
||||
Aloha.Repositories.myRepository.markObject = function (obj, resourceItem) {
|
||||
obj.attr('data-myRepository-name').text(resourceItem.name);
|
||||
};
|
||||
</code></pre>
|
||||
*
|
||||
*
|
||||
* @param obj jQuery target object to which the repositoryItem will be applied
|
||||
* @param repositoryItem The selected item. A class constructed from Document or Folder.
|
||||
* @return void
|
||||
*/
|
||||
markObject: function (obj, repositoryItem) {},
|
||||
|
||||
/**
|
||||
* Set a template for rendering objects of this repository
|
||||
* @param {String} template
|
||||
* @return void
|
||||
* @method
|
||||
*/
|
||||
setTemplate: function (template) {
|
||||
if (template) {
|
||||
this.template = template;
|
||||
} else {
|
||||
this.template = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether the repository has a template
|
||||
* @return {boolean} true when the repository has a template, false if not
|
||||
* @method
|
||||
*/
|
||||
hasTemplate: function () {
|
||||
return this.template ? true : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the parsed template
|
||||
* @return {Object} parsed template
|
||||
* @method
|
||||
*/
|
||||
getTemplate: function () {
|
||||
return this.template;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the repositoryItem with given id
|
||||
* @param itemId {String} id of the repository item to fetch
|
||||
* @param callback {function} callback function
|
||||
* @return {Aloha.Repository.Object} item with given id
|
||||
*/
|
||||
getObjectById: function (itemId, callback) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// expose the AbstractRepository
|
||||
Aloha.AbstractRepository = AbstractRepository;
|
||||
|
||||
return AbstractRepository;
|
||||
});
|
742
media/aloha-0.22.7/lib/aloha/repositorymanager.js
Executable file
@@ -0,0 +1,742 @@
|
||||
/* repositorymanager.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'util/class',
|
||||
'aloha/core',
|
||||
'aloha/console',
|
||||
'aloha/repositoryobjects' // Provides Aloha.RepositoryFolder
|
||||
], function (
|
||||
$,
|
||||
Class,
|
||||
Aloha,
|
||||
Console,
|
||||
__unused__
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Given an input set, returns a new set which is a range of the input set
|
||||
* that maps to the given predicate.
|
||||
*
|
||||
* Prefers native Array.prototype.filter() where available (after JavaScript
|
||||
* 1.6).
|
||||
*
|
||||
* @param {Array} domain
|
||||
* @param {function:boolean} predicate
|
||||
* @return {Array} Sub set of domain
|
||||
*/
|
||||
var filter = (function (native) {
|
||||
return (native
|
||||
? function (domain, predicate) {
|
||||
return domain.filter(predicate);
|
||||
}
|
||||
: function (domain, predicate) {
|
||||
var codomain = [];
|
||||
var i;
|
||||
for (i = 0; i < domain.length; i++) {
|
||||
if (predicate(domain[i])) {
|
||||
codomain.push(domain[i]);
|
||||
}
|
||||
}
|
||||
return codomain;
|
||||
}
|
||||
);
|
||||
}('filter' in Array.prototype));
|
||||
|
||||
/**
|
||||
* Bundles results, and meta information in preparation for the JSON Reader.
|
||||
*
|
||||
* Used with query().
|
||||
*
|
||||
* @param {Array.<Document|Folder>} items Results, collected from all
|
||||
* repositories.
|
||||
* @param {object<string, number>} meta Optional object containing metainfo.
|
||||
* @return {object} Result object.
|
||||
*/
|
||||
function bundle(items, meta) {
|
||||
var result = {
|
||||
items: items,
|
||||
results: items.length
|
||||
};
|
||||
if (meta) {
|
||||
result.numItems = meta.numItems;
|
||||
result.hasMoreItems = meta.hasMoreItems;
|
||||
result.timeout = meta.timeout;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes all the results we have collected to the client through the
|
||||
* callback it specified.
|
||||
*
|
||||
* TODO: Implement sorting based on repository specification sort
|
||||
* items by weight.
|
||||
* items.sort(function (a, b) {
|
||||
* return (b.weight || 0) - (a.weight || 0);
|
||||
* });
|
||||
*
|
||||
* @param {function} callback Callback specified by client when invoking
|
||||
* the query method.
|
||||
* @param {Array.<Document|Folder>|object<string, number>} results
|
||||
*/
|
||||
function report(callback, results) {
|
||||
callback(results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicates; used to filter lists of repositories based on whether they
|
||||
* implement a method or not.
|
||||
*
|
||||
* @type {object<string, function(Repository):boolean}
|
||||
*/
|
||||
var repositoryFilters = {
|
||||
query: function (repository) {
|
||||
return typeof repository.query === 'function';
|
||||
},
|
||||
getChildren: function (repository) {
|
||||
return typeof repository.getChildren === 'function';
|
||||
},
|
||||
getSelectedFolder: function (repository) {
|
||||
return typeof repository.getSelectedFolder === 'function';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Repository Manager.
|
||||
*
|
||||
* @namespace Aloha
|
||||
* @class RepositoryManager
|
||||
* @singleton
|
||||
*/
|
||||
var RepositoryManager = Class.extend({
|
||||
|
||||
repositories: [],
|
||||
|
||||
settings: (Aloha.settings && Aloha.settings.repositories) || {},
|
||||
|
||||
initialized: false,
|
||||
|
||||
/**
|
||||
* Initializes all registered repositories.
|
||||
*
|
||||
* ???
|
||||
* |
|
||||
* v
|
||||
*
|
||||
* Warning: testing has shown that repositories are maybe not loaded yet
|
||||
* (found that case in IE7), so don't rely on that in this init
|
||||
* function.
|
||||
*
|
||||
* ^
|
||||
* |
|
||||
* !!!
|
||||
*/
|
||||
init: function () {
|
||||
var manager = this;
|
||||
if (typeof manager.settings.timeout === 'undefined') {
|
||||
manager.settings.timeout = 5000;
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < manager.repositories.length; i++) {
|
||||
manager.initRepository(manager.repositories[i]);
|
||||
}
|
||||
manager.initialized = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a Repository.
|
||||
*
|
||||
* If the repositorie is registered after the Repository Manager is
|
||||
* initialized it will be automatically initialized.
|
||||
*
|
||||
* @param {Repository} repository Repository to register.
|
||||
*/
|
||||
register: function (repository) {
|
||||
var manager = this;
|
||||
if (!manager.getRepository(repository.repositoryId)) {
|
||||
manager.repositories.push(repository);
|
||||
if (manager.initialized) {
|
||||
manager.initRepository(repository);
|
||||
}
|
||||
} else {
|
||||
Console.warn(manager, 'A repository with name "'
|
||||
+ repository.repositoryId
|
||||
+ '" already registerd. Ignoring this.');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes a repository.
|
||||
*
|
||||
* @param {Repository} repository Repository to initialize.
|
||||
*/
|
||||
initRepository: function (repository) {
|
||||
var manager = this;
|
||||
if (!repository.settings) {
|
||||
repository.settings = {};
|
||||
}
|
||||
if (manager.settings[repository.repositoryId]) {
|
||||
$.extend(repository.settings,
|
||||
manager.settings[repository.repositoryId]);
|
||||
}
|
||||
repository.init();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the repository identified by repositoryId.
|
||||
*
|
||||
* @param {String} id Id of repository to retrieve.
|
||||
* @return {Repository|null} Repository or null if none with the given
|
||||
* id is found.
|
||||
*/
|
||||
getRepository: function (id) {
|
||||
var manager = this;
|
||||
var i;
|
||||
for (i = 0; i < manager.repositories.length; i++) {
|
||||
if (manager.repositories[i].repositoryId === id) {
|
||||
return manager.repositories[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches all repositories for repositoryObjects matching query and
|
||||
* repositoryObjectType.
|
||||
*
|
||||
* <pre><code>
|
||||
* // Example:
|
||||
* var params = {
|
||||
* queryString: 'hello',
|
||||
* objectTypeFilter: ['website'],
|
||||
* filter: null,
|
||||
* inFolderId: null,
|
||||
* orderBy: null,
|
||||
* maxItems: null,
|
||||
* skipCount: null,
|
||||
* renditionFilter: null,
|
||||
* repositoryId: null
|
||||
* };
|
||||
* Aloha.RepositoryManager.query(params, function (items) {
|
||||
* Console.log(items);
|
||||
* });
|
||||
* </code></pre>
|
||||
*
|
||||
* @param {object<string, mixed>} params
|
||||
*
|
||||
* queryString: String The query string for full text
|
||||
* search.
|
||||
* objectTypeFilter: Array (optional) Object types to be retrieved.
|
||||
* filter: Array (optional) Attributes that will be
|
||||
* included.
|
||||
* inFolderId: boolean (optional) Whether or not a candidate
|
||||
* object is a child-object of the
|
||||
* folder object identified by the
|
||||
* given inFolderId (objectId).
|
||||
* inTreeId: boolean (optional) This indicates whether or
|
||||
* not a candidate object is a
|
||||
* descendant-object of the folder
|
||||
* object identified by the given
|
||||
* inTreeId (objectId).
|
||||
* orderBy: Array (optional) example: [{
|
||||
* lastModificationDate: 'DESC',
|
||||
* name: 'ASC'
|
||||
* }]
|
||||
* maxItems: number (optional) Number of items to include in
|
||||
* result set.
|
||||
* skipCount: number (optional) This is tricky in a merged
|
||||
* multi repository scenario.
|
||||
* renditionFilter: Array (optional) Instead of termlist, an
|
||||
* array of kind or mimetype is
|
||||
* expected. If null or an empty
|
||||
* set, then all renditions are
|
||||
* returned. See
|
||||
* http://docs.oasis-open.org/cmis/CMIS/v1.0/cd04/cmis-spec-v1.0.html#_Ref237323310
|
||||
* for renditionFilter.
|
||||
*
|
||||
* @param {function(Document|Folder)} callback Function to be invoked
|
||||
* after the repository
|
||||
* manager has finished
|
||||
* querying all
|
||||
* repositories.
|
||||
*/
|
||||
query: function (params, callback) {
|
||||
var manager = this;
|
||||
|
||||
var i;
|
||||
|
||||
// The merged results, collected from repository responses.
|
||||
var results = [];
|
||||
|
||||
// The merged metainfo, collected from repository responses.
|
||||
var allmetainfo = {
|
||||
numItems: 0,
|
||||
hasMoreItems: false
|
||||
};
|
||||
|
||||
// A counting semaphore (working in reverse, ie: 0 means free).
|
||||
var numOpenQueries;
|
||||
|
||||
// Unless the calling client specifies otherwise, the manager will
|
||||
// wait a maximum of 5 seconds for all repositories to be queried
|
||||
// and respond. 5 seconds is deemed to be the reasonable time to
|
||||
// wait when querying the repository manager in the context of
|
||||
// something like autocomplete.
|
||||
var timeout = (params.timeout && parseInt(params.timeout, 10))
|
||||
|| manager.settings.timeout;
|
||||
|
||||
// When this timer times-out, whatever has been collected in
|
||||
// `results' will be returned to the calling client and all further
|
||||
// processing aborted.
|
||||
var timer = window.setTimeout(function () {
|
||||
// Store in metainfo that a timeout occurred.
|
||||
allmetainfo = allmetainfo || {};
|
||||
allmetainfo.timeout = true;
|
||||
|
||||
if (numOpenQueries > 0) {
|
||||
Console.warn(manager, numOpenQueries
|
||||
+ ' repositories did not return before the '
|
||||
+ 'configured timeout of ' + timeout + 'ms.');
|
||||
numOpenQueries = 0;
|
||||
}
|
||||
clearTimeout(timer);
|
||||
report(callback, bundle(results, allmetainfo));
|
||||
}, timeout);
|
||||
|
||||
/**
|
||||
* Invoked by each repository when it wants to present its results
|
||||
* to the manager.
|
||||
*
|
||||
* Collects the results from each repository, and decrements the
|
||||
* numOpenQueries semaphore to indicate that there is one less
|
||||
* repository for which the manager is waiting for a reponse.
|
||||
*
|
||||
* If a repository invokes this callback after all openCallbacks
|
||||
* have been closed (ie: numOpenQueries == 0), then the repository
|
||||
* was too late ("missed the ship"), and will be ignored.
|
||||
*
|
||||
* If numOpenQueries decrements to 0 during this call, it means that
|
||||
* the the manager is ready to report the results back to the client
|
||||
* through the report() method.
|
||||
*
|
||||
* @param {Array.<Document|Folder>} items Results returned by the
|
||||
* repository.
|
||||
* @param {object<string, number>} metainfo Optional Metainfo
|
||||
* returned by some
|
||||
* repositories.
|
||||
*/
|
||||
var process = function (items, metainfo) {
|
||||
var repository = this;
|
||||
|
||||
if (0 === numOpenQueries) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (items && items.length) {
|
||||
|
||||
// Because some negligent repository implementations do not
|
||||
// set repositoryId properly.
|
||||
if (!items[0].repositoryId) {
|
||||
var id = repository.repositoryId;
|
||||
var i;
|
||||
for (i = 0; i < items.length; i++) {
|
||||
items[i].repositoryId = id;
|
||||
}
|
||||
}
|
||||
|
||||
$.merge(results, items);
|
||||
}
|
||||
|
||||
if (metainfo && allmetainfo) {
|
||||
allmetainfo.numItems =
|
||||
($.isNumeric(metainfo.numItems) &&
|
||||
$.isNumeric(allmetainfo.numItems))
|
||||
? allmetainfo.numItems + metainfo.numItems
|
||||
: undefined;
|
||||
|
||||
allmetainfo.hasMoreItems =
|
||||
(typeof metainfo.hasMoreItems === 'boolean' &&
|
||||
typeof allmetainfo.hasMoreItems === 'boolean')
|
||||
? allmetainfo.hasMoreItems || metainfo.hasMoreItems
|
||||
: undefined;
|
||||
|
||||
if (metainfo.timeout) {
|
||||
allmetainfo.timeout = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
// Because if even one repository does not return metainfo,
|
||||
// so we have no aggregated metainfo at all.
|
||||
allmetainfo = undefined;
|
||||
}
|
||||
|
||||
Console.debug(manager, 'The repository '
|
||||
+ repository.repositoryId + 'returned with '
|
||||
+ items.length + ' results.');
|
||||
|
||||
// TODO: how to return the metainfo here?
|
||||
if (0 === --numOpenQueries) {
|
||||
clearTimeout(timer);
|
||||
report(callback, bundle(results, allmetainfo));
|
||||
}
|
||||
};
|
||||
|
||||
var repositories = params.repositoryId
|
||||
? [manager.getRepository(params.repositoryId)]
|
||||
: manager.repositories;
|
||||
|
||||
var queue = filter(repositories, repositoryFilters.query);
|
||||
|
||||
// If none of the repositories implemented the query method, then
|
||||
// don't wait for the timeout, simply report to the client.
|
||||
if (0 === queue.length) {
|
||||
clearTimeout(timer);
|
||||
report(callback, bundle(results, allmetainfo));
|
||||
return;
|
||||
}
|
||||
|
||||
var makeProcess = function (repository) {
|
||||
return function () {
|
||||
process.apply(repository, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
numOpenQueries = queue.length;
|
||||
|
||||
for (i = 0; i < queue.length; i++) {
|
||||
queue[i].query(params, makeProcess(queue[i]));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves children items.
|
||||
*
|
||||
* @param {object<string,mixed>} params Object with properties.
|
||||
*
|
||||
* objectTypeFilter: Array (optional) Object types to be retrieved.
|
||||
* filter: Array (optional) Attributes to be retrieved.
|
||||
* inFolderId: boolean (optional) This indicates whether or not
|
||||
* a candidate object is a
|
||||
* child-object of the folder
|
||||
* object identified by the given
|
||||
* inFolderId (objectId).
|
||||
* orderBy: Array (optional) example: [{
|
||||
* lastModificationDate: 'DESC',
|
||||
* name: 'ASC'
|
||||
* }]
|
||||
* maxItems: number (optional) number Items to return as a result.
|
||||
* skipCount: number (optional) This is tricky in a merged
|
||||
* multi repository scenario.
|
||||
* renditionFilter: Array (optional) Instead of termlist an Array
|
||||
* of kind or mimetype is
|
||||
* expected. If null or
|
||||
* Array.length == 0 all
|
||||
* renditions are returned. See
|
||||
* http://docs.oasis-open.org/cmis/CMIS/v1.0/cd04/cmis-spec-v1.0.html#_Ref237323310
|
||||
* for renditionFilter.
|
||||
*
|
||||
* @param {function(Document|Folder)} callback Function to be invoked
|
||||
* after the repository
|
||||
* manager has finished
|
||||
* querying all
|
||||
* repositories.
|
||||
*/
|
||||
getChildren: function (params, callback) {
|
||||
var manager = this;
|
||||
|
||||
var i;
|
||||
|
||||
// The marged results, collected from repository responses.
|
||||
var results = [];
|
||||
|
||||
// A counting semaphore (working in reverse, ie: 0 means free).
|
||||
var numOpenQueries = 0;
|
||||
|
||||
var timeout = (params.timeout && parseInt(params.timeout, 10))
|
||||
|| manager.settings.timeout;
|
||||
|
||||
var timer = window.setTimeout(function () {
|
||||
if (numOpenQueries > 0) {
|
||||
Console.warn(manager, numOpenQueries
|
||||
+ ' repositories did not respond before the '
|
||||
+ 'configured timeout of ' + timeout + 'ms.');
|
||||
numOpenQueries = 0;
|
||||
}
|
||||
clearTimeout(timer);
|
||||
report(callback, results);
|
||||
}, timeout);
|
||||
|
||||
var process = function (items) {
|
||||
if (0 === numOpenQueries) {
|
||||
return;
|
||||
}
|
||||
if (items) {
|
||||
$.merge(results, items);
|
||||
}
|
||||
if (0 === --numOpenQueries) {
|
||||
clearTimeout(timer);
|
||||
report(callback, results);
|
||||
}
|
||||
};
|
||||
|
||||
var repositories = params.repositoryId
|
||||
? [manager.getRepository(params.repositoryId)]
|
||||
: manager.repositories;
|
||||
|
||||
if (params.repositoryFilter && params.repositoryFilter.length) {
|
||||
repositories = filter(repositories, function (repository) {
|
||||
return -1 < $.inArray(repository.repositoryId,
|
||||
params.repositoryFilter);
|
||||
});
|
||||
}
|
||||
|
||||
// If the inFolderId is the default id of 'aloha', then return all
|
||||
// registered repositories as the result set.
|
||||
if ('aloha' === params.inFolderId) {
|
||||
var hasRepoFilter = params.repositoryFilter
|
||||
&& 0 < params.repositoryFilter.length;
|
||||
|
||||
for (i = 0; i < repositories.length; i++) {
|
||||
results.push(new Aloha.RepositoryFolder({
|
||||
id: repositories[i].repositoryId,
|
||||
name: repositories[i].repositoryName,
|
||||
repositoryId: repositories[i].repositoryId,
|
||||
type: 'repository',
|
||||
hasMoreItems: true
|
||||
}));
|
||||
}
|
||||
|
||||
clearTimeout(timer);
|
||||
report(callback, results);
|
||||
return;
|
||||
}
|
||||
|
||||
var queue = filter(repositories, repositoryFilters.getChildren);
|
||||
|
||||
if (0 === queue.length) {
|
||||
clearTimeout(timer);
|
||||
report(callback, results);
|
||||
return;
|
||||
}
|
||||
|
||||
numOpenQueries = queue.length;
|
||||
|
||||
for (i = 0; i < queue.length; i++) {
|
||||
queue[i].getChildren(params, process);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @fixme: Not tested, but the code for this function does not seem to
|
||||
* compute repository.makeClean will be undefined
|
||||
*
|
||||
* @todo: Rewrite this function header comment so that is clearer
|
||||
*
|
||||
* Pass an object, which represents an marked repository to corresponding
|
||||
* repository, so that it can make the content clean (prepare for saving)
|
||||
*
|
||||
* @param {jQuery} obj - representing an editable
|
||||
* @return void
|
||||
*/
|
||||
makeClean: function (obj) {
|
||||
// iterate through all registered repositories
|
||||
var that = this,
|
||||
repository = {},
|
||||
i = 0,
|
||||
j = that.repositories.length;
|
||||
|
||||
// find all repository tags
|
||||
obj.find('[data-gentics-aloha-repository=' + this.prefix + ']').each(function () {
|
||||
while (i < j) {
|
||||
repository.makeClean(obj);
|
||||
i += 1;
|
||||
}
|
||||
Console.debug(that, 'Passing contents of HTML Element with id { ' + this.attr('id') + ' } for cleaning to repository { ' + repository.repositoryId + ' }');
|
||||
repository.makeClean(this);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Marks an object as repository of this type and with this item.id.
|
||||
* Objects can be any DOM objects as A, SPAN, ABBR, etc. or
|
||||
* special objects such as aloha-aloha_block elements.
|
||||
*
|
||||
* Marks the target obj with two private attributes:
|
||||
* (see http://dev.w3.org/html5/spec/elements.html#embedding-custom-non-visible-data)
|
||||
* - data-gentics-aloha-repository: stores the repositoryId
|
||||
* - data-gentics-aloha-object-id: stores the object.id
|
||||
*
|
||||
* @param {HTMLElement} obj DOM object to mark.
|
||||
* @param {Aloha.Repository.Object} item Item which is applied to obj,
|
||||
* if set to null, the
|
||||
* "data-GENTICS-..." attributes
|
||||
* are removed.
|
||||
*/
|
||||
markObject: function (obj, item) {
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
var manager = this;
|
||||
|
||||
if (item) {
|
||||
var repository = manager.getRepository(item.repositoryId);
|
||||
if (repository) {
|
||||
$(obj).attr({
|
||||
'data-gentics-aloha-repository': item.repositoryId,
|
||||
'data-gentics-aloha-object-id': item.id
|
||||
});
|
||||
repository.markObject(obj, item);
|
||||
} else {
|
||||
Console.error(manager, 'Trying to apply a repository "'
|
||||
+ item.name
|
||||
+ '" to an object, but item has no repositoryId.');
|
||||
}
|
||||
} else {
|
||||
$(obj).removeAttr('data-gentics-aloha-repository')
|
||||
.removeAttr('data-gentics-aloha-object-id');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the object for which the given DOM object is marked from the
|
||||
* repository.
|
||||
*
|
||||
* Will initialize the item cache (per repository) if not already done.
|
||||
*
|
||||
* @param {HTMLElement} element DOM object which probably is marked.
|
||||
* @param {function} callback
|
||||
*/
|
||||
getObject: function (element, callback) {
|
||||
var manager = this;
|
||||
var $element = $(element);
|
||||
var itemId = $element.attr('data-gentics-aloha-object-id');
|
||||
var repositoryId = $element.attr('data-gentics-aloha-repository');
|
||||
var repository = manager.getRepository(repositoryId);
|
||||
|
||||
if (repository && itemId) {
|
||||
if (!manager.itemCache) {
|
||||
manager.itemCache = [];
|
||||
}
|
||||
|
||||
var cache = manager.itemCache[repositoryId];
|
||||
if (!cache) {
|
||||
cache = manager.itemCache[repositoryId] = [];
|
||||
}
|
||||
|
||||
if (cache[itemId]) {
|
||||
callback([cache[itemId]]);
|
||||
} else {
|
||||
repository.getObjectById(itemId, function (items) {
|
||||
cache[itemId] = items[0];
|
||||
callback(items);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark a folder as opened.
|
||||
*
|
||||
* Called by a repository client (eg: repository browser) when a folder
|
||||
* is opened.
|
||||
*
|
||||
* @param {object|Folder} folder Object with property repositoryId.
|
||||
*/
|
||||
folderOpened: function (folder) {
|
||||
var repository = this.getRepository(folder.repositoryId);
|
||||
if (typeof repository.folderOpened === 'function') {
|
||||
repository.folderOpened(folder);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark a folder as closed.
|
||||
*
|
||||
* Called by a repository client (eg: repository browser) when a folder
|
||||
* is closed.
|
||||
*
|
||||
* @param {object|Folder} folder Object with property repositoryId.
|
||||
*/
|
||||
folderClosed: function (folder) {
|
||||
var repository = this.getRepository(folder.repositoryId);
|
||||
if (typeof repository.folderClosed === 'function') {
|
||||
repository.folderClosed(folder);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark a folder as selected.
|
||||
*
|
||||
* Called by a repository client (eg: repository browser) when a folder
|
||||
* is selected.
|
||||
*
|
||||
* @param {object|Folder} folder Object with property repositoryId.
|
||||
*/
|
||||
folderSelected: function (folder) {
|
||||
var repository = this.getRepository(folder.repositoryId);
|
||||
if (typeof repository.folderSelected === 'function') {
|
||||
repository.folderSelected(folder);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the selected folder.
|
||||
*
|
||||
* @return {Folder} Selected folder or null if it cannot be found.
|
||||
*/
|
||||
getSelectedFolder: function () {
|
||||
var repositories = filter(this.repositories,
|
||||
repositoryFilters.getSelectedFolder);
|
||||
var i;
|
||||
var selected;
|
||||
for (i = 0; i < repositories.length; i++) {
|
||||
selected = repositories[i].getSelectedFolder();
|
||||
if (selected) {
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Human readable representation of repository manager.
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
toString: function () {
|
||||
return 'repositorymanager';
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Aloha.RepositoryManager = new RepositoryManager();
|
||||
|
||||
return Aloha.RepositoryManager;
|
||||
});
|
162
media/aloha-0.22.7/lib/aloha/repositoryobjects.js
Executable file
@@ -0,0 +1,162 @@
|
||||
/* repositoryobjects.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'aloha/core',
|
||||
'util/class'
|
||||
], function (
|
||||
Aloha,
|
||||
Class
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
var GENTICS = window.GENTICS;
|
||||
|
||||
Aloha.RepositoryObject = function () {};
|
||||
|
||||
/**
|
||||
* @namespace Aloha.Repository
|
||||
* @class Document
|
||||
* @constructor
|
||||
*
|
||||
* Abstract Document suitable for most Objects.<br /><br />
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
<pre><code>
|
||||
var item = new Aloha.Repository.Document({
|
||||
id: 1,
|
||||
repositoryId: 'myrepository',
|
||||
name: 'Aloha Editor - The HTML5 Editor',
|
||||
type: 'website',
|
||||
url:'http://aloha-editor.com',
|
||||
});
|
||||
</code></pre>
|
||||
*
|
||||
* @param {Object} properties An object with the data.
|
||||
* <div class="mdetail-params"><ul>
|
||||
* <li><code>id</code> : String <div class="sub-desc">Unique identifier</div></li>
|
||||
* <li><code>repositoryId</code> : String <div class="sub-desc">Unique repository identifier</div></li>
|
||||
* <li><code>name</code> : String <div class="sub-desc">Name of the object. This name is used to display</div></li>
|
||||
* <li><code>type</code> : String <div class="sub-desc">The specific object type</div></li>
|
||||
* <li><code>partentId</code> : String (optional) <div class="sub-desc"></div></li>
|
||||
* <li><code>mimetype</code> : String (optional) <div class="sub-desc">MIME type of the Content Stream</div></li>
|
||||
* <li><code>filename</code> : String (optional) <div class="sub-desc">File name of the Content Stream</div></li>
|
||||
* <li><code>length</code> : String (optional) <div class="sub-desc">Length of the content stream (in bytes)</div></li>
|
||||
* <li><code>url</code> : String (optional) <div class="sub-desc">URL of the content stream</div></li>
|
||||
* <li><code>renditions</code> : Array (optional) <div class="sub-desc">Array of different renditions of this object</div></li>
|
||||
* <li><code>localName</code> : String (optional) <div class="sub-desc">Name of the object. This name is used internally</div></li>
|
||||
* <li><code>createdBy</code> : String (optional) <div class="sub-desc">User who created the object</div></li>
|
||||
* <li><code>creationDate</code> : Date (optional) <div class="sub-desc">DateTime when the object was created</div></li>
|
||||
* <li><code>lastModifiedBy</code> : String (optional) <div class="sub-desc">User who last modified the object</div></li>
|
||||
* <li><code>lastModificationDate</code> : Date (optional) <div class="sub-desc">DateTime when the object was last modified</div></li>
|
||||
* </ul></div>
|
||||
*
|
||||
*/
|
||||
Aloha.RepositoryDocument = Class.extend({
|
||||
_constructor: function (properties) {
|
||||
|
||||
var p = properties;
|
||||
|
||||
this.type = 'document';
|
||||
|
||||
// Basic error checking for MUST attributes
|
||||
if (!p.id || !p.name || !p.repositoryId) {
|
||||
// Aloha.Log.error(this, "No valid Aloha Object. Missing MUST property");
|
||||
return;
|
||||
}
|
||||
|
||||
GENTICS.Utils.applyProperties(this, properties);
|
||||
|
||||
this.baseType = 'document';
|
||||
}
|
||||
// /**
|
||||
// * Not implemented method to generate this JS API doc correctly.
|
||||
// */
|
||||
// ,empty = function() }
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @namespace Aloha.Repository
|
||||
* @class Folder
|
||||
* @constructor
|
||||
* Abstract Folder suitable for most strucural Objects.<br /><br />
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
<pre><code>
|
||||
var item = new Aloha.Repository.Folder({
|
||||
id: 2,
|
||||
repositoryId: 'myrepository',
|
||||
name: 'images',
|
||||
type: 'directory',
|
||||
parentId:'/www'
|
||||
});
|
||||
</code></pre>
|
||||
* @param {Object} properties An object with the data.
|
||||
* <div class="mdetail-params"><ul>
|
||||
* <li><code>id</code> : String <div class="sub-desc">Unique identifier</div></li>
|
||||
* <li><code>repositoryId</code> : String <div class="sub-desc">Unique repository identifier</div></li>
|
||||
* <li><code>name</code> : String <div class="sub-desc">Name of the object. This name is used to display</div></li>
|
||||
* <li><code>type</code> : String <div class="sub-desc">The specific object type</div></li>
|
||||
* <li><code>partentId</code> : String (optional) <div class="sub-desc"></div></li>
|
||||
* <li><code>localName</code> : String (optional) <div class="sub-desc">Name of the object. This name is used internally</div></li>
|
||||
* <li><code>createdBy</code> : String (optional) <div class="sub-desc">User who created the object</div></li>
|
||||
* <li><code>creationDate</code> : Date (optional) <div class="sub-desc">DateTime when the object was created</div></li>
|
||||
* <li><code>lastModifiedBy</code> : String (optional) <div class="sub-desc">User who last modified the object</div></li>
|
||||
* <li><code>lastModificationDate</code> : Date (optional) <div class="sub-desc">DateTime when the object was last modified</div></li>
|
||||
* </ul></div>
|
||||
*
|
||||
*/
|
||||
Aloha.RepositoryFolder = Class.extend({
|
||||
|
||||
_constructor: function (properties) {
|
||||
|
||||
var p = properties;
|
||||
|
||||
this.type = 'folder';
|
||||
|
||||
// Basic error checking for MUST attributes
|
||||
if (!p.id || !p.name || !p.repositoryId) {
|
||||
// Aloha.Log.error(this, "No valid Aloha Object. Missing MUST property");
|
||||
return;
|
||||
}
|
||||
|
||||
GENTICS.Utils.applyProperties(this, properties);
|
||||
|
||||
this.baseType = 'folder';
|
||||
|
||||
}
|
||||
// /**
|
||||
// * Not implemented method to generate this JS API doc correctly.
|
||||
// */
|
||||
// ,empty = function() {};
|
||||
|
||||
});
|
||||
});
|
2402
media/aloha-0.22.7/lib/aloha/selection.js
Normal file
1045
media/aloha-0.22.7/lib/aloha/sidebar.js
Executable file
455
media/aloha-0.22.7/lib/css.js
Normal file
@@ -0,0 +1,455 @@
|
||||
/** MIT License (c) copyright B Cavalier & J Hann */
|
||||
|
||||
/**
|
||||
* curl css! plugin
|
||||
*
|
||||
* Licensed under the MIT License at:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
*/
|
||||
|
||||
(function (global) {
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* AMD css! plugin
|
||||
* This plugin will load and wait for css files. This could be handy when
|
||||
* loading css files as part of a layer or as a way to apply a run-time theme.
|
||||
* Most browsers do not support the load event handler of the link element.
|
||||
* Therefore, we have to use other means to detect when a css file loads.
|
||||
* (The HTML5 spec states that the LINK element should have a load event, but
|
||||
* not even Chrome 8 or FF4b7 have it, yet.
|
||||
* http://www.w3.org/TR/html5/semantics.html#the-link-element)
|
||||
*
|
||||
* This plugin tries to use the load event and a universal work-around when
|
||||
* it is invoked the first time. If the load event works, it is used on
|
||||
* every successive load. Therefore, browsers that support the load event will
|
||||
* just work (i.e. no need for hacks!). FYI, Feature-detecting the load
|
||||
* event is tricky since most browsers have a non-functional onload property.
|
||||
*
|
||||
* The universal work-around watches a stylesheet until its rules are
|
||||
* available (not null or undefined). There are nuances, of course, between
|
||||
* the various browsers. The isLinkReady function accounts for these.
|
||||
*
|
||||
* Note: it appears that all browsers load @import'ed stylesheets before
|
||||
* fully processing the rest of the importing stylesheet. Therefore, we
|
||||
* don't need to find and wait for any @import rules explicitly.
|
||||
*
|
||||
* Note #2: for Opera compatibility, stylesheets must have at least one rule.
|
||||
* AFAIK, there's no way to tell the difference between an empty sheet and
|
||||
* one that isn't finished loading in Opera (XD or same-domain).
|
||||
*
|
||||
* Options:
|
||||
* !nowait - does not wait for the stylesheet to be parsed, just loads it
|
||||
*
|
||||
* Global configuration options:
|
||||
*
|
||||
* cssDeferLoad: Boolean. You can also instruct this plugin to not wait
|
||||
* for css resources. They'll get loaded asap, but other code won't wait
|
||||
* for them. This is just like using the !nowait option on every css file.
|
||||
*
|
||||
* cssWatchPeriod: if direct load-detection techniques fail, this option
|
||||
* determines the msec to wait between brute-force checks for rules. The
|
||||
* default is 50 msec.
|
||||
*
|
||||
* You may specify an alternate file extension:
|
||||
* require('css!myproj/component.less') // --> myproj/component.less
|
||||
* require('css!myproj/component.scss') // --> myproj/component.scss
|
||||
*
|
||||
* When using alternative file extensions, be sure to serve the files from
|
||||
* the server with the correct mime type (text/css) or some browsers won't
|
||||
* parse them, causing an error in the plugin.
|
||||
*
|
||||
* usage:
|
||||
* require(['css!myproj/comp']); // load and wait for myproj/comp.css
|
||||
* define(['css!some/folder/file'], {}); // wait for some/folder/file.css
|
||||
* require(['css!myWidget!nowait']);
|
||||
*
|
||||
* Tested in:
|
||||
* Firefox 1.5, 2.0, 3.0, 3.5, 3.6, and 4.0b6
|
||||
* Safari 3.0.4, 3.2.1, 5.0
|
||||
* Chrome 7 (8+ is partly b0rked)
|
||||
* Opera 9.52, 10.63, and Opera 11.00
|
||||
* IE 6, 7, and 8
|
||||
* Netscape 7.2 (WTF? SRSLY!)
|
||||
* Does not work in Safari 2.x :(
|
||||
* In Chrome 8+, there's no way to wait for cross-domain (XD) stylesheets.
|
||||
* See comments in the code below.
|
||||
* TODO: figure out how to be forward-compatible when browsers support HTML5's
|
||||
* load handler without breaking IE and Opera
|
||||
*/
|
||||
|
||||
|
||||
var
|
||||
// compressibility shortcuts
|
||||
onreadystatechange = 'onreadystatechange',
|
||||
onload = 'onload',
|
||||
createElement = 'createElement',
|
||||
// failed is true if RequireJS threw an exception
|
||||
failed = false,
|
||||
undef,
|
||||
insertedSheets = {},
|
||||
features = {
|
||||
// true if the onload event handler works
|
||||
// "event-link-onload" : false
|
||||
},
|
||||
// this actually tests for absolute urls and root-relative urls
|
||||
// they're both non-relative
|
||||
nonRelUrlRe = /^\/|^[^:]*:\/\//,
|
||||
// Note: this will fail if there are parentheses in the url
|
||||
findUrlRx = /url\s*\(['"]?([^'"\)]*)['"]?\)/g,
|
||||
// doc will be undefined during a build
|
||||
doc = global.document,
|
||||
// find the head element and set it to it's standard property if nec.
|
||||
head,
|
||||
// collection of modules that have been written to the built file
|
||||
built = {};
|
||||
|
||||
if (doc) {
|
||||
head = doc.head || (doc.head = doc.getElementsByTagName('head')[0]);
|
||||
}
|
||||
|
||||
function has (feature) {
|
||||
return features[feature];
|
||||
}
|
||||
|
||||
/***** load-detection functions *****/
|
||||
|
||||
function loadHandler (params, cb) {
|
||||
// We're using 'readystatechange' because IE and Opera happily support both
|
||||
var link = params.link;
|
||||
link[onreadystatechange] = link[onload] = function () {
|
||||
if (!link.readyState || link.readyState == 'complete') {
|
||||
features["event-link-onload"] = true;
|
||||
cleanup(params);
|
||||
cb();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function nameWithExt (name, defaultExt) {
|
||||
return name.lastIndexOf('.') <= name.lastIndexOf('/') ?
|
||||
name + '.' + defaultExt : name;
|
||||
}
|
||||
|
||||
function parseSuffixes (name) {
|
||||
// creates a dual-structure: both an array and a hashmap
|
||||
// suffixes[0] is the actual name
|
||||
var parts = name.split('!'),
|
||||
suf, i = 1, pair;
|
||||
while ((suf = parts[i++])) { // double-parens to avoid jslint griping
|
||||
pair = suf.split('=', 2);
|
||||
parts[pair[0]] = pair.length == 2 ? pair[1] : true;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
var collectorSheet;
|
||||
function createLink (doc, optHref) {
|
||||
// detect if we need to avoid 31-sheet limit in IE (how to detect this for realz?)
|
||||
if (document.createStyleSheet) {
|
||||
if (!collectorSheet) {
|
||||
collectorSheet = document.createStyleSheet();
|
||||
}
|
||||
if (document.styleSheets.length >= 30) {
|
||||
moveLinksToCollector();
|
||||
}
|
||||
}
|
||||
var link = doc[createElement]('link');
|
||||
link.rel = "stylesheet";
|
||||
link.type = "text/css";
|
||||
link.setAttribute('_curl_movable', true);
|
||||
if (optHref) {
|
||||
link.href = optHref;
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
var testEl;
|
||||
function styleIsApplied () {
|
||||
// Chrome 8 hax0rs!
|
||||
// This is an ugly hack needed by Chrome 8+ which no longer waits for rules
|
||||
// to be applied to the document before exposing them to javascript.
|
||||
// Unfortunately, this routine will never fire for XD stylesheets since
|
||||
// Chrome will also throw an exception if attempting to access the rules
|
||||
// of an XD stylesheet. Therefore, there's no way to detect the load
|
||||
// event of XD stylesheets until Google fixes this, preferably with a
|
||||
// functional load event! As a work-around, use domReady() before
|
||||
// rendering widgets / components that need the css to be ready.
|
||||
if (!testEl) {
|
||||
testEl = doc[createElement]('div');
|
||||
testEl.id = '_cssx_load_test';
|
||||
head.appendChild(testEl);
|
||||
}
|
||||
return doc.defaultView.getComputedStyle(testEl, null).marginTop == '-5px';
|
||||
}
|
||||
|
||||
function isLinkReady (link) {
|
||||
// This routine is a bit fragile: browser vendors seem oblivious to
|
||||
// the need to know precisely when stylesheets load. Therefore, we need
|
||||
// to continually test beta browsers until they all support the LINK load
|
||||
// event like IE and Opera.
|
||||
var sheet, rules, ready = false;
|
||||
try {
|
||||
// webkit's and IE's sheet is null until the sheet is loaded
|
||||
sheet = link.sheet || link.styleSheet;
|
||||
// mozilla's sheet throws an exception if trying to access xd rules
|
||||
rules = sheet.cssRules || sheet.rules;
|
||||
// webkit's xd sheet returns rules == null
|
||||
// opera's sheet always returns rules, but length is zero until loaded
|
||||
// friggin IE doesn't count @import rules as rules, but IE should
|
||||
// never hit this routine anyways.
|
||||
ready = rules ?
|
||||
rules.length > 0 : // || (sheet.imports && sheet.imports.length > 0) :
|
||||
rules !== undef;
|
||||
// thanks, Chrome 8+, for this lovely hack. TODO: find a better way
|
||||
if (ready && {}.toString.call(window.chrome) == '[object Chrome]') {
|
||||
// fwiw, we'll never get this far if this is an XD stylesheet
|
||||
sheet.insertRule('#_cssx_load_test{margin-top:-5px;}', 0);
|
||||
ready = styleIsApplied();
|
||||
sheet.deleteRule(0);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// 1000 means FF loaded an xd stylesheet
|
||||
// other browsers just throw a security error here (IE uses the phrase 'Access is denied')
|
||||
ready = (ex.code == 1000) || (ex.message.match(/security|denied/i));
|
||||
}
|
||||
return ready;
|
||||
}
|
||||
|
||||
function ssWatcher (params, cb) {
|
||||
// watches a stylesheet for loading signs.
|
||||
if (isLinkReady(params.link)) {
|
||||
cleanup(params);
|
||||
cb();
|
||||
}
|
||||
else if (!failed) {
|
||||
setTimeout(function () { ssWatcher(params, cb); }, params.wait);
|
||||
}
|
||||
}
|
||||
|
||||
function loadDetector (params, cb) {
|
||||
// It would be nice to use onload everywhere, but the onload handler
|
||||
// only works in IE and Opera.
|
||||
// Detecting it cross-browser is completely impossible, too, since
|
||||
// THE BROWSERS ARE LIARS! DON'T TELL ME YOU HAVE AN ONLOAD PROPERTY
|
||||
// IF IT DOESN'T DO ANYTHING!
|
||||
var loaded;
|
||||
function cbOnce () {
|
||||
if (!loaded) {
|
||||
loaded = true;
|
||||
cb();
|
||||
}
|
||||
}
|
||||
loadHandler(params, cbOnce);
|
||||
if (!has("event-link-onload")) {
|
||||
ssWatcher(params, cbOnce);
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup (params) {
|
||||
var link = params.link;
|
||||
link[onreadystatechange] = link[onload] = null;
|
||||
}
|
||||
|
||||
function moveLinksToCollector () {
|
||||
// IE 6-8 fails when over 31 sheets, so we collect them.
|
||||
// Note: this hack relies on proper cache headers.
|
||||
var link, links, collector, pos = 0;
|
||||
collector = collectorSheet;
|
||||
collectorSheet = null; // so a new one will be created
|
||||
links = document.getElementsByTagName('link');
|
||||
while ((link = links[pos])) {
|
||||
if (link.getAttribute('_curl_movable')) {
|
||||
// move to the collectorSheet (note: bad cache directive will cause a re-download)
|
||||
collector.addImport(link.href);
|
||||
// remove from document
|
||||
link.parentNode && link.parentNode.removeChild(link);
|
||||
}
|
||||
else {
|
||||
// skip this sheet
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***** style element functions *****/
|
||||
|
||||
var currentStyle;
|
||||
|
||||
function translateUrls (cssText, baseUrl) {
|
||||
return cssText.replace(findUrlRx, function (all, url) {
|
||||
return 'url("' + translateUrl(url, baseUrl) + '")';
|
||||
});
|
||||
}
|
||||
|
||||
function translateUrl (url, parentPath) {
|
||||
// if this is a relative url
|
||||
if (!nonRelUrlRe.test(url)) {
|
||||
// append path onto it
|
||||
url = parentPath + url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function createStyle (cssText) {
|
||||
clearTimeout(createStyle.debouncer);
|
||||
if (createStyle.accum) {
|
||||
createStyle.accum.push(cssText);
|
||||
}
|
||||
else {
|
||||
createStyle.accum = [cssText];
|
||||
currentStyle = doc.createStyleSheet ? doc.createStyleSheet() :
|
||||
head.appendChild(doc.createElement('style'));
|
||||
}
|
||||
|
||||
createStyle.debouncer = setTimeout(function () {
|
||||
// Note: IE 6-8 won't accept the W3C method for inserting css text
|
||||
var style, allCssText;
|
||||
|
||||
style = currentStyle;
|
||||
currentStyle = undef;
|
||||
|
||||
allCssText = createStyle.accum.join('\n');
|
||||
createStyle.accum = undef;
|
||||
|
||||
// for safari which chokes on @charset "UTF-8";
|
||||
allCssText = allCssText.replace(/.+charset[^;]+;/g, '');
|
||||
|
||||
// TODO: hoist all @imports to the top of the file to follow w3c spec
|
||||
|
||||
'cssText' in style ? style.cssText = allCssText :
|
||||
style.appendChild(doc.createTextNode(allCssText));
|
||||
|
||||
}, 0);
|
||||
|
||||
return currentStyle;
|
||||
}
|
||||
|
||||
function createSheetProxy (sheet) {
|
||||
return {
|
||||
cssRules: function () {
|
||||
return sheet.cssRules || sheet.rules;
|
||||
},
|
||||
insertRule: sheet.insertRule || function (text, index) {
|
||||
var parts = text.split(/\{|\}/g);
|
||||
sheet.addRule(parts[0], parts[1], index);
|
||||
return index;
|
||||
},
|
||||
deleteRule: sheet.deleteRule || function (index) {
|
||||
sheet.removeRule(index);
|
||||
return index;
|
||||
},
|
||||
sheet: function () {
|
||||
return sheet;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/***** finally! the actual plugin *****/
|
||||
|
||||
define(/*=='css',==*/ {
|
||||
|
||||
'normalize': function (resourceId, normalize) {
|
||||
var resources, normalized;
|
||||
|
||||
if (!resourceId) return resourceId;
|
||||
|
||||
resources = resourceId.split(",");
|
||||
normalized = [];
|
||||
|
||||
for (var i = 0, len = resources.length; i < len; i++) {
|
||||
normalized.push(normalize(resources[i]));
|
||||
}
|
||||
|
||||
return normalized.join(',');
|
||||
},
|
||||
|
||||
'load': function (resourceId, require, callback, config) {
|
||||
var resources = (resourceId || '').split(","),
|
||||
loadingCount = resources.length;
|
||||
|
||||
// all detector functions must ensure that this function only gets
|
||||
// called once per stylesheet!
|
||||
function loaded () {
|
||||
// load/error handler may have executed before stylesheet is
|
||||
// fully parsed / processed in Opera, so use setTimeout.
|
||||
// Opera will process before the it next enters the event loop
|
||||
// (so 0 msec is enough time).
|
||||
if(--loadingCount == 0){
|
||||
// TODO: move this setTimeout to loadHandler
|
||||
setTimeout(function () { callback(createSheetProxy(link.sheet || link.styleSheet)); }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!resourceId) {
|
||||
// return the run-time API
|
||||
callback({
|
||||
'translateUrls': function (cssText, baseId) {
|
||||
var baseUrl;
|
||||
baseUrl = require['toUrl'](baseId);
|
||||
baseUrl = baseUrl.substr(0, baseUrl.lastIndexOf('/') + 1);
|
||||
return translateUrls(cssText, baseUrl);
|
||||
},
|
||||
'injectStyle': function (cssText) {
|
||||
return createStyle(cssText);
|
||||
},
|
||||
|
||||
'proxySheet': function (sheet) {
|
||||
// for W3C, `sheet` is a reference to a <style> node so we need to
|
||||
// return the sheet property.
|
||||
if (sheet.sheet /* instanceof CSSStyleSheet */) sheet = sheet.sheet;
|
||||
return createSheetProxy(sheet);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
// `after` will become truthy once the loop executes a second time
|
||||
for (var i = resources.length - 1, after; i >= 0; i--, after = true) {
|
||||
|
||||
resourceId = resources[i];
|
||||
|
||||
var
|
||||
// TODO: this is a bit weird: find a better way to extract name?
|
||||
opts = parseSuffixes(resourceId),
|
||||
name = opts.shift(),
|
||||
url = require['toUrl'](nameWithExt(name, 'css')),
|
||||
link = createLink(doc),
|
||||
nowait = 'nowait' in opts ? opts['nowait'] != 'false' : !!config['cssDeferLoad'],
|
||||
params = {
|
||||
link: link,
|
||||
url: url,
|
||||
wait: config['cssWatchPeriod'] || 50
|
||||
};
|
||||
|
||||
if (nowait) {
|
||||
callback(createSheetProxy(link.sheet || link.styleSheet));
|
||||
}
|
||||
else {
|
||||
// hook up load detector(s)
|
||||
loadDetector(params, loaded);
|
||||
}
|
||||
|
||||
// go!
|
||||
link.href = url;
|
||||
|
||||
if (after) {
|
||||
head.insertBefore(link, insertedSheets[after].previousSibling);
|
||||
}
|
||||
else {
|
||||
head.appendChild(link);
|
||||
}
|
||||
insertedSheets[url] = link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
'plugin-builder': './builder/css'
|
||||
|
||||
});
|
||||
|
||||
})(this);
|
192
media/aloha-0.22.7/lib/i18n.js
Normal file
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* @license RequireJS i18n 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/requirejs/i18n for details
|
||||
*/
|
||||
/*jslint regexp: true */
|
||||
/*global require: false, navigator: false, define: false */
|
||||
|
||||
/**
|
||||
* This plugin handles i18n! prefixed modules. It does the following:
|
||||
*
|
||||
* 1) A regular module can have a dependency on an i18n bundle, but the regular
|
||||
* module does not want to specify what locale to load. So it just specifies
|
||||
* the top-level bundle, like "i18n!nls/colors".
|
||||
*
|
||||
* This plugin will load the i18n bundle at nls/colors, see that it is a root/master
|
||||
* bundle since it does not have a locale in its name. It will then try to find
|
||||
* the best match locale available in that master bundle, then request all the
|
||||
* locale pieces for that best match locale. For instance, if the locale is "en-us",
|
||||
* then the plugin will ask for the "en-us", "en" and "root" bundles to be loaded
|
||||
* (but only if they are specified on the master bundle).
|
||||
*
|
||||
* Once all the bundles for the locale pieces load, then it mixes in all those
|
||||
* locale pieces into each other, then finally sets the context.defined value
|
||||
* for the nls/colors bundle to be that mixed in locale.
|
||||
*
|
||||
* 2) A regular module specifies a specific locale to load. For instance,
|
||||
* i18n!nls/fr-fr/colors. In this case, the plugin needs to load the master bundle
|
||||
* first, at nls/colors, then figure out what the best match locale is for fr-fr,
|
||||
* since maybe only fr or just root is defined for that locale. Once that best
|
||||
* fit is found, all of its locale pieces need to have their bundles loaded.
|
||||
*
|
||||
* Once all the bundles for the locale pieces load, then it mixes in all those
|
||||
* locale pieces into each other, then finally sets the context.defined value
|
||||
* for the nls/fr-fr/colors bundle to be that mixed in locale.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
//regexp for reconstructing the master bundle name from parts of the regexp match
|
||||
//nlsRegExp.exec("foo/bar/baz/nls/en-ca/foo") gives:
|
||||
//["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
|
||||
//nlsRegExp.exec("foo/bar/baz/nls/foo") gives:
|
||||
//["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""]
|
||||
//so, if match[5] is blank, it means this is the top bundle definition.
|
||||
var nlsRegExp = /(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/;
|
||||
|
||||
//Helper function to avoid repeating code. Lots of arguments in the
|
||||
//desire to stay functional and support RequireJS contexts without having
|
||||
//to know about the RequireJS contexts.
|
||||
function addPart(locale, master, needed, toLoad, prefix, suffix) {
|
||||
if (master[locale]) {
|
||||
needed.push(locale);
|
||||
if (master[locale] === true || master[locale] === 1) {
|
||||
toLoad.push(prefix + locale + '/' + suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addIfExists(req, locale, toLoad, prefix, suffix) {
|
||||
var fullName = prefix + locale + '/' + suffix;
|
||||
if (require._fileExists(req.toUrl(fullName))) {
|
||||
toLoad.push(fullName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function to mix in properties from source into target,
|
||||
* but only if target does not already have a property of the same name.
|
||||
* This is not robust in IE for transferring methods that match
|
||||
* Object.prototype names, but the uses of mixin here seem unlikely to
|
||||
* trigger a problem related to that.
|
||||
*/
|
||||
function mixin(target, source, force) {
|
||||
var prop;
|
||||
for (prop in source) {
|
||||
if (source.hasOwnProperty(prop) && (!target.hasOwnProperty(prop) || force)) {
|
||||
target[prop] = source[prop];
|
||||
} else if (typeof source[prop] === 'object') {
|
||||
mixin(target[prop], source[prop], force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define(['module'], function (module) {
|
||||
var masterConfig = module.config();
|
||||
|
||||
return {
|
||||
version: '2.0.1',
|
||||
/**
|
||||
* Called when a dependency needs to be loaded.
|
||||
*/
|
||||
load: function (name, req, onLoad, config) {
|
||||
config = config || {};
|
||||
|
||||
if (config.locale) {
|
||||
masterConfig.locale = config.locale;
|
||||
}
|
||||
|
||||
var masterName,
|
||||
match = nlsRegExp.exec(name),
|
||||
prefix = match[1],
|
||||
locale = match[4],
|
||||
suffix = match[5],
|
||||
parts = locale.split("-"),
|
||||
toLoad = [],
|
||||
value = {},
|
||||
i, part, current = "";
|
||||
|
||||
//If match[5] is blank, it means this is the top bundle definition,
|
||||
//so it does not have to be handled. Locale-specific requests
|
||||
//will have a match[4] value but no match[5]
|
||||
if (match[5]) {
|
||||
//locale-specific bundle
|
||||
prefix = match[1];
|
||||
masterName = prefix + suffix;
|
||||
} else {
|
||||
//Top-level bundle.
|
||||
masterName = name;
|
||||
suffix = match[4];
|
||||
locale = masterConfig.locale;
|
||||
if (!locale) {
|
||||
locale = masterConfig.locale =
|
||||
typeof navigator === "undefined" ? "root" :
|
||||
(navigator.language ||
|
||||
navigator.userLanguage || "root").toLowerCase();
|
||||
}
|
||||
parts = locale.split("-");
|
||||
}
|
||||
|
||||
if (config.isBuild) {
|
||||
//Check for existence of all locale possible files and
|
||||
//require them if exist.
|
||||
toLoad.push(masterName);
|
||||
addIfExists(req, "root", toLoad, prefix, suffix);
|
||||
for (i = 0; i < parts.length; i++) {
|
||||
part = parts[i];
|
||||
current += (current ? "-" : "") + part;
|
||||
addIfExists(req, current, toLoad, prefix, suffix);
|
||||
}
|
||||
|
||||
req(toLoad, function () {
|
||||
onLoad();
|
||||
});
|
||||
} else {
|
||||
//First, fetch the master bundle, it knows what locales are available.
|
||||
req([masterName], function (master) {
|
||||
//Figure out the best fit
|
||||
var needed = [],
|
||||
part;
|
||||
|
||||
//Always allow for root, then do the rest of the locale parts.
|
||||
addPart("root", master, needed, toLoad, prefix, suffix);
|
||||
for (i = 0; i < parts.length; i++) {
|
||||
part = parts[i];
|
||||
current += (current ? "-" : "") + part;
|
||||
addPart(current, master, needed, toLoad, prefix, suffix);
|
||||
}
|
||||
|
||||
//Load all the parts missing.
|
||||
req(toLoad, function () {
|
||||
var i, partBundle, part;
|
||||
for (i = needed.length - 1; i > -1 && needed[i]; i--) {
|
||||
part = needed[i];
|
||||
partBundle = master[part];
|
||||
if (partBundle === true || partBundle === 1) {
|
||||
partBundle = req(prefix + part + '/' + suffix);
|
||||
}
|
||||
mixin(value, partBundle);
|
||||
}
|
||||
|
||||
// MODIFICATION FROM ALOHA START: add a t() function
|
||||
value.t = function( key, defaultValue ) {
|
||||
if ( this[key] ) {
|
||||
return this[key];
|
||||
} else if ( defaultValue ) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
// END OF ALOHA MODIFICATION
|
||||
|
||||
//All done, notify the loader.
|
||||
onLoad(value);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}());
|
@@ -18,7 +18,7 @@
|
||||
defaultPort = hasLocation && (location.port || undefined),
|
||||
buildMap = [];
|
||||
|
||||
define([],function () {
|
||||
define(function () {
|
||||
var text, get, fs;
|
||||
|
||||
if (typeof window !== "undefined" && window.navigator && window.document) {
|
208
media/aloha-0.22.7/lib/util/arrays.js
Normal file
@@ -0,0 +1,208 @@
|
||||
/* arrays.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Implements unique() using the browser's sort().
|
||||
*
|
||||
* @param a
|
||||
* The array to sort and strip of duplicate values.
|
||||
* Warning: this array will be modified in-place.
|
||||
* @param compFn
|
||||
* A custom comparison function that accepts two values a and
|
||||
* b from the given array and returns -1, 0, 1 depending on
|
||||
* whether a < b, a == b, a > b respectively.
|
||||
*
|
||||
* If no compFn is provided, the algorithm will use the
|
||||
* browsers default sort behaviour and loose comparison to
|
||||
* detect duplicates.
|
||||
* @return
|
||||
* The given array.
|
||||
*/
|
||||
function sortUnique(a, compFn) {
|
||||
var i;
|
||||
if (compFn) {
|
||||
a.sort(compFn);
|
||||
for (i = 1; i < a.length; i++) {
|
||||
if (0 === compFn(a[i], a[i - 1])) {
|
||||
a.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
a.sort();
|
||||
for (i = 1; i < a.length; i++) {
|
||||
// Use loosely typed comparsion if no compFn is given
|
||||
// to avoid sortUnique( [6, "6", 6] ) => [6, "6", 6]
|
||||
if (a[i] == a[i - 1]) {
|
||||
a.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow comparison of two arrays.
|
||||
*
|
||||
* @param a, b
|
||||
* The arrays to compare.
|
||||
* @param equalFn
|
||||
* A custom comparison function that accepts two values a and
|
||||
* b from the given arrays and returns true or false for
|
||||
* equal and not equal respectively.
|
||||
*
|
||||
* If no equalFn is provided, the algorithm will use the strict
|
||||
* equals operator.
|
||||
* @return
|
||||
* True if all items in a and b are equal, false if not.
|
||||
*/
|
||||
function equal(a, b, equalFn) {
|
||||
var i,
|
||||
len = a.length;
|
||||
if (len !== b.length) {
|
||||
return false;
|
||||
}
|
||||
if (equalFn) {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!equalFn(a[i], b[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ECMAScript map replacement
|
||||
* See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
|
||||
* And http://es5.github.com/#x15.4.4.19
|
||||
* It's not exactly according to standard, but it does exactly what one expects.
|
||||
*/
|
||||
function map(a, fn) {
|
||||
var i, len, result = [];
|
||||
for (i = 0, len = a.length; i < len; i++) {
|
||||
result.push(fn(a[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function mapNative(a, fn) {
|
||||
// Call map directly on the object instead of going through
|
||||
// Array.prototype.map. This avoids the problem that we may get
|
||||
// passed an array-like object (NodeList) which may cause an
|
||||
// error if the implementation of Array.prototype.map can only
|
||||
// deal with arrays (Array.prototype.map may be native or
|
||||
// provided by a javscript framework).
|
||||
return a.map(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that contains all values in the given a for
|
||||
* which pred returns true.
|
||||
*/
|
||||
function filter(a, pred) {
|
||||
var i,
|
||||
len,
|
||||
value,
|
||||
result = [];
|
||||
for (i = 0, len = a.length; i < len; i++) {
|
||||
value = a[i];
|
||||
if (pred(value)) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a value in the given array.
|
||||
* Strict comparison is used to find the value.
|
||||
* Returns the index of the first occurrence of the given value in
|
||||
* the given a, or -1 if a contains no such value.
|
||||
*/
|
||||
function indexOf(a, value) {
|
||||
var i,
|
||||
len;
|
||||
for (i = 0, len = a.length; i < len; i++) {
|
||||
if (value === a[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces an array of values to a single value.
|
||||
*
|
||||
* For example:
|
||||
* Arrays.reduce([2, 3, 4], 1, function (a, b) { return a + b; });
|
||||
* returns the result of (((1 + 2) + 3) + 4)
|
||||
*
|
||||
* @param a
|
||||
* An array of values.
|
||||
* @param init
|
||||
* An initial value.
|
||||
* @param fn
|
||||
* A function that takes two values and returns the reduction
|
||||
* of both.
|
||||
*/
|
||||
function reduce(a, init, fn) {
|
||||
var i,
|
||||
len;
|
||||
for (i = 0, len = a.length; i < len; i++) {
|
||||
init = fn(init, a[i]);
|
||||
}
|
||||
return init;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given value to the given function unless the value is
|
||||
* null, in which case just returns null.
|
||||
*
|
||||
* This is a utility function to be used with reduce().
|
||||
*/
|
||||
function applyNotNull(value, fn) {
|
||||
return value == null ? null : fn(value);
|
||||
}
|
||||
|
||||
return {
|
||||
filter: filter,
|
||||
indexOf: indexOf,
|
||||
reduce: reduce,
|
||||
applyNotNull: applyNotNull,
|
||||
sortUnique: sortUnique,
|
||||
equal: equal,
|
||||
map: Array.prototype.map ? mapNative : map
|
||||
};
|
||||
});
|
32
media/aloha-0.22.7/lib/util/browser.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/* ephemera.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define(['jquery'], function ($) {
|
||||
'use strict';
|
||||
return {
|
||||
ie7: $.browser.msie && parseInt($.browser.version, 10) < 8
|
||||
};
|
||||
});
|
78
media/aloha-0.22.7/lib/util/class.js
Executable file
@@ -0,0 +1,78 @@
|
||||
/* Simple JavaScript Inheritance
|
||||
* By John Resig http://ejohn.org/
|
||||
* MIT Licensed.
|
||||
*/
|
||||
// Inspired by base2 and Prototype
|
||||
/*
|
||||
* MODIFICATIONS:
|
||||
* * The name of the "constructor" method was changed from "init" to "_constructor"
|
||||
* * Mixin Support using https://gist.github.com/1006243
|
||||
* * Modified to be a require.js module
|
||||
*/
|
||||
define([], function () {
|
||||
var initializing = false,
|
||||
fnTest = /xyz/.test(function () {
|
||||
xyz;
|
||||
}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
// with doing that Class is available in the global namespace.
|
||||
this.Class = function () {};
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Class.extend = function () {
|
||||
var _super = this.prototype;
|
||||
|
||||
// Instantiate a base class (but only create the instance,
|
||||
// don't run the init constructor)
|
||||
initializing = true;
|
||||
var prototype = new this();
|
||||
initializing = false;
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var prop = arguments[i];
|
||||
for (var name in prop) {
|
||||
// Check if we're overwriting an existing function
|
||||
prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function (name, fn) {
|
||||
return function () {
|
||||
|
||||
var tmp = this._super;
|
||||
|
||||
// Add a new ._super() method that is the same method
|
||||
// but on the super-class
|
||||
this._super = _super[name];
|
||||
|
||||
// The method only need to be bound temporarily, so we
|
||||
// remove it when we're done executing
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
|
||||
return ret;
|
||||
};
|
||||
})(name, prop[name]) : prop[name];
|
||||
}
|
||||
}
|
||||
|
||||
// The dummy class constructor
|
||||
function Class() {
|
||||
// All construction is actually done in the _constructor method
|
||||
if (!initializing && this._constructor) this._constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Populate our constructed prototype object
|
||||
Class.prototype = prototype;
|
||||
|
||||
// Enforce the constructor to be what we expect
|
||||
Class.constructor = Class;
|
||||
|
||||
// And make this class extendable
|
||||
Class.extend = arguments.callee;
|
||||
|
||||
return Class;
|
||||
|
||||
};
|
||||
|
||||
return this.Class;
|
||||
|
||||
});
|
1706
media/aloha-0.22.7/lib/util/dom.js
Executable file
301
media/aloha-0.22.7/lib/util/dom2.js
Normal file
@@ -0,0 +1,301 @@
|
||||
/* ephemera.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'util/maps',
|
||||
'util/strings',
|
||||
'util/browser'
|
||||
], function (
|
||||
$,
|
||||
Maps,
|
||||
Strings,
|
||||
Browser
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var spacesRx = /\s+/;
|
||||
var attrRegex = /\s([^\/<>\s=]+)(?:=(?:"[^"]*"|'[^']*'|[^>\/\s]+))?/g;
|
||||
|
||||
/**
|
||||
* Like insertBefore, inserts firstChild into parent before
|
||||
* refChild, except also inserts all the following siblings of
|
||||
* firstChild.
|
||||
*/
|
||||
function moveNextAll(parent, firstChild, refChild) {
|
||||
while (firstChild) {
|
||||
var nextChild = firstChild.nextSibling;
|
||||
parent.insertBefore(firstChild, refChild);
|
||||
firstChild = nextChild;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to serialize outerHTML of DOM elements in older (pre-HTML5) Gecko,
|
||||
* Safari, and Opera browsers.
|
||||
*
|
||||
* Beware that XMLSerializer generates an XHTML string (<div class="team" />
|
||||
* instead of <div class="team"></div>). It is noted here:
|
||||
* http://stackoverflow.com/questions/1700870/how-do-i-do-outerhtml-in-firefox
|
||||
* that some browsers (like older versions of Firefox) have problems with
|
||||
* XMLSerializer, and an alternative, albeit more expensive option, is
|
||||
* described.
|
||||
*
|
||||
* @type {XMLSerializer|null}
|
||||
*/
|
||||
var Serializer = window.XMLSerializer && new window.XMLSerializer();
|
||||
|
||||
/**
|
||||
* Gets the serialized HTML that describes the given DOM element and its
|
||||
* innerHTML.
|
||||
*
|
||||
* Polyfill for older versions of Gecko, Safari, and Opera browsers.
|
||||
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=92264 for background.
|
||||
*
|
||||
* @param {HTMLElement} node DOM Element.
|
||||
* @return {String}
|
||||
*/
|
||||
function outerHtml(node) {
|
||||
var html = node.outerHTML;
|
||||
if (typeof html !== 'undefined') {
|
||||
return html;
|
||||
}
|
||||
try {
|
||||
return Serializer ? Serializer.serializeToString(node) : node.xml;
|
||||
} catch (e) {
|
||||
return node.xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the names of all attributes from the given elmenet.
|
||||
*
|
||||
* Correctly handles the case that IE7 and IE8 have approx 70-90
|
||||
* default attributes on each and every element.
|
||||
*
|
||||
* This implementation does not iterate over the elem.attributes
|
||||
* property since that is much slower on IE7 (even when
|
||||
* checking the attrNode.specified property). Instead it parses the
|
||||
* HTML of the element. For elements with few attributes the
|
||||
* performance on IE7 is improved by an order of magnitued.
|
||||
*
|
||||
* On IE7, when you clone a <button disabled="disabled"/> or an
|
||||
* <input checked="checked"/> element the boolean properties will
|
||||
* not be set on the cloned node. We choose the speed optimization
|
||||
* over correctness in this case. The dom-to-xhtml plugin has a
|
||||
* workaround for this case.
|
||||
*/
|
||||
function attrNames(elem) {
|
||||
var names = [];
|
||||
var html = outerHtml(elem.cloneNode(false));
|
||||
var match;
|
||||
while (null != (match = attrRegex.exec(html))) {
|
||||
names.push(match[1]);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the attributes of the given element.
|
||||
*
|
||||
* See attrNames() for an edge case on IE7.
|
||||
*
|
||||
* @param elem
|
||||
* An element to get the attributes for.
|
||||
* @return
|
||||
* An array containing [name, value] tuples for each attribute.
|
||||
* Attribute values will always be strings, but possibly empty strings.
|
||||
*/
|
||||
function attrs(elem) {
|
||||
var as = [];
|
||||
var names = attrNames(elem);
|
||||
var i;
|
||||
var len;
|
||||
for (i = 0, len = names.length; i < len; i++) {
|
||||
var name = names[i];
|
||||
var value = $.attr(elem, name);
|
||||
if (null == value) {
|
||||
value = "";
|
||||
} else {
|
||||
value = value.toString();
|
||||
}
|
||||
as.push([name, value]);
|
||||
}
|
||||
return as;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like indexByClass() but operates on a list of elements instead.
|
||||
* The given list may be a NodeList, HTMLCollection, or an array.
|
||||
*/
|
||||
function indexByClassHaveList(elems, classMap) {
|
||||
var index = {},
|
||||
indexed,
|
||||
classes,
|
||||
elem,
|
||||
cls,
|
||||
len,
|
||||
i,
|
||||
j;
|
||||
for (i = 0, len = elems.length; i < len; i++) {
|
||||
elem = elems[i];
|
||||
if (elem.className) {
|
||||
classes = Strings.words(elem.className);
|
||||
for (j = 0; j < classes.length; j++) {
|
||||
cls = classes[j];
|
||||
if (classMap[cls]) {
|
||||
indexed = index[cls];
|
||||
if (indexed) {
|
||||
indexed.push(elem);
|
||||
} else {
|
||||
index[cls] = [elem];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes descendant elements based on the individual classes in
|
||||
* the class attribute.
|
||||
*
|
||||
* Based on these observations;
|
||||
*
|
||||
* * $('.class1, .class2') takes twice as long as $('.class1') on IE7.
|
||||
*
|
||||
* * $('.class1, .class2') is fast on IE8 (approx the same as
|
||||
* $('.class'), no matter how many classes), but if the individual
|
||||
* elements in the result set should be handled differently, the
|
||||
* subsequent hasClass('.class1') and hasClass('.class2') calls
|
||||
* slow things down again.
|
||||
*
|
||||
* * DOM traversal with elem.firstChild elem.nextSibling is very
|
||||
* slow on IE7 compared to just iterating over
|
||||
* root.getElementsByTagName('*').
|
||||
*
|
||||
* * $('name.class') is much faster than just $('.class'), but as
|
||||
* soon as you need a single class in classMap that may be present
|
||||
* on any element, that optimization doesn't gain anything since
|
||||
* then you have to examine every element.
|
||||
*
|
||||
* This function will always take approx. the same amount of time
|
||||
* (on IE7 approx. equivalent to a single call to $('.class')) no
|
||||
* matter how many entries there are in classMap to index.
|
||||
*
|
||||
* This function only makes sense for multiple entries in
|
||||
* classMap. For a single class lookup, $('.class') or
|
||||
* $('name.class') is fine (even better in the latter case).
|
||||
*
|
||||
* @param root
|
||||
* The root element to search for elements to index
|
||||
* (will not be included in search).
|
||||
* @param classMap
|
||||
* A map from class name to boolean true.
|
||||
* @return
|
||||
* A map from class name to an array of elements with that class.
|
||||
* Every entry in classMap for which elements have been found
|
||||
* will have a corresponding entry in the returned
|
||||
* map. Entries for which no elements have been found, may or
|
||||
* may not have an entry in the returned map.
|
||||
*/
|
||||
function indexByClass(root, classMap) {
|
||||
var elems;
|
||||
if (Browser.ie7) {
|
||||
elems = root.getElementsByTagName('*');
|
||||
} else {
|
||||
// Optimize for browsers that support querySelectorAll/getElementsByClassName.
|
||||
// On IE8 for example, if there is a relatively high
|
||||
// elems/resultSet ratio, performance can improve by a factor of 2.
|
||||
elems = $(root).find('.' + Maps.keys(classMap).join(',.'));
|
||||
}
|
||||
return indexByClassHaveList(elems, classMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes descendant elements based on elem.nodeName.
|
||||
*
|
||||
* Based on these observations:
|
||||
*
|
||||
* * On IE8, for moderate values of names.length, individual calls to
|
||||
* getElementsByTagName is just as fast as $root.find('name, name,
|
||||
* name, name').
|
||||
*
|
||||
* * On IE7, $root.find('name, name, name, name') is extemely slow
|
||||
* (can be an order of magnitude slower than individual calls to
|
||||
* getElementsByTagName, why is that?).
|
||||
*
|
||||
* * Although getElementsByTagName is very fast even on IE7, when
|
||||
* names.length > 7 an alternative implementation that iterates
|
||||
* over all tags and checks names from a hashmap (similar to how
|
||||
* indexByClass does it) may become interesting, but
|
||||
* names.length > 7 is unlikely.
|
||||
*
|
||||
* This function only makes sense if the given names array has many
|
||||
* entries. For only one or two different names, calling $('name')
|
||||
* or context.getElementsByTagName(name) directly is fine (but
|
||||
* beware of $('name, name, ...') as explained above).
|
||||
*
|
||||
* The signature of this function differs from indexByClass by not
|
||||
* taking a map but instead an array of names.
|
||||
*
|
||||
* @param root
|
||||
* The root element to search for elements to index
|
||||
* (will not be included in search).
|
||||
* @param names
|
||||
* An array of element names to look for.
|
||||
* Names must be in all-uppercase (the same as elem.nodeName).
|
||||
* @return
|
||||
* A map from element name to an array of elements with that name.
|
||||
* Names will be all-uppercase.
|
||||
* Arrays will be proper arrays, not NodeLists.
|
||||
* Every entry in classMap for which elements have been found
|
||||
* will have a corresponding entry in the returned
|
||||
* map. Entries for which no elements have been found, may or
|
||||
* may not have an entry in the returned map.
|
||||
*/
|
||||
function indexByName(root, names) {
|
||||
var i,
|
||||
index = {},
|
||||
len;
|
||||
for (i = 0, len = names.length; i < len; i++) {
|
||||
var name = names[i];
|
||||
index[name] = $.makeArray(root.getElementsByTagName(name));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
return {
|
||||
moveNextAll: moveNextAll,
|
||||
attrNames: attrNames,
|
||||
attrs: attrs,
|
||||
indexByClass: indexByClass,
|
||||
indexByName: indexByName,
|
||||
indexByClassHaveList: indexByClassHaveList,
|
||||
outerHtml: outerHtml
|
||||
};
|
||||
});
|
41
media/aloha-0.22.7/lib/util/functions.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/* functions.js is part of Aloha Editor project http://aloha-editor.org
|
||||
*
|
||||
* Aloha Editor is a WYSIWYG HTML5 inline editing library and editor.
|
||||
* Copyright (c) 2010-2012 Gentics Software GmbH, Vienna, Austria.
|
||||
* Contributors http://aloha-editor.org/contribution.php
|
||||
*
|
||||
* Aloha Editor is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* Aloha Editor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* As an additional permission to the GNU GPL version 2, you may distribute
|
||||
* non-source (e.g., minimized or compacted) forms of the Aloha-Editor
|
||||
* source code without the copy of the GNU GPL normally required,
|
||||
* provided you include this license notice and a URL through which
|
||||
* recipients can access the Corresponding Source.
|
||||
*/
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The identity function returns its single argument.
|
||||
* Useful for composition when some default behaviour is needed.
|
||||
*/
|
||||
function identity(arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
return {
|
||||
identity: identity
|
||||
};
|
||||
});
|
464
media/aloha-0.22.7/lib/util/json2.js
Normal file
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2011-02-23
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the value
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date ?
|
||||
'Date(' + this[key] + ')' : value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver parameter is a function that can filter and
|
||||
transform the results. It receives each of the keys and values,
|
||||
and its return value is used instead of the original value.
|
||||
If it returns what it received, then the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
*/
|
||||
|
||||
/*jslint evil: true, strict: false, regexp: false */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
// Create a JSON object only if one does not already exist.
|
||||
var JSON;
|
||||
if (!JSON) {
|
||||
JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
|
||||
return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z' : null;
|
||||
};
|
||||
|
||||
String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) {
|
||||
return this.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"': '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0;
|
||||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' : '"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' && typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {
|
||||
'': value
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
cx.lastIndex = 0;
|
||||
if (cx.test(text)) {
|
||||
text = text.replace(cx, function (a) {
|
||||
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function' ? walk({
|
||||
'': j
|
||||
}, '') : j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
||||
|
||||
define('util/json2', [], function () {
|
||||
return JSON;
|
||||
});
|