W.I.P of collaborative odf editor:
- Add wodocollabtexteditor library
659
api/js/webodf/collab/EditorSession.js
Normal file
@ -0,0 +1,659 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global runtime, define, document, core, odf, gui, ops*/
|
||||
|
||||
define("webodf/editor/EditorSession", [
|
||||
"dojo/text!resources/fonts/fonts.css"
|
||||
], function (fontsCSS) { // fontsCSS is retrieved as a string, using dojo's text retrieval AMD plugin
|
||||
"use strict";
|
||||
|
||||
runtime.loadClass("core.Async");
|
||||
runtime.loadClass("core.DomUtils");
|
||||
runtime.loadClass("odf.OdfUtils");
|
||||
runtime.loadClass("ops.OdtDocument");
|
||||
runtime.loadClass("ops.OdtStepsTranslator");
|
||||
runtime.loadClass("ops.Session");
|
||||
runtime.loadClass("odf.Namespaces");
|
||||
runtime.loadClass("odf.OdfCanvas");
|
||||
runtime.loadClass("odf.OdfUtils");
|
||||
runtime.loadClass("gui.CaretManager");
|
||||
runtime.loadClass("gui.Caret");
|
||||
runtime.loadClass("gui.OdfFieldView");
|
||||
runtime.loadClass("gui.SessionController");
|
||||
runtime.loadClass("gui.SessionView");
|
||||
runtime.loadClass("gui.HyperlinkTooltipView");
|
||||
runtime.loadClass("gui.TrivialUndoManager");
|
||||
runtime.loadClass("gui.SvgSelectionView");
|
||||
runtime.loadClass("gui.SelectionViewManager");
|
||||
runtime.loadClass("core.EventNotifier");
|
||||
runtime.loadClass("gui.ShadowCursor");
|
||||
runtime.loadClass("gui.CommonConstraints");
|
||||
|
||||
/**
|
||||
* Instantiate a new editor session attached to an existing operation session
|
||||
* @constructor
|
||||
* @implements {core.EventSource}
|
||||
* @param {!ops.Session} session
|
||||
* @param {!string} localMemberId
|
||||
* @param {{viewOptions:gui.SessionViewOptions,directParagraphStylingEnabled:boolean,annotationsEnabled:boolean}} config
|
||||
*/
|
||||
var EditorSession = function EditorSession(session, localMemberId, config) {
|
||||
var self = this,
|
||||
currentParagraphNode = null,
|
||||
currentCommonStyleName = null,
|
||||
currentStyleName = null,
|
||||
caretManager,
|
||||
selectionViewManager,
|
||||
hyperlinkTooltipView,
|
||||
odtDocument = session.getOdtDocument(),
|
||||
textns = odf.Namespaces.textns,
|
||||
fontStyles = document.createElement('style'),
|
||||
formatting = odtDocument.getFormatting(),
|
||||
domUtils = core.DomUtils,
|
||||
odfUtils = odf.OdfUtils,
|
||||
odfFieldView,
|
||||
eventNotifier = new core.EventNotifier([
|
||||
EditorSession.signalMemberAdded,
|
||||
EditorSession.signalMemberUpdated,
|
||||
EditorSession.signalMemberRemoved,
|
||||
EditorSession.signalCursorAdded,
|
||||
EditorSession.signalCursorMoved,
|
||||
EditorSession.signalCursorRemoved,
|
||||
EditorSession.signalParagraphChanged,
|
||||
EditorSession.signalCommonStyleCreated,
|
||||
EditorSession.signalCommonStyleDeleted,
|
||||
EditorSession.signalParagraphStyleModified,
|
||||
EditorSession.signalUndoStackChanged]),
|
||||
shadowCursor = new gui.ShadowCursor(odtDocument),
|
||||
sessionConstraints,
|
||||
/**@const*/
|
||||
NEXT = core.StepDirection.NEXT;
|
||||
|
||||
/**
|
||||
* @return {Array.<!string>}
|
||||
*/
|
||||
function getAvailableFonts() {
|
||||
var availableFonts, regex, matches;
|
||||
|
||||
availableFonts = {};
|
||||
|
||||
/*jslint regexp: true*/
|
||||
regex = /font-family *: *(?:\'([^']*)\'|\"([^"]*)\")/gm;
|
||||
/*jslint regexp: false*/
|
||||
matches = regex.exec(fontsCSS);
|
||||
|
||||
while (matches) {
|
||||
availableFonts[matches[1] || matches[2]] = 1;
|
||||
matches = regex.exec(fontsCSS);
|
||||
}
|
||||
availableFonts = Object.keys(availableFonts);
|
||||
|
||||
return availableFonts;
|
||||
}
|
||||
|
||||
function checkParagraphStyleName() {
|
||||
var newStyleName,
|
||||
newCommonStyleName;
|
||||
|
||||
newStyleName = currentParagraphNode.getAttributeNS(textns, 'style-name');
|
||||
|
||||
if (newStyleName !== currentStyleName) {
|
||||
currentStyleName = newStyleName;
|
||||
// check if common style is still the same
|
||||
newCommonStyleName = formatting.getFirstCommonParentStyleNameOrSelf(newStyleName);
|
||||
if (!newCommonStyleName) {
|
||||
// Default style, empty-string name
|
||||
currentCommonStyleName = newStyleName = currentStyleName = "";
|
||||
self.emit(EditorSession.signalParagraphChanged, {
|
||||
type: 'style',
|
||||
node: currentParagraphNode,
|
||||
styleName: currentCommonStyleName
|
||||
});
|
||||
return;
|
||||
}
|
||||
// a common style
|
||||
if (newCommonStyleName !== currentCommonStyleName) {
|
||||
currentCommonStyleName = newCommonStyleName;
|
||||
self.emit(EditorSession.signalParagraphChanged, {
|
||||
type: 'style',
|
||||
node: currentParagraphNode,
|
||||
styleName: currentCommonStyleName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a NCName from the passed string
|
||||
* @param {!string} name
|
||||
* @return {!string}
|
||||
*/
|
||||
function createNCName(name) {
|
||||
var letter,
|
||||
result = "",
|
||||
i;
|
||||
|
||||
// encode
|
||||
for (i = 0; i < name.length; i += 1) {
|
||||
letter = name[i];
|
||||
// simple approach, can be improved to not skip other allowed chars
|
||||
if (letter.match(/[a-zA-Z0-9.-_]/) !== null) {
|
||||
result += letter;
|
||||
} else {
|
||||
result += "_" + letter.charCodeAt(0).toString(16) + "_";
|
||||
}
|
||||
}
|
||||
// ensure leading char is from proper range
|
||||
if (result.match(/^[a-zA-Z_]/) === null) {
|
||||
result = "_" + result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function uniqueParagraphStyleNCName(name) {
|
||||
var result,
|
||||
i = 0,
|
||||
ncMemberId = createNCName(localMemberId),
|
||||
ncName = createNCName(name);
|
||||
|
||||
// create default paragraph style
|
||||
// localMemberId is used to avoid id conflicts with ids created by other members
|
||||
result = ncName + "_" + ncMemberId;
|
||||
// then loop until result is really unique
|
||||
while (formatting.hasParagraphStyle(result)) {
|
||||
result = ncName + "_" + i + "_" + ncMemberId;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function trackCursor(cursor) {
|
||||
var node;
|
||||
|
||||
node = odfUtils.getParagraphElement(cursor.getNode());
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
currentParagraphNode = node;
|
||||
checkParagraphStyleName();
|
||||
}
|
||||
|
||||
function trackCurrentParagraph(info) {
|
||||
var cursor = odtDocument.getCursor(localMemberId),
|
||||
range = cursor && cursor.getSelectedRange(),
|
||||
paragraphRange = odtDocument.getDOMDocument().createRange();
|
||||
paragraphRange.selectNode(info.paragraphElement);
|
||||
if ((range && domUtils.rangesIntersect(range, paragraphRange)) || info.paragraphElement === currentParagraphNode) {
|
||||
self.emit(EditorSession.signalParagraphChanged, info);
|
||||
checkParagraphStyleName();
|
||||
}
|
||||
paragraphRange.detach();
|
||||
}
|
||||
|
||||
function onMemberAdded(member) {
|
||||
self.emit(EditorSession.signalMemberAdded, member.getMemberId());
|
||||
}
|
||||
|
||||
function onMemberUpdated(member) {
|
||||
self.emit(EditorSession.signalMemberUpdated, member.getMemberId());
|
||||
}
|
||||
|
||||
function onMemberRemoved(memberId) {
|
||||
self.emit(EditorSession.signalMemberRemoved, memberId);
|
||||
}
|
||||
|
||||
function onCursorAdded(cursor) {
|
||||
self.emit(EditorSession.signalCursorAdded, cursor.getMemberId());
|
||||
trackCursor(cursor);
|
||||
}
|
||||
|
||||
function onCursorRemoved(memberId) {
|
||||
self.emit(EditorSession.signalCursorRemoved, memberId);
|
||||
}
|
||||
|
||||
function onCursorMoved(cursor) {
|
||||
// Emit 'cursorMoved' only when *I* am moving the cursor, not the other users
|
||||
if (cursor.getMemberId() === localMemberId) {
|
||||
self.emit(EditorSession.signalCursorMoved, cursor);
|
||||
trackCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
function onStyleCreated(newStyleName) {
|
||||
self.emit(EditorSession.signalCommonStyleCreated, newStyleName);
|
||||
}
|
||||
|
||||
function onStyleDeleted(styleName) {
|
||||
self.emit(EditorSession.signalCommonStyleDeleted, styleName);
|
||||
}
|
||||
|
||||
function onParagraphStyleModified(styleName) {
|
||||
self.emit(EditorSession.signalParagraphStyleModified, styleName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all subscribers for the given event with the specified argument
|
||||
* @param {!string} eventid
|
||||
* @param {Object} args
|
||||
*/
|
||||
this.emit = function (eventid, args) {
|
||||
eventNotifier.emit(eventid, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribe to a given event with a callback
|
||||
* @param {!string} eventid
|
||||
* @param {!Function} cb
|
||||
*/
|
||||
this.subscribe = function (eventid, cb) {
|
||||
eventNotifier.subscribe(eventid, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} eventid
|
||||
* @param {!Function} cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.unsubscribe = function (eventid, cb) {
|
||||
eventNotifier.unsubscribe(eventid, cb);
|
||||
};
|
||||
|
||||
this.getCursorPosition = function () {
|
||||
return odtDocument.getCursorPosition(localMemberId);
|
||||
};
|
||||
|
||||
this.getCursorSelection = function () {
|
||||
return odtDocument.getCursorSelection(localMemberId);
|
||||
};
|
||||
|
||||
this.getOdfCanvas = function () {
|
||||
return odtDocument.getOdfCanvas();
|
||||
};
|
||||
|
||||
this.getCurrentParagraph = function () {
|
||||
return currentParagraphNode;
|
||||
};
|
||||
|
||||
this.getAvailableParagraphStyles = function () {
|
||||
return formatting.getAvailableParagraphStyles();
|
||||
};
|
||||
|
||||
this.getCurrentParagraphStyle = function () {
|
||||
return currentCommonStyleName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies the paragraph style with the given
|
||||
* style name to all the paragraphs within
|
||||
* the cursor selection.
|
||||
* @param {!string} styleName
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setCurrentParagraphStyle = function (styleName) {
|
||||
var range = odtDocument.getCursor(localMemberId).getSelectedRange(),
|
||||
paragraphs = odfUtils.getParagraphElements(range),
|
||||
opQueue = [];
|
||||
|
||||
paragraphs.forEach(function (paragraph) {
|
||||
var paragraphStartPoint = odtDocument.convertDomPointToCursorStep(paragraph, 0, NEXT),
|
||||
paragraphStyleName = paragraph.getAttributeNS(odf.Namespaces.textns, "style-name"),
|
||||
opSetParagraphStyle;
|
||||
|
||||
if (paragraphStyleName !== styleName) {
|
||||
opSetParagraphStyle = new ops.OpSetParagraphStyle();
|
||||
opSetParagraphStyle.init({
|
||||
memberid: localMemberId,
|
||||
styleName: styleName,
|
||||
position: paragraphStartPoint
|
||||
});
|
||||
opQueue.push(opSetParagraphStyle);
|
||||
}
|
||||
});
|
||||
|
||||
if (opQueue.length > 0) {
|
||||
session.enqueue(opQueue);
|
||||
}
|
||||
};
|
||||
|
||||
this.insertTable = function (initialRows, initialColumns, tableStyleName, tableColumnStyleName, tableCellStyleMatrix) {
|
||||
var op = new ops.OpInsertTable();
|
||||
op.init({
|
||||
memberid: localMemberId,
|
||||
position: self.getCursorPosition(),
|
||||
initialRows: initialRows,
|
||||
initialColumns: initialColumns,
|
||||
tableStyleName: tableStyleName,
|
||||
tableColumnStyleName: tableColumnStyleName,
|
||||
tableCellStyleMatrix: tableCellStyleMatrix
|
||||
});
|
||||
session.enqueue([op]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a style name and returns the corresponding paragraph style
|
||||
* element. If the style name is an empty string, the default style
|
||||
* is returned.
|
||||
* @param {!string} styleName
|
||||
* @return {?Element}
|
||||
*/
|
||||
function getParagraphStyleElement(styleName) {
|
||||
return (styleName === "")
|
||||
? formatting.getDefaultStyleElement('paragraph')
|
||||
: formatting.getStyleElement(styleName, 'paragraph');
|
||||
}
|
||||
|
||||
this.getParagraphStyleElement = getParagraphStyleElement;
|
||||
|
||||
/**
|
||||
* Returns if the style is used anywhere in the document
|
||||
* @param {!Element} styleElement
|
||||
* @return {boolean}
|
||||
*/
|
||||
this.isStyleUsed = function (styleElement) {
|
||||
return formatting.isStyleUsed(styleElement);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the attributes of a given paragraph style name
|
||||
* (with inheritance). If the name is an empty string,
|
||||
* the attributes of the default style are returned.
|
||||
* @param {!string} styleName
|
||||
* @return {?odf.Formatting.StyleData}
|
||||
*/
|
||||
this.getParagraphStyleAttributes = function (styleName) {
|
||||
var styleNode = getParagraphStyleElement(styleName),
|
||||
includeSystemDefault = styleName === "";
|
||||
|
||||
if (styleNode) {
|
||||
return formatting.getInheritedStyleAttributes(styleNode, includeSystemDefault);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates and enqueues a paragraph-style cloning operation.
|
||||
* Returns the created id for the new style.
|
||||
* @param {!string} styleName id of the style to update
|
||||
* @param {!{paragraphProperties,textProperties}} setProperties properties which are set
|
||||
* @param {!{paragraphPropertyNames,textPropertyNames}=} removedProperties properties which are removed
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.updateParagraphStyle = function (styleName, setProperties, removedProperties) {
|
||||
var op;
|
||||
op = new ops.OpUpdateParagraphStyle();
|
||||
op.init({
|
||||
memberid: localMemberId,
|
||||
styleName: styleName,
|
||||
setProperties: setProperties,
|
||||
removedProperties: (!removedProperties) ? {} : removedProperties
|
||||
});
|
||||
session.enqueue([op]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates and enqueues a paragraph-style cloning operation.
|
||||
* Returns the created id for the new style.
|
||||
* @param {!string} styleName id of the style to clone
|
||||
* @param {!string} newStyleDisplayName display name of the new style
|
||||
* @return {!string}
|
||||
*/
|
||||
this.cloneParagraphStyle = function (styleName, newStyleDisplayName) {
|
||||
var newStyleName = uniqueParagraphStyleNCName(newStyleDisplayName),
|
||||
styleNode = getParagraphStyleElement(styleName),
|
||||
op, setProperties, attributes, i;
|
||||
|
||||
setProperties = formatting.getStyleAttributes(styleNode);
|
||||
// copy any attributes directly on the style
|
||||
attributes = styleNode.attributes;
|
||||
for (i = 0; i < attributes.length; i += 1) {
|
||||
// skip...
|
||||
// * style:display-name -> not copied, set to new string below
|
||||
// * style:name -> not copied, set from op by styleName property
|
||||
// * style:family -> "paragraph" always, set by op
|
||||
if (!/^(style:display-name|style:name|style:family)/.test(attributes[i].name)) {
|
||||
setProperties[attributes[i].name] = attributes[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
setProperties['style:display-name'] = newStyleDisplayName;
|
||||
|
||||
op = new ops.OpAddStyle();
|
||||
op.init({
|
||||
memberid: localMemberId,
|
||||
styleName: newStyleName,
|
||||
styleFamily: 'paragraph',
|
||||
setProperties: setProperties
|
||||
});
|
||||
session.enqueue([op]);
|
||||
|
||||
return newStyleName;
|
||||
};
|
||||
|
||||
this.deleteStyle = function (styleName) {
|
||||
var op;
|
||||
op = new ops.OpRemoveStyle();
|
||||
op.init({
|
||||
memberid: localMemberId,
|
||||
styleName: styleName,
|
||||
styleFamily: 'paragraph'
|
||||
});
|
||||
session.enqueue([op]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of the declared fonts in the ODF document,
|
||||
* with 'duplicates' like Arial1, Arial2, etc removed. The alphabetically
|
||||
* first font name for any given family is kept.
|
||||
* The elements of the array are objects containing the font's name and
|
||||
* the family.
|
||||
* @return {Array.<!Object>}
|
||||
*/
|
||||
this.getDeclaredFonts = function () {
|
||||
var fontMap = formatting.getFontMap(),
|
||||
usedFamilies = [],
|
||||
array = [],
|
||||
sortedNames,
|
||||
key,
|
||||
value,
|
||||
i;
|
||||
|
||||
// Sort all the keys in the font map alphabetically
|
||||
sortedNames = Object.keys(fontMap);
|
||||
sortedNames.sort();
|
||||
|
||||
for (i = 0; i < sortedNames.length; i += 1) {
|
||||
key = sortedNames[i];
|
||||
value = fontMap[key];
|
||||
|
||||
// Use the font declaration only if the family is not already used.
|
||||
// Therefore we are able to discard the alphabetic successors of the first
|
||||
// font name.
|
||||
if (usedFamilies.indexOf(value) === -1) {
|
||||
array.push({
|
||||
name: key,
|
||||
family: value
|
||||
});
|
||||
if (value) {
|
||||
usedFamilies.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
this.getSelectedHyperlinks = function () {
|
||||
var cursor = odtDocument.getCursor(localMemberId);
|
||||
// no own cursor yet/currently added?
|
||||
if (!cursor) {
|
||||
return [];
|
||||
}
|
||||
return odfUtils.getHyperlinkElements(cursor.getSelectedRange());
|
||||
};
|
||||
|
||||
this.getSelectedRange = function () {
|
||||
var cursor = odtDocument.getCursor(localMemberId);
|
||||
return cursor && cursor.getSelectedRange();
|
||||
};
|
||||
|
||||
function undoStackModified(e) {
|
||||
self.emit(EditorSession.signalUndoStackChanged, e);
|
||||
}
|
||||
|
||||
this.undo = function () {
|
||||
self.sessionController.undo();
|
||||
};
|
||||
|
||||
this.redo = function () {
|
||||
self.sessionController.redo();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {?ops.Member}
|
||||
*/
|
||||
this.getMember = function (memberId) {
|
||||
return odtDocument.getMember(memberId);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!function(!Object=)} callback passing an error object in case of error
|
||||
* @return {undefined}
|
||||
*/
|
||||
function destroy(callback) {
|
||||
var head = document.getElementsByTagName('head')[0],
|
||||
eventManager = self.sessionController.getEventManager();
|
||||
|
||||
head.removeChild(fontStyles);
|
||||
|
||||
odtDocument.unsubscribe(ops.Document.signalMemberAdded, onMemberAdded);
|
||||
odtDocument.unsubscribe(ops.Document.signalMemberUpdated, onMemberUpdated);
|
||||
odtDocument.unsubscribe(ops.Document.signalMemberRemoved, onMemberRemoved);
|
||||
odtDocument.unsubscribe(ops.Document.signalCursorAdded, onCursorAdded);
|
||||
odtDocument.unsubscribe(ops.Document.signalCursorRemoved, onCursorRemoved);
|
||||
odtDocument.unsubscribe(ops.Document.signalCursorMoved, onCursorMoved);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCommonStyleCreated, onStyleCreated);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalCommonStyleDeleted, onStyleDeleted);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalParagraphChanged, trackCurrentParagraph);
|
||||
odtDocument.unsubscribe(ops.OdtDocument.signalUndoStackChanged, undoStackModified);
|
||||
|
||||
eventManager.unsubscribe("mousemove", hyperlinkTooltipView.showTooltip);
|
||||
eventManager.unsubscribe("mouseout", hyperlinkTooltipView.hideTooltip);
|
||||
delete self.sessionView;
|
||||
delete self.sessionController;
|
||||
callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!function(!Error=)} callback passing an error object in case of error
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.destroy = function(callback) {
|
||||
var cleanup = [
|
||||
self.sessionView.destroy,
|
||||
caretManager.destroy,
|
||||
selectionViewManager.destroy,
|
||||
self.sessionController.destroy,
|
||||
hyperlinkTooltipView.destroy,
|
||||
odfFieldView.destroy,
|
||||
destroy
|
||||
];
|
||||
|
||||
core.Async.destroyAll(cleanup, callback);
|
||||
};
|
||||
|
||||
function init() {
|
||||
var head = document.getElementsByTagName('head')[0],
|
||||
odfCanvas = session.getOdtDocument().getOdfCanvas(),
|
||||
eventManager;
|
||||
|
||||
// TODO: fonts.css should be rather done by odfCanvas, or?
|
||||
fontStyles.type = 'text/css';
|
||||
fontStyles.media = 'screen, print, handheld, projection';
|
||||
fontStyles.appendChild(document.createTextNode(fontsCSS));
|
||||
head.appendChild(fontStyles);
|
||||
|
||||
odfFieldView = new gui.OdfFieldView(odfCanvas);
|
||||
odfFieldView.showFieldHighlight();
|
||||
self.sessionController = new gui.SessionController(session, localMemberId, shadowCursor, {
|
||||
annotationsEnabled: config.annotationsEnabled,
|
||||
directTextStylingEnabled: config.directTextStylingEnabled,
|
||||
directParagraphStylingEnabled: config.directParagraphStylingEnabled
|
||||
});
|
||||
sessionConstraints = self.sessionController.getSessionConstraints();
|
||||
|
||||
eventManager = self.sessionController.getEventManager();
|
||||
hyperlinkTooltipView = new gui.HyperlinkTooltipView(odfCanvas,
|
||||
self.sessionController.getHyperlinkClickHandler().getModifier);
|
||||
eventManager.subscribe("mousemove", hyperlinkTooltipView.showTooltip);
|
||||
eventManager.subscribe("mouseout", hyperlinkTooltipView.hideTooltip);
|
||||
|
||||
caretManager = new gui.CaretManager(self.sessionController, odfCanvas.getViewport());
|
||||
selectionViewManager = new gui.SelectionViewManager(gui.SvgSelectionView);
|
||||
self.sessionView = new gui.SessionView(config.viewOptions, localMemberId, session, sessionConstraints, caretManager, selectionViewManager);
|
||||
self.availableFonts = getAvailableFonts();
|
||||
selectionViewManager.registerCursor(shadowCursor, true);
|
||||
|
||||
// Session Constraints can be applied once the controllers are instantiated.
|
||||
if (config.reviewModeEnabled) {
|
||||
// Disallow deleting other authors' annotations.
|
||||
sessionConstraints.setState(gui.CommonConstraints.EDIT.ANNOTATIONS.ONLY_DELETE_OWN, true);
|
||||
sessionConstraints.setState(gui.CommonConstraints.EDIT.REVIEW_MODE, true);
|
||||
}
|
||||
|
||||
// Custom signals, that make sense in the Editor context. We do not want to expose webodf's ops signals to random bits of the editor UI.
|
||||
odtDocument.subscribe(ops.Document.signalMemberAdded, onMemberAdded);
|
||||
odtDocument.subscribe(ops.Document.signalMemberUpdated, onMemberUpdated);
|
||||
odtDocument.subscribe(ops.Document.signalMemberRemoved, onMemberRemoved);
|
||||
odtDocument.subscribe(ops.Document.signalCursorAdded, onCursorAdded);
|
||||
odtDocument.subscribe(ops.Document.signalCursorRemoved, onCursorRemoved);
|
||||
odtDocument.subscribe(ops.Document.signalCursorMoved, onCursorMoved);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCommonStyleCreated, onStyleCreated);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalCommonStyleDeleted, onStyleDeleted);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalParagraphStyleModified, onParagraphStyleModified);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalParagraphChanged, trackCurrentParagraph);
|
||||
odtDocument.subscribe(ops.OdtDocument.signalUndoStackChanged, undoStackModified);
|
||||
}
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
/**@const*/EditorSession.signalMemberAdded = "memberAdded";
|
||||
/**@const*/EditorSession.signalMemberUpdated = "memberUpdated";
|
||||
/**@const*/EditorSession.signalMemberRemoved = "memberRemoved";
|
||||
/**@const*/EditorSession.signalCursorAdded = "cursorAdded";
|
||||
/**@const*/EditorSession.signalCursorRemoved = "cursorRemoved";
|
||||
/**@const*/EditorSession.signalCursorMoved = "cursorMoved";
|
||||
/**@const*/EditorSession.signalParagraphChanged = "paragraphChanged";
|
||||
/**@const*/EditorSession.signalCommonStyleCreated = "styleCreated";
|
||||
/**@const*/EditorSession.signalCommonStyleDeleted = "styleDeleted";
|
||||
/**@const*/EditorSession.signalParagraphStyleModified = "paragraphStyleModified";
|
||||
/**@const*/EditorSession.signalUndoStackChanged = "signalUndoStackChanged";
|
||||
|
||||
return EditorSession;
|
||||
});
|
83
api/js/webodf/collab/FullWindowZoomHelper.js
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (C) 2014 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, document, window */
|
||||
|
||||
define("webodf/editor/FullWindowZoomHelper", [], function () {
|
||||
"use strict";
|
||||
|
||||
// fullscreen pinch-zoom adaption
|
||||
var FullWindowZoomHelper = function FullWindowZoomHelper(toolbarContainerElement, canvasContainerElement) {
|
||||
|
||||
function translateToolbar() {
|
||||
var y = document.body.scrollTop;
|
||||
|
||||
toolbarContainerElement.style.WebkitTransformOrigin = "center top";
|
||||
toolbarContainerElement.style.WebkitTransform = 'translateY(' + y + 'px)';
|
||||
}
|
||||
|
||||
function repositionContainer() {
|
||||
canvasContainerElement.style.top = toolbarContainerElement.getBoundingClientRect().height + 'px';
|
||||
}
|
||||
|
||||
this.destroy = function (callback) {
|
||||
window.removeEventListener('scroll', translateToolbar);
|
||||
window.removeEventListener('focusout', translateToolbar);
|
||||
window.removeEventListener('touchmove', translateToolbar);
|
||||
window.removeEventListener('resize', repositionContainer);
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
function init() {
|
||||
var metaElement, toolbarStyle;
|
||||
|
||||
// prevent any zooming on the window TODO: do not overwrite any other existing content of viewport metadata
|
||||
metaElement = document.createElement("meta");
|
||||
metaElement.setAttribute("name", "viewport");
|
||||
metaElement.setAttribute("content", "width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0");
|
||||
document.head.appendChild(metaElement);
|
||||
|
||||
// set the toolbar absolute and fixed to top
|
||||
toolbarStyle = toolbarContainerElement.style;
|
||||
toolbarStyle.top = 0;
|
||||
toolbarStyle.left = 0;
|
||||
toolbarStyle.right = 0;
|
||||
toolbarStyle.position = "absolute";
|
||||
toolbarStyle.zIndex = 5;
|
||||
toolbarStyle.boxShadow = "0 1px 5px rgba(0, 0, 0, 0.25)";
|
||||
|
||||
repositionContainer();
|
||||
|
||||
window.addEventListener('scroll', translateToolbar);
|
||||
window.addEventListener('focusout', translateToolbar);
|
||||
window.addEventListener('touchmove', translateToolbar);
|
||||
window.addEventListener('resize', repositionContainer);
|
||||
}
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
return FullWindowZoomHelper;
|
||||
});
|
189
api/js/webodf/collab/MemberListView.js
Normal file
@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define,runtime */
|
||||
|
||||
define("webodf/editor/MemberListView",
|
||||
["webodf/editor/EditorSession"],
|
||||
|
||||
function (EditorSession) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @param {!Element} memberListDiv
|
||||
* @constructor
|
||||
*/
|
||||
return function MemberListView(memberListDiv) {
|
||||
var editorSession = null;
|
||||
|
||||
runtime.assert(memberListDiv, "memberListDiv unavailable");
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {undefined}
|
||||
*/
|
||||
function updateAvatarButton(memberId, memberDetails) {
|
||||
var node = memberListDiv.firstChild;
|
||||
|
||||
// this takes care of incorrectly implemented MemberModels,
|
||||
// which might end up returning undefined member data
|
||||
if (!memberDetails) {
|
||||
runtime.log("MemberModel sent undefined data for member \"" + memberId + "\".");
|
||||
return;
|
||||
}
|
||||
|
||||
while (node) {
|
||||
if (node.memberId === memberId) {
|
||||
node = node.firstChild;
|
||||
while (node) {
|
||||
if (node.localName === "img") {
|
||||
// update avatar image
|
||||
node.src = memberDetails.imageUrl;
|
||||
// update border color
|
||||
node.style.borderColor = memberDetails.color;
|
||||
} else if (node.localName === "div") {
|
||||
node.setAttribute('fullname', memberDetails.fullName);
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
return;
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {undefined}
|
||||
*/
|
||||
function createAvatarButton(memberId) {
|
||||
var doc = memberListDiv.ownerDocument,
|
||||
htmlns = doc.documentElement.namespaceURI,
|
||||
avatarDiv = doc.createElementNS(htmlns, "div"),
|
||||
imageElement = doc.createElement("img"),
|
||||
fullnameNode = doc.createElement("div");
|
||||
|
||||
avatarDiv.className = "webodfeditor-memberListButton";
|
||||
fullnameNode.className = "webodfeditor-memberListLabel";
|
||||
avatarDiv.appendChild(imageElement);
|
||||
avatarDiv.appendChild(fullnameNode);
|
||||
avatarDiv.memberId = memberId; // TODO: namespace?
|
||||
|
||||
avatarDiv.onclick = function () {
|
||||
var caret = editorSession.sessionView.getCaret(memberId);
|
||||
if (caret) {
|
||||
caret.toggleHandleVisibility();
|
||||
}
|
||||
};
|
||||
memberListDiv.appendChild(avatarDiv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {undefined}
|
||||
*/
|
||||
function removeAvatarButton(memberId) {
|
||||
var node = memberListDiv.firstChild;
|
||||
while (node) {
|
||||
if (node.memberId === memberId) {
|
||||
memberListDiv.removeChild(node);
|
||||
return;
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {undefined}
|
||||
*/
|
||||
function addMember(memberId) {
|
||||
var member = editorSession.getMember(memberId),
|
||||
properties = member.getProperties();
|
||||
createAvatarButton(memberId);
|
||||
updateAvatarButton(memberId, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {undefined}
|
||||
*/
|
||||
function updateMember(memberId) {
|
||||
var member = editorSession.getMember(memberId),
|
||||
properties = member.getProperties();
|
||||
|
||||
updateAvatarButton(memberId, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} memberId
|
||||
* @return {undefined}
|
||||
*/
|
||||
function removeMember(memberId) {
|
||||
removeAvatarButton(memberId);
|
||||
}
|
||||
|
||||
function disconnectFromEditorSession() {
|
||||
var node, nextNode;
|
||||
|
||||
if (editorSession) {
|
||||
// unsubscribe from editorSession
|
||||
editorSession.unsubscribe(EditorSession.signalMemberAdded, addMember);
|
||||
editorSession.unsubscribe(EditorSession.signalMemberUpdated, updateMember);
|
||||
editorSession.unsubscribe(EditorSession.signalMemberRemoved, removeMember);
|
||||
// remove all current avatars
|
||||
node = memberListDiv.firstChild;
|
||||
while (node) {
|
||||
nextNode = node.nextSibling;
|
||||
memberListDiv.removeChild(node);
|
||||
node = nextNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!EditorSession} session
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setEditorSession = function(session) {
|
||||
disconnectFromEditorSession();
|
||||
|
||||
editorSession = session;
|
||||
if (editorSession) {
|
||||
editorSession.subscribe(EditorSession.signalMemberAdded, addMember);
|
||||
editorSession.subscribe(EditorSession.signalMemberUpdated, updateMember);
|
||||
editorSession.subscribe(EditorSession.signalMemberRemoved, removeMember);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!function(!Error=)} callback, passing an error object in case of error
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.destroy = function (callback) {
|
||||
disconnectFromEditorSession();
|
||||
callback();
|
||||
};
|
||||
};
|
||||
});
|
105
api/js/webodf/collab/SessionListView.js
Normal file
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Copyright (C) 2012-2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global Node, define, runtime */
|
||||
|
||||
define("webodf/editor/SessionListView", [], function () {
|
||||
"use strict";
|
||||
|
||||
return function SessionListView(sessionList, sessionListDiv, cb) {
|
||||
|
||||
function createSessionDescription(sessionDetails) {
|
||||
return " (" + sessionDetails.cursors.length + " members) ";
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function createSessionViewItem(sessionDetails) {
|
||||
runtime.assert(sessionListDiv, "sessionListDiv unavailable");
|
||||
var doc = sessionListDiv.ownerDocument,
|
||||
htmlns = doc.documentElement.namespaceURI,
|
||||
sessionDiv = doc.createElementNS(htmlns, "div"),
|
||||
sessionDescriptionDiv = doc.createElementNS(htmlns, "span"),
|
||||
sessionDownloadDiv;
|
||||
|
||||
sessionDiv.sessionId = sessionDetails.id; // TODO: namespace?
|
||||
sessionDiv.appendChild(sessionDescriptionDiv);
|
||||
sessionDiv.appendChild(doc.createTextNode(createSessionDescription(sessionDetails)));
|
||||
|
||||
sessionDescriptionDiv.appendChild(doc.createTextNode(sessionDetails.title));
|
||||
sessionDescriptionDiv.style.cursor = "pointer"; // TODO: do not set on each element, use CSS
|
||||
sessionDescriptionDiv.style.fontWeight = "bold";
|
||||
sessionDescriptionDiv.onclick = function () {
|
||||
cb(sessionDetails.id);
|
||||
};
|
||||
|
||||
if (sessionDetails.fileUrl) {
|
||||
sessionDownloadDiv = doc.createElementNS(htmlns, "a");
|
||||
sessionDownloadDiv.appendChild(doc.createTextNode("Download"));
|
||||
sessionDownloadDiv.setAttribute("href", sessionDetails.fileUrl);
|
||||
sessionDiv.appendChild(sessionDownloadDiv);
|
||||
}
|
||||
|
||||
sessionListDiv.appendChild(sessionDiv);
|
||||
}
|
||||
|
||||
function updateSessionViewItem(sessionDetails) {
|
||||
var node = sessionListDiv.firstChild;
|
||||
while (node) {
|
||||
if (node.sessionId === sessionDetails.id) {
|
||||
node.firstChild.nextSibling.data = createSessionDescription(sessionDetails);
|
||||
return;
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} sessionId
|
||||
*/
|
||||
function removeSessionViewItem(sessionId) {
|
||||
var node = sessionListDiv.firstChild;
|
||||
while (node) {
|
||||
if (node.sessionId === sessionId) {
|
||||
sessionListDiv.removeChild(node);
|
||||
return;
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
var idx,
|
||||
subscriber = {onCreated: createSessionViewItem, onUpdated: updateSessionViewItem, onRemoved: removeSessionViewItem},
|
||||
sessions = sessionList.getSessions(subscriber);
|
||||
|
||||
// fill session list
|
||||
for (idx = 0; idx < sessions.length; idx += 1) {
|
||||
createSessionViewItem(sessions[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
};
|
||||
});
|
292
api/js/webodf/collab/Tools.js
Normal file
@ -0,0 +1,292 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, document, dijit, dojo, runtime, ops*/
|
||||
|
||||
define("webodf/editor/Tools", [
|
||||
"dojo/ready",
|
||||
"dijit/MenuItem",
|
||||
"dijit/DropDownMenu",
|
||||
"dijit/form/Button",
|
||||
"dijit/form/DropDownButton",
|
||||
"dijit/Toolbar",
|
||||
"webodf/editor/widgets/paragraphAlignment",
|
||||
"webodf/editor/widgets/simpleStyles",
|
||||
"webodf/editor/widgets/undoRedoMenu",
|
||||
"webodf/editor/widgets/toolbarWidgets/currentStyle",
|
||||
"webodf/editor/widgets/annotation",
|
||||
"webodf/editor/widgets/editHyperlinks",
|
||||
"webodf/editor/widgets/imageInserter",
|
||||
"webodf/editor/widgets/paragraphStylesDialog",
|
||||
"webodf/editor/widgets/zoomSlider",
|
||||
"webodf/editor/widgets/aboutDialog",
|
||||
"webodf/editor/EditorSession"],
|
||||
function (ready, MenuItem, DropDownMenu, Button, DropDownButton, Toolbar, ParagraphAlignment, SimpleStyles, UndoRedoMenu, CurrentStyle, AnnotationControl, EditHyperlinks, ImageInserter, ParagraphStylesDialog, ZoomSlider, AboutDialog, EditorSession) {
|
||||
"use strict";
|
||||
|
||||
return function Tools(toolbarElementId, args) {
|
||||
var tr = runtime.tr,
|
||||
onToolDone = args.onToolDone,
|
||||
loadOdtFile = args.loadOdtFile,
|
||||
saveOdtFile = args.saveOdtFile,
|
||||
saveAsOdtFile = args.saveAsOdtFile,
|
||||
downloadOdtFile = args.downloadOdtFile,
|
||||
close = args.close,
|
||||
toolbar,
|
||||
loadButton, saveButton, closeButton, aboutButton,
|
||||
saveAsButton, downloadButton,
|
||||
formatDropDownMenu, formatMenuButton,
|
||||
paragraphStylesMenuItem, paragraphStylesDialog,
|
||||
editorSession,
|
||||
aboutDialog,
|
||||
sessionSubscribers = [];
|
||||
|
||||
/**
|
||||
* Creates a tool and installs it, if the enabled flag is set to true.
|
||||
* Only supports tool classes whose constructor has a single argument which
|
||||
* is a callback to pass the created widget object to.
|
||||
* @param {!function(new:Object, function(!Object):undefined)} Tool constructor method of the tool
|
||||
* @param {!boolean} enabled
|
||||
* @return {?Object}
|
||||
*/
|
||||
function createTool(Tool, enabled) {
|
||||
var tool = null;
|
||||
|
||||
if (enabled) {
|
||||
tool = new Tool(function (widget) {
|
||||
widget.placeAt(toolbar);
|
||||
widget.startup();
|
||||
});
|
||||
sessionSubscribers.push(tool);
|
||||
tool.onToolDone = onToolDone;
|
||||
}
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
function handleCursorMoved(cursor) {
|
||||
var disabled = cursor.getSelectionType() === ops.OdtCursor.RegionSelection;
|
||||
if (formatMenuButton) {
|
||||
formatMenuButton.setAttribute('disabled', disabled);
|
||||
}
|
||||
}
|
||||
|
||||
function setEditorSession(session) {
|
||||
if (editorSession) {
|
||||
editorSession.unsubscribe(EditorSession.signalCursorMoved, handleCursorMoved);
|
||||
}
|
||||
|
||||
editorSession = session;
|
||||
if (editorSession) {
|
||||
editorSession.subscribe(EditorSession.signalCursorMoved, handleCursorMoved);
|
||||
}
|
||||
|
||||
sessionSubscribers.forEach(function (subscriber) {
|
||||
subscriber.setEditorSession(editorSession);
|
||||
});
|
||||
|
||||
[saveButton, saveAsButton, downloadButton, closeButton, formatMenuButton].forEach(function (button) {
|
||||
if (button) {
|
||||
button.setAttribute('disabled', !editorSession);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.setEditorSession = setEditorSession;
|
||||
|
||||
/**
|
||||
* @param {!function(!Error=)} callback, passing an error object in case of error
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.destroy = function (callback) {
|
||||
// TODO:
|
||||
// 1. We don't want to use `document`
|
||||
// 2. We would like to avoid deleting all widgets
|
||||
// under document.body because this might interfere with
|
||||
// other apps that use the editor not-in-an-iframe,
|
||||
// but dojo always puts its dialogs below the body,
|
||||
// so this works for now. Perhaps will be obsoleted
|
||||
// once we move to a better widget toolkit
|
||||
var widgets = dijit.findWidgets(document.body);
|
||||
dojo.forEach(widgets, function(w) {
|
||||
w.destroyRecursive(false);
|
||||
});
|
||||
callback();
|
||||
};
|
||||
|
||||
// init
|
||||
ready(function () {
|
||||
toolbar = new Toolbar({}, toolbarElementId);
|
||||
|
||||
// About
|
||||
if (args.aboutEnabled) {
|
||||
aboutButton = new Button({
|
||||
label: tr('About WebODF Text Editor'),
|
||||
showLabel: false,
|
||||
iconClass: 'webodfeditor-dijitWebODFIcon'
|
||||
});
|
||||
aboutDialog = new AboutDialog(function (dialog) {
|
||||
aboutButton.onClick = function () {
|
||||
dialog.startup();
|
||||
dialog.show();
|
||||
};
|
||||
});
|
||||
aboutDialog.onToolDone = onToolDone;
|
||||
aboutButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
// Load
|
||||
if (loadOdtFile) {
|
||||
loadButton = new Button({
|
||||
label: tr('Open'),
|
||||
showLabel: false,
|
||||
iconClass: 'dijitIcon dijitIconFolderOpen',
|
||||
onClick: function () {
|
||||
loadOdtFile();
|
||||
}
|
||||
});
|
||||
loadButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
// Save
|
||||
if (saveOdtFile) {
|
||||
saveButton = new Button({
|
||||
label: tr('Save'),
|
||||
showLabel: false,
|
||||
disabled: true,
|
||||
iconClass: 'dijitEditorIcon dijitEditorIconSave',
|
||||
onClick: function () {
|
||||
saveOdtFile();
|
||||
onToolDone();
|
||||
}
|
||||
});
|
||||
saveButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
// SaveAs
|
||||
if (saveAsOdtFile) {
|
||||
saveAsButton = new Button({
|
||||
label: tr('Save as...'),
|
||||
showLabel: false,
|
||||
disabled: true,
|
||||
iconClass: 'webodfeditor-dijitSaveAsIcon',
|
||||
onClick: function () {
|
||||
saveAsOdtFile();
|
||||
onToolDone();
|
||||
}
|
||||
});
|
||||
saveAsButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
// Download
|
||||
if (downloadOdtFile) {
|
||||
downloadButton = new Button({
|
||||
label: tr('Download'),
|
||||
showLabel: true,
|
||||
disabled: true,
|
||||
style: {
|
||||
float: 'right'
|
||||
},
|
||||
onClick: function () {
|
||||
downloadOdtFile();
|
||||
onToolDone();
|
||||
}
|
||||
});
|
||||
downloadButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
// Format menu
|
||||
if (args.paragraphStyleEditingEnabled) {
|
||||
formatDropDownMenu = new DropDownMenu({});
|
||||
paragraphStylesMenuItem = new MenuItem({
|
||||
label: tr("Paragraph...")
|
||||
});
|
||||
formatDropDownMenu.addChild(paragraphStylesMenuItem);
|
||||
|
||||
paragraphStylesDialog = new ParagraphStylesDialog(function (dialog) {
|
||||
paragraphStylesMenuItem.onClick = function () {
|
||||
if (editorSession) {
|
||||
dialog.startup();
|
||||
dialog.show();
|
||||
}
|
||||
};
|
||||
});
|
||||
sessionSubscribers.push(paragraphStylesDialog);
|
||||
paragraphStylesDialog.onToolDone = onToolDone;
|
||||
|
||||
formatMenuButton = new DropDownButton({
|
||||
dropDown: formatDropDownMenu,
|
||||
disabled: true,
|
||||
label: tr('Format'),
|
||||
iconClass: "dijitIconEditTask"
|
||||
});
|
||||
formatMenuButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
// Undo/Redo
|
||||
createTool(UndoRedoMenu, args.undoRedoEnabled);
|
||||
|
||||
// Add annotation
|
||||
createTool(AnnotationControl, args.annotationsEnabled);
|
||||
|
||||
// Simple Style Selector [B, I, U, S]
|
||||
createTool(SimpleStyles, args.directTextStylingEnabled);
|
||||
|
||||
// Paragraph direct alignment buttons
|
||||
createTool(ParagraphAlignment, args.directParagraphStylingEnabled);
|
||||
|
||||
// Paragraph Style Selector
|
||||
createTool(CurrentStyle, args.paragraphStyleSelectingEnabled);
|
||||
|
||||
// Zoom Level Selector
|
||||
createTool(ZoomSlider, args.zoomingEnabled);
|
||||
|
||||
// hyper links
|
||||
createTool(EditHyperlinks, args.hyperlinkEditingEnabled);
|
||||
|
||||
// image insertion
|
||||
createTool(ImageInserter, args.imageInsertingEnabled);
|
||||
|
||||
// close button
|
||||
if (close) {
|
||||
closeButton = new Button({
|
||||
label: tr('Close'),
|
||||
showLabel: false,
|
||||
disabled: true,
|
||||
iconClass: 'dijitEditorIcon dijitEditorIconCancel',
|
||||
style: {
|
||||
float: 'right'
|
||||
},
|
||||
onClick: function () {
|
||||
close();
|
||||
}
|
||||
});
|
||||
closeButton.placeAt(toolbar);
|
||||
}
|
||||
|
||||
setEditorSession(editorSession);
|
||||
});
|
||||
};
|
||||
|
||||
});
|
81
api/js/webodf/collab/Translator.js
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, runtime, XMLHttpRequest */
|
||||
|
||||
define("webodf/editor/Translator", [], function () {
|
||||
"use strict";
|
||||
|
||||
return function Translator(translationsPath, locale, callback) {
|
||||
var self = this,
|
||||
dictionary = {};
|
||||
|
||||
function translate(key) {
|
||||
return dictionary[key];
|
||||
}
|
||||
function setLocale(newLocale, cb) {
|
||||
// TODO: Add smarter locale resolution at some point
|
||||
if (newLocale.split('-')[0] === "de" || newLocale.split('_')[0] === "de") {
|
||||
newLocale = "de-DE";
|
||||
} else if (newLocale.split('-')[0] === "nl" || newLocale.split('_')[0] === "nl") {
|
||||
newLocale = "nl-NL";
|
||||
} else if (newLocale.split('-')[0] === "fr" || newLocale.split('_')[0] === "fr") {
|
||||
newLocale = "fr-FR";
|
||||
} else if (newLocale.split('-')[0] === "it" || newLocale.split('_')[0] === "it") {
|
||||
newLocale = "it-IT";
|
||||
} else if (newLocale.split('-')[0] === "eu" || newLocale.split('_')[0] === "eu") {
|
||||
newLocale = "eu";
|
||||
} else if (newLocale.split('-')[0] === "en" || newLocale.split('_')[0] === "en") {
|
||||
newLocale = "en-US";
|
||||
} else {
|
||||
newLocale = "en-US";
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest(),
|
||||
path = translationsPath + '/' + newLocale + ".json";
|
||||
xhr.open("GET", path);
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200) {// HTTP OK
|
||||
dictionary = JSON.parse(xhr.response);
|
||||
locale = newLocale;
|
||||
}
|
||||
cb();
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
function getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
this.translate = translate;
|
||||
this.getLocale = getLocale;
|
||||
|
||||
function init() {
|
||||
setLocale(locale, function () {
|
||||
callback(self);
|
||||
});
|
||||
}
|
||||
init();
|
||||
};
|
||||
});
|
1
api/js/webodf/collab/app/resources/app.css
Normal file
BIN
api/js/webodf/collab/avatar-joe.png
Normal file
After Width: | Height: | Size: 30 KiB |
72
api/js/webodf/collab/backend/Server.js
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global ops*/
|
||||
/*jslint emptyblock: true, unparam: true*/
|
||||
|
||||
/**
|
||||
* Network status has three possible values: "unavailable", "timeout", "ready"
|
||||
* @interface
|
||||
*/
|
||||
ops.Server = function Server() {"use strict"; };
|
||||
|
||||
|
||||
/**
|
||||
* @param {!number} timeout in milliseconds
|
||||
* @param {!function(!string)} cb reports the state: "unavailable", "timeout", "ready"
|
||||
* @return {undefined}
|
||||
*/
|
||||
ops.Server.prototype.connect = function (timeout, cb) {"use strict"; };
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
ops.Server.prototype.networkStatus = function () {"use strict"; };
|
||||
|
||||
/**
|
||||
* @param {!string} login
|
||||
* @param {!string} password
|
||||
* @param {function(!Object)} successCb
|
||||
* @param {function(!string)} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
ops.Server.prototype.login = function (login, password, successCb, failCb) {"use strict"; };
|
||||
|
||||
/**
|
||||
* @param {!string} userId TODO: should the server not rather cache that info after login as property?
|
||||
* @param {!string} sessionId
|
||||
* @param {!function(!string)} successCb
|
||||
* @param {!function()} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
ops.Server.prototype.joinSession = function (userId, sessionId, successCb, failCb) {"use strict"; };
|
||||
|
||||
/**
|
||||
* @param {!string} sessionId
|
||||
* @param {!string} memberId
|
||||
* @param {!function(!string)} successCb
|
||||
* @param {!function()} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
ops.Server.prototype.leaveSession = function (sessionId, memberId, successCb, failCb) {"use strict"; };
|
50
api/js/webodf/collab/backend/ServerFactory.js
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global ops, SessionList*/
|
||||
/*jslint emptyblock: true, unparam: true*/
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
function ServerFactory() {"use strict"; }
|
||||
|
||||
/**
|
||||
* @return {!ops.Server}
|
||||
*/
|
||||
ServerFactory.prototype.createServer = function () {"use strict"; };
|
||||
|
||||
/**
|
||||
* @param {!string} sessionId
|
||||
* @param {!string} memberId
|
||||
* @param {!ops.Server} server
|
||||
* @return {!SessionBackend}
|
||||
*/
|
||||
ServerFactory.prototype.createSessionBackend = function (sessionId, memberId, server) {"use strict"; };
|
||||
|
||||
/**
|
||||
* @param {!ops.Server} server
|
||||
* @return {!SessionList}
|
||||
*/
|
||||
ServerFactory.prototype.createSessionList = function (server) {"use strict"; };
|
346
api/js/webodf/collab/backend/jsglobal/OperationRouter.js
Normal file
@ -0,0 +1,346 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, runtime, core, ops*/
|
||||
|
||||
define("webodf/editor/backend/jsglobal/OperationRouter", [], function () {
|
||||
"use strict";
|
||||
|
||||
var /**@const @type {!string}*/
|
||||
EVENT_BEFORESAVETOFILE = "beforeSaveToFile",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_SAVEDTOFILE = "savedToFile",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED = "hasLocalUnsyncedOperationsChanged",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_HASSESSIONHOSTCONNECTIONCHANGED = "hasSessionHostConnectionChanged";
|
||||
|
||||
runtime.loadClass("ops.OperationTransformer");
|
||||
runtime.loadClass("core.EventNotifier");
|
||||
runtime.loadClass("core.Task");
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements ops.OperationRouter
|
||||
*/
|
||||
return function JsGlobalOperationRouter(sessionId, memberId, server, errorCallback) {
|
||||
|
||||
var events = new core.EventNotifier([
|
||||
ops.OperationRouter.signalProcessingBatchStart,
|
||||
ops.OperationRouter.signalProcessingBatchEnd,
|
||||
EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED,
|
||||
EVENT_HASSESSIONHOSTCONNECTIONCHANGED,
|
||||
EVENT_BEFORESAVETOFILE,
|
||||
EVENT_SAVEDTOFILE
|
||||
]),
|
||||
/**@type{!ops.OperationFactory}*/
|
||||
operationFactory,
|
||||
playbackFunction,
|
||||
operationTransformer = new ops.OperationTransformer(),
|
||||
/**@type{number}*/
|
||||
groupIdentifier = 0,
|
||||
uploadingOpSpecCount,
|
||||
syncTask,
|
||||
unsyncedClientOpspecQueue = [],
|
||||
hasLocalUnsyncedOps = false,
|
||||
hasSessionHostConnection = true,
|
||||
hasUnresolvableConflict = false,
|
||||
syncInProgress = false,
|
||||
syncAttemptCompleteCallbacks = [],
|
||||
successfulSyncCallbacks = [],
|
||||
destroyed = false;
|
||||
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function updateUnsyncedOps() {
|
||||
var hasLocalUnsyncedOpsNow = (unsyncedClientOpspecQueue.length > 0);
|
||||
|
||||
// no change?
|
||||
if (hasLocalUnsyncedOps === hasLocalUnsyncedOpsNow) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasLocalUnsyncedOps = hasLocalUnsyncedOpsNow;
|
||||
events.emit(EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED, hasLocalUnsyncedOps);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!boolean}
|
||||
*/
|
||||
this.hasLocalUnsyncedOps = function() {
|
||||
return hasLocalUnsyncedOps;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!boolean} hasConnection
|
||||
* @return {undefined}
|
||||
*/
|
||||
function updateHasSessionHostConnectionState(hasConnection) {
|
||||
// no change?
|
||||
if (hasSessionHostConnection === hasConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasSessionHostConnection = hasConnection;
|
||||
events.emit(EVENT_HASSESSIONHOSTCONNECTIONCHANGED, hasSessionHostConnection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!boolean}
|
||||
*/
|
||||
this.hasSessionHostConnection = function () {
|
||||
return hasSessionHostConnection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the factory to use to create operation instances from operation specs.
|
||||
*
|
||||
* @param {!ops.OperationFactory} f
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setOperationFactory = function (f) {
|
||||
operationFactory = f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the method which should be called to apply operations.
|
||||
*
|
||||
* @param {!function(!ops.Operation):boolean} playback_func
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setPlaybackFunction = function (playback_func) {
|
||||
playbackFunction = playback_func;
|
||||
};
|
||||
|
||||
/**
|
||||
* Brings the locally created operations into the game.
|
||||
*
|
||||
* @param {!Array.<!{optype:!string}>} operationSpecs
|
||||
* @return {undefined}
|
||||
*/
|
||||
function executeOpSpecs(operationSpecs) {
|
||||
// This is an extremely simplistic and VERY temporary implementation of operation grouping.
|
||||
// In order to improve undo behaviour, the undo manager requires knowledge about what groups
|
||||
// of operations were queued together, so these can be stored in a single undo state.
|
||||
// The current implementation is only designed for a localeditor instance & the TrivialUndoManager.
|
||||
// TODO redesign this concept to work with collaborative editing
|
||||
groupIdentifier += 1;
|
||||
events.emit(ops.OperationRouter.signalProcessingBatchStart, {});
|
||||
operationSpecs.forEach(function (opspec) {
|
||||
var /**@type{?ops.Operation}*/
|
||||
timedOp;
|
||||
|
||||
timedOp = operationFactory.create(opspec);
|
||||
timedOp.group = "g" + groupIdentifier;
|
||||
|
||||
// TODO: handle return flag in error case
|
||||
playbackFunction(timedOp);
|
||||
});
|
||||
events.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes local operations and prepares to send to these to the collab server
|
||||
*
|
||||
* @param {!Array.<!ops.Operation>} operations
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.push = function (operations) {
|
||||
if (hasUnresolvableConflict) {
|
||||
throw new Error("unresolvableConflictingOps");
|
||||
}
|
||||
|
||||
var specs = [],
|
||||
timestamp = Date.now();
|
||||
|
||||
operations.forEach(function(op) {
|
||||
var spec = op.spec();
|
||||
spec.timestamp = timestamp;
|
||||
specs.push(spec);
|
||||
});
|
||||
|
||||
unsyncedClientOpspecQueue = unsyncedClientOpspecQueue.concat(specs);
|
||||
executeOpSpecs(specs);
|
||||
updateUnsyncedOps();
|
||||
syncTask.trigger();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function()} cb
|
||||
*/
|
||||
this.close = function (cb) {
|
||||
function internalDestroy() {
|
||||
destroyed = true;
|
||||
syncTask.destroy(cb);
|
||||
}
|
||||
syncAttemptCompleteCallbacks.push(internalDestroy);
|
||||
syncTask.triggerImmediate();
|
||||
if (!syncInProgress) {
|
||||
internalDestroy();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} eventId
|
||||
* @param {!Function} cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.subscribe = function (eventId, cb) {
|
||||
events.subscribe(eventId, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} eventId
|
||||
* @param {!Function} cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.unsubscribe = function (eventId, cb) {
|
||||
events.unsubscribe(eventId, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Complete the current synchronize request
|
||||
* @param {!boolean=} connectionState If specified, update the session host connection state.
|
||||
* @return {undefined}
|
||||
*/
|
||||
function completeSyncRequest(connectionState) {
|
||||
syncInProgress = false;
|
||||
updateUnsyncedOps();
|
||||
if (connectionState !== undefined) {
|
||||
updateHasSessionHostConnectionState(connectionState);
|
||||
}
|
||||
|
||||
syncAttemptCompleteCallbacks.forEach(function(cb) {
|
||||
cb();
|
||||
});
|
||||
syncAttemptCompleteCallbacks.length = 0;
|
||||
|
||||
if (!destroyed) {
|
||||
syncTask.cancel();
|
||||
syncTask.trigger();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a synchronization error and retry
|
||||
* @param {!Error} e
|
||||
* @return {undefined}
|
||||
*/
|
||||
function logErrorAndRetry(e) {
|
||||
var isConnected;
|
||||
switch (e.code) {
|
||||
case "SEQ_OUTOFDATE":
|
||||
// This error is an expected as part of normal operation. Don't bother logging
|
||||
isConnected = true;
|
||||
break;
|
||||
case "SERVICE_UNAVAILABLE":
|
||||
// This error is an expected as part of normal operation. Don't bother logging.
|
||||
// However, the error does indicate a connectivity problem with the session, so
|
||||
// ensure the connection status is updated
|
||||
isConnected = false;
|
||||
break;
|
||||
default:
|
||||
isConnected = false;
|
||||
runtime.log(e);
|
||||
break;
|
||||
}
|
||||
completeSyncRequest(isConnected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove synchronized client ops off the client queue
|
||||
* @return {undefined}
|
||||
*/
|
||||
function onPushSuccess() {
|
||||
// Only remove operations that have now been uploaded to the remote service
|
||||
unsyncedClientOpspecQueue.splice(0, uploadingOpSpecCount);
|
||||
completeSyncRequest(true);
|
||||
successfulSyncCallbacks.forEach(function(cb) {
|
||||
cb();
|
||||
});
|
||||
successfulSyncCallbacks.length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process remote changes
|
||||
* @param {!{specs: !Array.<!Object>, sequenceId: !Object}} remoteChanges
|
||||
* @return {undefined}
|
||||
*/
|
||||
function onRemoteChangesSuccess(remoteChanges) {
|
||||
var transformResult = operationTransformer.transform(unsyncedClientOpspecQueue, remoteChanges.specs);
|
||||
if (!transformResult) {
|
||||
hasUnresolvableConflict = true;
|
||||
errorCallback("unresolvableConflictingOps");
|
||||
completeSyncRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
if (transformResult.opSpecsB.length > 0) {
|
||||
// Apply remote changes that have been transformed against local updates
|
||||
executeOpSpecs(transformResult.opSpecsB);
|
||||
}
|
||||
|
||||
// The local client changes are now transformed against the current remote updates, and should not be transformed again.
|
||||
// Update the local sync queue with the translated results in case the push attempt fails due to a conflict
|
||||
unsyncedClientOpspecQueue = transformResult.opSpecsA;
|
||||
|
||||
// Send local changes that have been transformed against the remote updates
|
||||
uploadingOpSpecCount = unsyncedClientOpspecQueue.length;
|
||||
if (unsyncedClientOpspecQueue.length > 0) {
|
||||
server.getJsGlobalServer().push(sessionId, memberId, remoteChanges.sequenceId, unsyncedClientOpspecQueue, onPushSuccess, logErrorAndRetry);
|
||||
} else {
|
||||
onPushSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DO NOT CALL DIRECTLY, use syncTask.trigger instead.
|
||||
*
|
||||
* Synchronize the local state with the remote server. This is an async call and will return immediately, while
|
||||
* the processing occurs in the background.
|
||||
*
|
||||
* @return {undefined}
|
||||
*/
|
||||
function synchronizeWithServer() {
|
||||
if (hasUnresolvableConflict === false && syncInProgress === false) {
|
||||
syncInProgress = true;
|
||||
server.getJsGlobalServer().getRemoteChanges(sessionId, memberId, onRemoteChangesSuccess, logErrorAndRetry);
|
||||
}
|
||||
}
|
||||
|
||||
this.requestReplay = function(cb) {
|
||||
if (hasUnresolvableConflict) {
|
||||
throw new Error("unresolvableConflictingOps");
|
||||
}
|
||||
successfulSyncCallbacks.push(cb);
|
||||
syncTask.triggerImmediate();
|
||||
};
|
||||
|
||||
function init() {
|
||||
syncTask = core.Task.createTimeoutTask(synchronizeWithServer, 100);
|
||||
}
|
||||
init();
|
||||
};
|
||||
});
|
103
api/js/webodf/collab/backend/jsglobal/Server.js
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, window, runtime, core*/
|
||||
|
||||
define("webodf/editor/backend/jsglobal/Server", [], function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements ops.Server
|
||||
*/
|
||||
return function JsGlobalServer() {
|
||||
var jsGlobalInstance;
|
||||
|
||||
this.getGenesisUrl = function () {
|
||||
return "welcome.odt";
|
||||
};
|
||||
|
||||
this.getJsGlobalServer = function() {
|
||||
return jsGlobalInstance;
|
||||
};
|
||||
|
||||
/*jslint unparam: true*/
|
||||
/**
|
||||
* @param {!number} timeout in milliseconds
|
||||
* @param {!function(!string)} callback
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.connect = function (timeout, callback) {
|
||||
var interval = window.setInterval(function() {
|
||||
if (window.jsGlobalInstance) {
|
||||
jsGlobalInstance = window.jsGlobalInstance;
|
||||
window.clearInterval(interval);
|
||||
callback("ready");
|
||||
}
|
||||
// TODO properly timeout
|
||||
}, 100);
|
||||
};
|
||||
/*jslint unparam: false*/
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
this.networkStatus = function () {
|
||||
return "ready";
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} login
|
||||
* @param {!string} password
|
||||
* @param {function(!Object)} successCb
|
||||
* @param {function(!string)} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.login = function (login, password, successCb, failCb) {
|
||||
jsGlobalInstance.login(login, password, successCb, failCb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} userId
|
||||
* @param {!string} sessionId
|
||||
* @param {!function(!string)} successCb
|
||||
* @param {!function()} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.joinSession = function (userId, sessionId, successCb, failCb) {
|
||||
jsGlobalInstance.joinSession(userId, sessionId, successCb, failCb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} sessionId
|
||||
* @param {!string} memberId
|
||||
* @param {!function()} successCb
|
||||
* @param {!function()} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.leaveSession = function (sessionId, memberId, successCb, failCb) {
|
||||
jsGlobalInstance.leaveSession(sessionId, memberId, successCb, failCb);
|
||||
};
|
||||
};
|
||||
});
|
49
api/js/webodf/collab/backend/jsglobal/ServerFactory.js
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, document, require, runtime, ops */
|
||||
|
||||
define("webodf/editor/backend/jsglobal/ServerFactory", [
|
||||
"webodf/editor/backend/jsglobal/Server",
|
||||
"webodf/editor/backend/jsglobal/SessionBackend",
|
||||
"webodf/editor/backend/jsglobal/SessionList"],
|
||||
function (JsGlobalServer, JsGlobalSessionBackend, JsGlobalSessionList) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements ServerFactory
|
||||
*/
|
||||
return function JsGlobalServerFactory() {
|
||||
this.createServer = function (args) {
|
||||
return new JsGlobalServer(args);
|
||||
};
|
||||
this.createSessionBackend = function (sid, mid, server) {
|
||||
return new JsGlobalSessionBackend(sid, mid, server);
|
||||
};
|
||||
this.createSessionList = function (server) {
|
||||
return new JsGlobalSessionList(server);
|
||||
};
|
||||
};
|
||||
});
|
66
api/js/webodf/collab/backend/jsglobal/SessionBackend.js
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (C) 2014 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, ops*/
|
||||
|
||||
|
||||
define("webodf/editor/backend/jsglobal/SessionBackend", [
|
||||
"webodf/editor/backend/jsglobal/OperationRouter"],
|
||||
function (JsGlobalOperationRouter) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements SessionBackend
|
||||
*/
|
||||
function JsGlobalSessionBackend(sessionId, memberId, server) {
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
this.getMemberId = function () {
|
||||
return memberId;
|
||||
};
|
||||
|
||||
/*jslint unparam: true*/
|
||||
/**
|
||||
* @param {!odf.OdfContainer} odfContainer
|
||||
* @param {!function(!Object)} errorCallback
|
||||
* @return {!ops.OperationRouter}
|
||||
*/
|
||||
this.createOperationRouter = function (odfContainer, errorCallback) {
|
||||
return new JsGlobalOperationRouter(sessionId, memberId, server, errorCallback);
|
||||
};
|
||||
/*jslint unparam: false*/
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
this.getGenesisUrl = function () {
|
||||
return server.getGenesisUrl(sessionId);
|
||||
};
|
||||
}
|
||||
|
||||
return JsGlobalSessionBackend;
|
||||
});
|
126
api/js/webodf/collab/backend/jsglobal/SessionList.js
Normal file
@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, ops, runtime, core */
|
||||
|
||||
define("webodf/editor/backend/jsglobal/SessionList", [], function () {
|
||||
"use strict";
|
||||
|
||||
var /**@const @type {!string}*/
|
||||
EVENT_SESSION_CREATED = "jsglobal/sessionCreated",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_SESSION_MODIFIED = "jsglobal/sessionModified",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_SESSION_REMOVED = "jsglobal/sessionRemoved",
|
||||
/**@const @type {!number}*/
|
||||
POLL_FREQUENCY_MS = 500;
|
||||
|
||||
runtime.loadClass("core.EventNotifier");
|
||||
|
||||
return function JsGlobalSessionList(server) {
|
||||
var events = new core.EventNotifier([
|
||||
EVENT_SESSION_CREATED,
|
||||
EVENT_SESSION_MODIFIED,
|
||||
EVENT_SESSION_REMOVED
|
||||
]),
|
||||
pullUpdateTask,
|
||||
existingSessionHashes = {},
|
||||
sessions;
|
||||
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function fetchAndProcessSessionList() {
|
||||
var sessionPresentInUpdate = {};
|
||||
sessions = server.getJsGlobalServer().getSessions();
|
||||
|
||||
sessions.forEach(function(newSessionObj) {
|
||||
var existingSession = existingSessionHashes[newSessionObj.id],
|
||||
newSessionHash = JSON.stringify(newSessionObj); // World's most inefficient hash? Perhaps!
|
||||
|
||||
if (!existingSession) {
|
||||
events.core_EventNotifier$emit(EVENT_SESSION_CREATED, newSessionObj);
|
||||
} else if (existingSession.hash !== newSessionHash) {
|
||||
events.core_EventNotifier$emit(EVENT_SESSION_MODIFIED, newSessionObj);
|
||||
}
|
||||
existingSessionHashes[newSessionObj.id] = newSessionHash;
|
||||
sessionPresentInUpdate[newSessionObj.id] = true;
|
||||
});
|
||||
|
||||
Object.keys(existingSessionHashes).forEach(function(sessionId) {
|
||||
if (!sessionPresentInUpdate.hasOwnProperty(sessionId)) {
|
||||
events.core_EventNotifier$emit(EVENT_SESSION_REMOVED, sessionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current session list, and optionally subscribe to future updates
|
||||
*
|
||||
* @param {!{onCreated: function(!Object):undefined, onUpdated: function(!Object):undefined, onRemoved: function(!string):undefined}=} subscriber
|
||||
* @return {!Array.<!Object>} Return an array of session objects
|
||||
*/
|
||||
this.getSessions = function (subscriber) {
|
||||
fetchAndProcessSessionList();
|
||||
if (subscriber) {
|
||||
events.core_EventNotifier$subscribe(EVENT_SESSION_CREATED, subscriber.onCreated);
|
||||
events.core_EventNotifier$subscribe(EVENT_SESSION_MODIFIED, subscriber.onUpdated);
|
||||
events.core_EventNotifier$subscribe(EVENT_SESSION_REMOVED, subscriber.onRemoved);
|
||||
}
|
||||
return sessions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unsubscribe to updates
|
||||
*
|
||||
* @param {!{onCreated: function(!Object):undefined, onUpdated: function(!Object):undefined, onRemoved: function(!string):undefined}} subscriber
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.unsubscribe = function (subscriber) {
|
||||
events.unsubscribe(EVENT_SESSION_CREATED, subscriber.onCreated);
|
||||
events.unsubscribe(EVENT_SESSION_MODIFIED, subscriber.onUpdated);
|
||||
events.unsubscribe(EVENT_SESSION_REMOVED, subscriber.onRemoved);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!boolean}{ enabled
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setUpdatesEnabled = function (enabled) {
|
||||
if (enabled) {
|
||||
pullUpdateTask.triggerImmediate();
|
||||
} else {
|
||||
pullUpdateTask.cancel();
|
||||
}
|
||||
};
|
||||
|
||||
function init() {
|
||||
pullUpdateTask = core.Task.createTimeoutTask(function() {
|
||||
fetchAndProcessSessionList();
|
||||
pullUpdateTask.trigger();
|
||||
}, POLL_FREQUENCY_MS);
|
||||
}
|
||||
init();
|
||||
};
|
||||
});
|
593
api/js/webodf/collab/backend/pullbox/OperationRouter.js
Normal file
@ -0,0 +1,593 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, runtime, core, ops*/
|
||||
|
||||
define("webodf/editor/backend/pullbox/OperationRouter", [], function () {
|
||||
"use strict";
|
||||
|
||||
// TODO: these eventid strings should be defined at OperationRouter interface
|
||||
var /**@const @type {!string}*/
|
||||
EVENT_BEFORESAVETOFILE = "beforeSaveToFile",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_SAVEDTOFILE = "savedToFile",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED = "hasLocalUnsyncedOperationsChanged",
|
||||
/**@const @type {!string}*/
|
||||
EVENT_HASSESSIONHOSTCONNECTIONCHANGED = "hasSessionHostConnectionChanged";
|
||||
|
||||
runtime.loadClass("ops.OperationTransformer");
|
||||
runtime.loadClass("core.EventNotifier");
|
||||
|
||||
/**
|
||||
* route operations in a networked collaborative manner.
|
||||
*
|
||||
* incoming operations (from controller) are sent to a server,
|
||||
* who will distribute them.
|
||||
*
|
||||
* incoming operations (from the server are played on the DOM.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements ops.OperationRouter
|
||||
*/
|
||||
return function PullBoxOperationRouter(sessionId, memberId, server, odfContainer, errorCallback) {
|
||||
|
||||
var operationFactory,
|
||||
/**@type{function(!ops.Operation):boolean}*/
|
||||
playbackFunction,
|
||||
idleTimeout = null,
|
||||
syncOpsTimeout = null,
|
||||
/**@type{!boolean}*/
|
||||
isInstantSyncRequested = false,
|
||||
/**@type{!boolean}*/
|
||||
isPlayingUnplayedServerOpSpecs = false,
|
||||
/**@type{!boolean}*/
|
||||
isSyncCallRunning = false,
|
||||
/**@type{!boolean}*/
|
||||
hasError = false,
|
||||
/**@type{!boolean}*/
|
||||
syncingBlocked = false,
|
||||
/** @type {!string} id of latest op stack state known on the server */
|
||||
lastServerSeq = "",
|
||||
/** @type {!Array.<!Function>} sync request callbacks created since the last sync call to the server */
|
||||
syncRequestCallbacksQueue = [],
|
||||
/** @type {!Array.<!Object>} ops created since the last sync call to the server */
|
||||
unsyncedClientOpspecQueue = [],
|
||||
/** @type {!Array.<!Object>} ops already received from the server but not yet applied */
|
||||
unplayedServerOpspecQueue = [],
|
||||
/** @type {!Array.<!Function>} sync request callbacks which should be called after the received ops have been applied server */
|
||||
uncalledSyncRequestCallbacksQueue = [],
|
||||
/**@type{!boolean}*/
|
||||
hasLocalUnsyncedOps = false,
|
||||
/**@type{!boolean}*/
|
||||
hasSessionHostConnection = true,
|
||||
eventNotifier = new core.EventNotifier([
|
||||
EVENT_BEFORESAVETOFILE,
|
||||
EVENT_SAVEDTOFILE,
|
||||
EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED,
|
||||
EVENT_HASSESSIONHOSTCONNECTIONCHANGED,
|
||||
ops.OperationRouter.signalProcessingBatchStart,
|
||||
ops.OperationRouter.signalProcessingBatchEnd
|
||||
]),
|
||||
/**@type{!boolean} tells if any local ops have been modifying ops */
|
||||
hasPushedModificationOps = false,
|
||||
operationTransformer = new ops.OperationTransformer(),
|
||||
/**@const*/replayTime = 500,
|
||||
/**@const*/syncOpsDelay = 3000,
|
||||
/**@const*/idleDelay = 5000;
|
||||
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function updateHasLocalUnsyncedOpsState() {
|
||||
var hasLocalUnsyncedOpsNow = (unsyncedClientOpspecQueue.length > 0);
|
||||
|
||||
// no change?
|
||||
if (hasLocalUnsyncedOps === hasLocalUnsyncedOpsNow) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasLocalUnsyncedOps = hasLocalUnsyncedOpsNow;
|
||||
eventNotifier.emit(EVENT_HASLOCALUNSYNCEDOPERATIONSCHANGED, hasLocalUnsyncedOps);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!boolean} hasConnection
|
||||
* @return {undefined}
|
||||
*/
|
||||
function updateHasSessionHostConnectionState(hasConnection) {
|
||||
// no change?
|
||||
if (hasSessionHostConnection === hasConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasSessionHostConnection = hasConnection;
|
||||
eventNotifier.emit(EVENT_HASSESSIONHOSTCONNECTIONCHANGED, hasSessionHostConnection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function playUnplayedServerOpSpecs() {
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function doPlayUnplayedServerOpSpecs() {
|
||||
var opspec, op, startTime, i;
|
||||
|
||||
isPlayingUnplayedServerOpSpecs = false;
|
||||
|
||||
// take start time
|
||||
startTime = Date.now();
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchStart, {});
|
||||
|
||||
// apply as much as possible in the given time
|
||||
while (unplayedServerOpspecQueue.length > 0) {
|
||||
// time over?
|
||||
if (Date.now() - startTime > replayTime) {
|
||||
break;
|
||||
}
|
||||
|
||||
opspec = unplayedServerOpspecQueue.shift();
|
||||
|
||||
// use factory to create an instance, and playback!
|
||||
op = operationFactory.create(opspec);
|
||||
runtime.log(" op in: "+runtime.toJson(opspec));
|
||||
if (op !== null) {
|
||||
if (!playbackFunction(op)) {
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
hasError = true;
|
||||
errorCallback("opExecutionFailure");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
hasError = true;
|
||||
runtime.log("ignoring invalid incoming opspec: " + opspec);
|
||||
errorCallback("unknownOpReceived");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
|
||||
// still unplayed opspecs?
|
||||
if (unplayedServerOpspecQueue.length > 0) {
|
||||
// let other events be handled. then continue
|
||||
isPlayingUnplayedServerOpSpecs = true;
|
||||
runtime.getWindow().setTimeout(doPlayUnplayedServerOpSpecs, 1);
|
||||
} else {
|
||||
// finally call all the callbacks waiting for that sync!
|
||||
for (i = 0; i < uncalledSyncRequestCallbacksQueue.length; i += 1) {
|
||||
uncalledSyncRequestCallbacksQueue[i]();
|
||||
}
|
||||
|
||||
uncalledSyncRequestCallbacksQueue = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlayingUnplayedServerOpSpecs) {
|
||||
return;
|
||||
}
|
||||
doPlayUnplayedServerOpSpecs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array.<!Object>} opspecs
|
||||
* @param {Array.<!Function>} callbacks
|
||||
* @return {undefined}
|
||||
*/
|
||||
function receiveOpSpecsFromNetwork(opspecs, callbacks) {
|
||||
// append to existing unplayed
|
||||
unplayedServerOpspecQueue = unplayedServerOpspecQueue.concat(opspecs);
|
||||
uncalledSyncRequestCallbacksQueue = uncalledSyncRequestCallbacksQueue.concat(callbacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the unsynced client ops and the server ops,
|
||||
* applies the server ops after transformation
|
||||
* @param {Array.<!Object>} serverOpspecs
|
||||
* @return {!boolean}
|
||||
*/
|
||||
function handleOpsSyncConflict(serverOpspecs) {
|
||||
var i,
|
||||
transformResult;
|
||||
|
||||
if (! serverOpspecs) {
|
||||
// TODO: proper error message, stop working
|
||||
runtime.BrowserRuntime$assert(false, "no opspecs received!");
|
||||
return false;
|
||||
} // TODO: more checking of proper content in serverOpspecs
|
||||
|
||||
transformResult = operationTransformer.transform(unsyncedClientOpspecQueue, /**@type{!Array.<!Object>}*/(serverOpspecs));
|
||||
|
||||
if (!transformResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// store transformed server ops
|
||||
for (i = 0; i < transformResult.opSpecsB.length; i += 1) {
|
||||
unplayedServerOpspecQueue.push(transformResult.opSpecsB[i]);
|
||||
}
|
||||
|
||||
// store opspecs of all transformed client opspecs
|
||||
unsyncedClientOpspecQueue = [];
|
||||
for (i = 0; i < transformResult.opSpecsA.length; i += 1) {
|
||||
unsyncedClientOpspecQueue.push(transformResult.opSpecsA[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function syncOps() {
|
||||
var syncedClientOpspecs,
|
||||
syncRequestCallbacksArray;
|
||||
|
||||
/**
|
||||
* @return {undefined}
|
||||
*/
|
||||
function startSyncOpsTimeout() {
|
||||
idleTimeout = null;
|
||||
syncOpsTimeout = runtime.getWindow().setTimeout(function() {
|
||||
syncOpsTimeout = null;
|
||||
syncOps();
|
||||
}, syncOpsDelay);
|
||||
}
|
||||
|
||||
if (isSyncCallRunning || hasError) {
|
||||
return;
|
||||
}
|
||||
// TODO: hack, remove
|
||||
if (syncingBlocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
runtime.log("OperationRouter: sending sync_ops call");
|
||||
// no more instant pull request in any case
|
||||
isInstantSyncRequested = false;
|
||||
// set lock
|
||||
isSyncCallRunning = true;
|
||||
|
||||
// take specs from queue, if any
|
||||
syncedClientOpspecs = unsyncedClientOpspecQueue;
|
||||
unsyncedClientOpspecQueue = [];
|
||||
syncRequestCallbacksArray = syncRequestCallbacksQueue;
|
||||
syncRequestCallbacksQueue = [];
|
||||
|
||||
server.call({
|
||||
command: 'sync_ops',
|
||||
args: {
|
||||
es_id: sessionId,
|
||||
member_id: memberId,
|
||||
seq_head: String(lastServerSeq),
|
||||
client_ops: syncedClientOpspecs
|
||||
}
|
||||
}, function(responseData) {
|
||||
var response,
|
||||
/**@type{!boolean}*/
|
||||
hasUnresolvableConflict = false;
|
||||
|
||||
updateHasSessionHostConnectionState(true);
|
||||
|
||||
if (syncingBlocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
response = /** @type{{result:string, head_seq:string, ops:Array.<!Object>}} */(runtime.fromJson(responseData));
|
||||
} catch (e) {
|
||||
hasError = true;
|
||||
runtime.log("Could not parse reply: "+responseData);
|
||||
errorCallback("unknownServerReply");
|
||||
return;
|
||||
}
|
||||
// TODO: hack, remove
|
||||
runtime.log("sync_ops reply: " + responseData);
|
||||
|
||||
// just new ops?
|
||||
if (response.result === "new_ops") {
|
||||
if (response.ops.length > 0) {
|
||||
// no new locally in the meantime?
|
||||
if (unsyncedClientOpspecQueue.length === 0) {
|
||||
receiveOpSpecsFromNetwork(response.ops, syncRequestCallbacksArray);
|
||||
} else {
|
||||
// transform server ops against new local ones and apply,
|
||||
// transform and send new local ops to server
|
||||
runtime.log("meh, have new ops locally meanwhile, have to do transformations.");
|
||||
hasUnresolvableConflict = !handleOpsSyncConflict(response.ops);
|
||||
syncRequestCallbacksQueue = syncRequestCallbacksArray.concat(syncRequestCallbacksQueue);
|
||||
}
|
||||
// and note server state
|
||||
lastServerSeq = response.head_seq;
|
||||
} else {
|
||||
receiveOpSpecsFromNetwork([], syncRequestCallbacksArray);
|
||||
}
|
||||
} else if (response.result === "added") {
|
||||
runtime.log("All added to server");
|
||||
receiveOpSpecsFromNetwork([], syncRequestCallbacksArray);
|
||||
// note server state
|
||||
lastServerSeq = response.head_seq;
|
||||
updateHasLocalUnsyncedOpsState();
|
||||
} else if (response.result === "conflict") {
|
||||
// put the send ops back into the outgoing queue
|
||||
unsyncedClientOpspecQueue = syncedClientOpspecs.concat(unsyncedClientOpspecQueue);
|
||||
syncRequestCallbacksQueue = syncRequestCallbacksArray.concat(syncRequestCallbacksQueue);
|
||||
// transform server ops against new local ones and apply,
|
||||
// transform and request new send new local ops to server
|
||||
runtime.log("meh, server has new ops meanwhile, have to do transformations.");
|
||||
hasUnresolvableConflict = !handleOpsSyncConflict(response.ops);
|
||||
// and note server state
|
||||
lastServerSeq = response.head_seq;
|
||||
// try again instantly
|
||||
if (!hasUnresolvableConflict) {
|
||||
isInstantSyncRequested = true;
|
||||
}
|
||||
} else if (response.result === "error") {
|
||||
runtime.log("server reports an error: "+response.error);
|
||||
hasError = true;
|
||||
errorCallback(
|
||||
response.error === "ENOSESSION" ? "sessionDoesNotExist":
|
||||
response.error === "ENOMEMBER" ? "notMemberOfSession":
|
||||
"unknownServerReply"
|
||||
);
|
||||
} else {
|
||||
hasError = true;
|
||||
runtime.log("Unexpected result on sync-ops call: "+response.result);
|
||||
errorCallback("unknownServerReply");
|
||||
}
|
||||
if (hasError) {
|
||||
return;
|
||||
}
|
||||
|
||||
// unlock
|
||||
isSyncCallRunning = false;
|
||||
|
||||
if (hasUnresolvableConflict) {
|
||||
hasError = true;
|
||||
errorCallback("unresolvableConflictingOps");
|
||||
} else {
|
||||
// prepare next sync
|
||||
if (isInstantSyncRequested) {
|
||||
syncOps();
|
||||
} else {
|
||||
// nothing on client to sync?
|
||||
if (unsyncedClientOpspecQueue.length === 0) {
|
||||
idleTimeout = runtime.getWindow().setTimeout(startSyncOpsTimeout, idleDelay);
|
||||
} else {
|
||||
startSyncOpsTimeout();
|
||||
}
|
||||
}
|
||||
playUnplayedServerOpSpecs();
|
||||
}
|
||||
}, function() {
|
||||
runtime.log("meh, server cannot be reached ATM.");
|
||||
// signal connection problem, but do not give up for now
|
||||
updateHasSessionHostConnectionState(false);
|
||||
// put the (not) send ops back into the outgoing queue
|
||||
unsyncedClientOpspecQueue = syncedClientOpspecs.concat(unsyncedClientOpspecQueue);
|
||||
syncRequestCallbacksQueue = syncRequestCallbacksArray.concat(syncRequestCallbacksQueue);
|
||||
// unlock
|
||||
isSyncCallRunning = false;
|
||||
// nothing on client to sync?
|
||||
if (unsyncedClientOpspecQueue.length === 0) {
|
||||
idleTimeout = runtime.getWindow().setTimeout(startSyncOpsTimeout, idleDelay);
|
||||
} else {
|
||||
startSyncOpsTimeout();
|
||||
}
|
||||
playUnplayedServerOpSpecs();
|
||||
});
|
||||
}
|
||||
|
||||
function triggerPushingOps() {
|
||||
// disable any idle timeout
|
||||
if (idleTimeout) {
|
||||
runtime.clearTimeout(idleTimeout);
|
||||
idleTimeout = null;
|
||||
}
|
||||
|
||||
// enable syncOps timeout, if needed
|
||||
if (!syncOpsTimeout && !isSyncCallRunning) {
|
||||
runtime.log("OperationRouter: opsSync requested for pushing");
|
||||
syncOpsTimeout = runtime.getWindow().setTimeout(function() {
|
||||
syncOpsTimeout = null;
|
||||
syncOps();
|
||||
}, syncOpsDelay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Funtion} cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
function requestInstantOpsSync(cb) {
|
||||
// register callback
|
||||
syncRequestCallbacksQueue.push(cb);
|
||||
|
||||
// disable any idle timeout
|
||||
if (idleTimeout) {
|
||||
runtime.clearTimeout(idleTimeout);
|
||||
idleTimeout = null;
|
||||
}
|
||||
|
||||
// disable any syncOps timeout
|
||||
if (syncOpsTimeout) {
|
||||
runtime.clearTimeout(syncOpsTimeout);
|
||||
syncOpsTimeout = null;
|
||||
}
|
||||
|
||||
runtime.log("OperationRouter: instant opsSync requested");
|
||||
isInstantSyncRequested = true;
|
||||
syncOps();
|
||||
}
|
||||
|
||||
this.requestReplay = function (done_cb) {
|
||||
requestInstantOpsSync(done_cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the factory to use to create operation instances from operation specs.
|
||||
*
|
||||
* @param {!ops.OperationFactory} f
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setOperationFactory = function (f) {
|
||||
operationFactory = f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the method which should be called to apply operations.
|
||||
*
|
||||
* @param {!function(!ops.Operation):boolean} playback_func
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.setPlaybackFunction = function (playback_func) {
|
||||
playbackFunction = playback_func;
|
||||
};
|
||||
|
||||
/**
|
||||
* Brings the locally created operations into the game.
|
||||
*
|
||||
* @param {!Array.<!ops.Operation>} operations
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.push = function (operations) {
|
||||
var i, op, opspec,
|
||||
timestamp = Date.now();
|
||||
|
||||
if (hasError) {
|
||||
return;
|
||||
}
|
||||
// TODO: should be an assert in the future
|
||||
// there needs to be a flag telling that processing is happening,
|
||||
// and thus any input should be dropped in the sessioncontroller
|
||||
// ideally also have some UI element showing the processing state
|
||||
if (unplayedServerOpspecQueue.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchStart, {});
|
||||
|
||||
for (i = 0; i < operations.length; i += 1) {
|
||||
op = operations[i];
|
||||
opspec = op.spec();
|
||||
|
||||
// note if any local ops modified
|
||||
hasPushedModificationOps = hasPushedModificationOps || op.isEdit;
|
||||
|
||||
// add timestamp TODO: improve the useless recreation of the op
|
||||
opspec.timestamp = timestamp;
|
||||
op = operationFactory.create(opspec);
|
||||
|
||||
// apply locally
|
||||
if (!playbackFunction(op)) {
|
||||
hasError = true;
|
||||
errorCallback("opExecutionFailure");
|
||||
return;
|
||||
}
|
||||
|
||||
// send to server
|
||||
unsyncedClientOpspecQueue.push(opspec);
|
||||
}
|
||||
|
||||
triggerPushingOps();
|
||||
|
||||
updateHasLocalUnsyncedOpsState();
|
||||
|
||||
eventNotifier.emit(ops.OperationRouter.signalProcessingBatchEnd, {});
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests a gracefull shutdown of the Operation Router.
|
||||
* Buffered operations shall be sent to the server.
|
||||
* A callback is called on success.
|
||||
*/
|
||||
this.close = function (cb) {
|
||||
function cbDoneSaving(err) {
|
||||
eventNotifier.emit(EVENT_SAVEDTOFILE, null);
|
||||
cb(err);
|
||||
}
|
||||
|
||||
function cbSuccess(fileData) {
|
||||
server.writeSessionStateToFile(sessionId, memberId, lastServerSeq, fileData, cbDoneSaving);
|
||||
}
|
||||
|
||||
function doClose() {
|
||||
syncingBlocked = true;
|
||||
if (hasPushedModificationOps) {
|
||||
eventNotifier.emit(EVENT_BEFORESAVETOFILE, null);
|
||||
|
||||
odfContainer.createByteArray(cbSuccess, cbDoneSaving);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
cb();
|
||||
} else if (hasLocalUnsyncedOps) {
|
||||
requestInstantOpsSync(doClose);
|
||||
} else {
|
||||
doClose();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} eventId
|
||||
* @param {!Function} cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.subscribe = function (eventId, cb) {
|
||||
eventNotifier.subscribe(eventId, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} eventId
|
||||
* @param {!Function} cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.unsubscribe = function (eventId, cb) {
|
||||
eventNotifier.unsubscribe(eventId, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {!boolean}
|
||||
*/
|
||||
this.hasLocalUnsyncedOps = function () {
|
||||
return hasLocalUnsyncedOps;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {!boolean}
|
||||
*/
|
||||
this.hasSessionHostConnection = function () {
|
||||
return hasSessionHostConnection;
|
||||
};
|
||||
};
|
||||
});
|
291
api/js/webodf/collab/backend/pullbox/Server.js
Normal file
@ -0,0 +1,291 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, runtime, core, XMLHttpRequest*/
|
||||
|
||||
define("webodf/editor/backend/pullbox/Server", [], function () {
|
||||
"use strict";
|
||||
|
||||
runtime.loadClass("core.Base64");
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements ops.Server
|
||||
* @param {{url:string}} args
|
||||
*/
|
||||
return function PullBoxServer(args) {
|
||||
|
||||
var self = this,
|
||||
token,
|
||||
/**@const*/serverCallTimeout = 10000,
|
||||
base64 = new core.Base64();
|
||||
|
||||
args = args || {};
|
||||
args.url = args.url || "/WSER";
|
||||
args.sessionStateToFileUrl = args.sessionStateToFileUrl || "/SS2F";
|
||||
|
||||
this.getGenesisUrl = function (sessionId) {
|
||||
return args.genesisUrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!Object} message
|
||||
* @param {!function(!string)} cb
|
||||
* @param {!function(!number,!string)} cbError passes the status number
|
||||
* and the statustext, or -1 if there was an exception on sending
|
||||
* @return {undefined}
|
||||
*/
|
||||
function call(message, cb, cbError) {
|
||||
var xhr = new XMLHttpRequest(),
|
||||
messageString = JSON.stringify(message);
|
||||
|
||||
function handleResult() {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status < 200 || xhr.status >= 300) {
|
||||
// report error
|
||||
runtime.log("Status " + String(xhr.status) + ": " +
|
||||
xhr.responseText || xhr.statusText);
|
||||
cbError(xhr.status, xhr.statusText);
|
||||
} else {
|
||||
runtime.log("Status " + String(xhr.status) + ": " +
|
||||
xhr.responseText || xhr.statusText);
|
||||
cb(xhr.responseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runtime.log("Sending message to server: " + messageString);
|
||||
// create body data for request from metadata and payload
|
||||
|
||||
// do the request
|
||||
xhr.open('POST', args.url, true);
|
||||
if (token) {
|
||||
xhr.setRequestHeader("requesttoken", token);
|
||||
}
|
||||
xhr.setRequestHeader("content-type", "application/json");
|
||||
xhr.onreadystatechange = handleResult;
|
||||
xhr.timeout = serverCallTimeout;
|
||||
// TODO: seems handleResult is called on timeout as well, with xhr.status === 0
|
||||
// xhr.ontimeout = handleTimeout;
|
||||
try {
|
||||
xhr.send(messageString);
|
||||
} catch (e) {
|
||||
runtime.log("Problem with calling server: " + e);
|
||||
cbError(-1, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
this.call = call;
|
||||
|
||||
this.getToken = function () {
|
||||
return token;
|
||||
};
|
||||
|
||||
/**
|
||||
* for pre-authenticated use
|
||||
*/
|
||||
this.setToken = function (a_token) {
|
||||
token = a_token;
|
||||
};
|
||||
|
||||
|
||||
/*jslint unparam: true*/
|
||||
/**
|
||||
* @param {!number} timeout in milliseconds
|
||||
* @param {!function(!string)} callback
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.connect = function (timeout, callback) {
|
||||
/*
|
||||
var accumulatedWaitingTime = 0;
|
||||
|
||||
// already tried connecting?
|
||||
if (self.networkStatus() === "ready") {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
callback("ready");
|
||||
};
|
||||
/*jslint unparam: false*/
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
this.networkStatus = function () {
|
||||
return "ready";
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} login
|
||||
* @param {!string} password
|
||||
* @param {function(!Object)} successCb
|
||||
* @param {function(!string)} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.login = function (login, password, successCb, failCb) {
|
||||
successCb ({
|
||||
'full_name' :'Hadi Nategh',
|
||||
'uid' : 'sysop',
|
||||
'securityToken' : '10000',
|
||||
'token' : '10000',
|
||||
'sessiondata_list' : [],
|
||||
'success' : true,
|
||||
'member_id' : 'sysop'
|
||||
});
|
||||
return;
|
||||
call({
|
||||
command: "login",
|
||||
args: {
|
||||
login: base64.toBase64(login),
|
||||
password: base64.toBase64(password)
|
||||
}
|
||||
}, function(responseData) {
|
||||
var response = /**@type {{token:string}}*/(runtime.fromJson(responseData));
|
||||
runtime.log("Login reply: " + responseData);
|
||||
|
||||
if (response.hasOwnProperty("token")) {
|
||||
token = response.token;
|
||||
runtime.log("Caching token: " + self.getToken());
|
||||
successCb(response);
|
||||
} else {
|
||||
failCb(responseData);
|
||||
}
|
||||
}, failCb);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} userId
|
||||
* @param {!string} sessionId
|
||||
* @param {!function(!string)} successCb
|
||||
* @param {!function()} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.joinSession = function (userId, sessionId, successCb, failCb) {
|
||||
successCb('sysop');
|
||||
return;
|
||||
call({
|
||||
command: "join_session",
|
||||
args: {
|
||||
user_id: userId,
|
||||
es_id: sessionId
|
||||
}
|
||||
}, function(responseData) {
|
||||
var response = /**@type {{success:string, member_id:string}}*/(runtime.fromJson(responseData));
|
||||
runtime.log("join_session reply: " + responseData);
|
||||
|
||||
if (response.hasOwnProperty("success") && response.success) {
|
||||
successCb(response.member_id);
|
||||
} else {
|
||||
failCb();
|
||||
}
|
||||
}, failCb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} sessionId
|
||||
* @param {!string} memberId
|
||||
* @param {!function()} successCb
|
||||
* @param {!function()} failCb
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.leaveSession = function (sessionId, memberId, successCb, failCb) {
|
||||
call({
|
||||
command: "leave_session",
|
||||
args: {
|
||||
es_id: sessionId,
|
||||
member_id: memberId
|
||||
}
|
||||
}, function(responseData) {
|
||||
var response = /**@type {{success:string, member_id:string}}*/(runtime.fromJson(responseData));
|
||||
runtime.log("leave_session reply: " + responseData);
|
||||
|
||||
if (response.hasOwnProperty("success") && response.success) {
|
||||
successCb();
|
||||
} else {
|
||||
failCb();
|
||||
}
|
||||
}, failCb);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string} sessionId
|
||||
* @param {!string} memberId
|
||||
* @param {!string} seqHead
|
||||
* @param {!function(!Object=)} callback
|
||||
* @return {undefined}
|
||||
*/
|
||||
this.writeSessionStateToFile = function(sessionId, memberId, seqHead, fileData, callback) {
|
||||
// code copied from BrowserRuntime.writeFile and adapted
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
function handleResult() {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 0 && !xhr.responseText) {// TODO: check makes sense here as well?
|
||||
// for local files there is no difference between missing
|
||||
// and empty files, so empty files are considered as errors
|
||||
runtime.log("File " + args.sessionStateToFileUrl + " is empty.");
|
||||
} else if ((xhr.status >= 200 && xhr.status < 300) ||
|
||||
xhr.status === 0) {
|
||||
// report success
|
||||
runtime.log(null);
|
||||
} else {
|
||||
// report error
|
||||
runtime.log("Status " + String(xhr.status) + ": " +
|
||||
xhr.responseText || xhr.statusText);
|
||||
}
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
// do the request
|
||||
xhr.open('POST', args.sessionStateToFileUrl, true);
|
||||
if (token) {
|
||||
xhr.setRequestHeader("requesttoken", token);
|
||||
}
|
||||
xhr.setRequestHeader("webodf-session-id", sessionId);
|
||||
xhr.setRequestHeader("webodf-member-id", memberId);
|
||||
xhr.setRequestHeader("webodf-session-revision", seqHead);
|
||||
xhr.onreadystatechange = handleResult;
|
||||
// ArrayBufferView will have an ArrayBuffer property, in WebKit, XHR can send()
|
||||
// an ArrayBuffer, In Firefox, one must use sendAsBinary with a string
|
||||
if (fileData.buffer && !xhr.sendAsBinary) {
|
||||
fileData = fileData.buffer; // webkit supports sending an ArrayBuffer
|
||||
} else {
|
||||
// encode into a string, this works in FireFox >= 3
|
||||
fileData = runtime.byteArrayToString(fileData, "binary");
|
||||
}
|
||||
try {
|
||||
if (xhr.sendAsBinary) {
|
||||
xhr.sendAsBinary(fileData);
|
||||
} else {
|
||||
xhr.send(fileData);
|
||||
}
|
||||
} catch (e) {
|
||||
runtime.log("Problem with calling \"writeSessionStateToFile\" on server");
|
||||
callback(e.message);
|
||||
}
|
||||
};
|
||||
};
|
||||
});
|
49
api/js/webodf/collab/backend/pullbox/ServerFactory.js
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, document, require, runtime, ops */
|
||||
|
||||
define("webodf/editor/backend/pullbox/ServerFactory", [
|
||||
"webodf/editor/backend/pullbox/Server",
|
||||
"webodf/editor/backend/pullbox/SessionBackend",
|
||||
"webodf/editor/backend/pullbox/SessionList"],
|
||||
function (PullBoxServer, PullBoxSessionBackend, PullBoxSessionList) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements ServerFactory
|
||||
*/
|
||||
return function PullBoxServerFactory() {
|
||||
this.createServer = function (args) {
|
||||
return new PullBoxServer(args);
|
||||
};
|
||||
this.createSessionBackend = function (sid, mid, server) {
|
||||
return new PullBoxSessionBackend(sid, mid, server);
|
||||
};
|
||||
this.createSessionList = function (server) {
|
||||
return new PullBoxSessionList(server);
|
||||
};
|
||||
};
|
||||
});
|
64
api/js/webodf/collab/backend/pullbox/SessionBackend.js
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (C) 2014 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, ops*/
|
||||
|
||||
|
||||
define("webodf/editor/backend/pullbox/SessionBackend", [
|
||||
"webodf/editor/backend/pullbox/OperationRouter"],
|
||||
function (PullBoxOperationRouter) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements SessionBackend
|
||||
*/
|
||||
function PullBoxSessionBackend(sessionId, memberId, server) {
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
this.getMemberId = function () {
|
||||
return memberId;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!odf.OdfContainer} odfContainer
|
||||
* @param {!function(!Object)} errorCallback
|
||||
* @return {!ops.OperationRouter}
|
||||
*/
|
||||
this.createOperationRouter = function (odfContainer, errorCallback) {
|
||||
return new PullBoxOperationRouter(sessionId, memberId, server, odfContainer, errorCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {!string}
|
||||
*/
|
||||
this.getGenesisUrl = function () {
|
||||
return server.getGenesisUrl(sessionId);
|
||||
};
|
||||
}
|
||||
|
||||
return PullBoxSessionBackend;
|
||||
});
|
173
api/js/webodf/collab/backend/pullbox/SessionList.js
Normal file
@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Copyright (C) 2013 KO GmbH <copyright@kogmbh.com>
|
||||
*
|
||||
* @licstart
|
||||
* This file is part of WebODF.
|
||||
*
|
||||
* WebODF is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License (GNU AGPL)
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* WebODF 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with WebODF. If not, see <http://www.gnu.org/licenses/>.
|
||||
* @licend
|
||||
*
|
||||
* @source: http://www.webodf.org/
|
||||
* @source: https://github.com/kogmbh/WebODF/
|
||||
*/
|
||||
|
||||
/*global define, ops, runtime */
|
||||
|
||||
define("webodf/editor/backend/pullbox/SessionList", [], function () {
|
||||
"use strict";
|
||||
|
||||
return function PullBoxSessionList(server) {
|
||||
var cachedSessionData = {},
|
||||
subscribers = [],
|
||||
serverPullingTimeoutId = null,
|
||||
pullingActive = true;
|
||||
|
||||
function onSessionData(sessionData) {
|
||||
var i,
|
||||
isNew = !cachedSessionData.hasOwnProperty(sessionData.id);
|
||||
|
||||
// extend data with download url
|
||||
sessionData.fileUrl = "/session/" + sessionData.id + "/last/" + sessionData.filename;
|
||||
// cache
|
||||
cachedSessionData[sessionData.id] = sessionData;
|
||||
runtime.log("get session data for:" + sessionData.title + ", is new:" + isNew);
|
||||
|
||||
for (i = 0; i < subscribers.length; i += 1) {
|
||||
if (isNew) {
|
||||
subscribers[i].onCreated(sessionData);
|
||||
} else {
|
||||
subscribers[i].onUpdated(sessionData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSessionRemoved(sessionId) {
|
||||
var i;
|
||||
|
||||
if (cachedSessionData.hasOwnProperty(sessionId)) {
|
||||
delete cachedSessionData[sessionId];
|
||||
|
||||
for (i = 0; i < subscribers.length; i += 1) {
|
||||
subscribers[i].onRemoved(sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pullSessionList() {
|
||||
serverPullingTimeoutId = null;
|
||||
|
||||
server.call({
|
||||
command: "query_sessiondata_list"
|
||||
}, function (responseData) {
|
||||
var response = runtime.fromJson(responseData),
|
||||
sessionList, i,
|
||||
unupdatedSessions = {};
|
||||
|
||||
// stopped meanwhile? TODO: support for cancelling calls
|
||||
if (!pullingActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
runtime.log("query_sessiondata_list reply: " + responseData);
|
||||
|
||||
if (response.hasOwnProperty("sessiondata_list")) {
|
||||
// collect known sessions
|
||||
for (i in cachedSessionData) {
|
||||
if (cachedSessionData.hasOwnProperty(i)) {
|
||||
unupdatedSessions[i] = ""; // some dummy value, unused
|
||||
}
|
||||
}
|
||||
|
||||
// add/update with all delivered sessions
|
||||
sessionList = response.sessiondata_list;
|
||||
for (i = 0; i < sessionList.length; i += 1) {
|
||||
if (unupdatedSessions.hasOwnProperty(sessionList[i].id)) {
|
||||
delete unupdatedSessions[sessionList[i].id];
|
||||
}
|
||||
onSessionData(sessionList[i]);
|
||||
}
|
||||
|
||||
// remove unupdated sessions
|
||||
for (i in unupdatedSessions) {
|
||||
if (unupdatedSessions.hasOwnProperty(i)) {
|
||||
onSessionRemoved(i);
|
||||
}
|
||||
}
|
||||
|
||||
// next update in 5 secs
|
||||
serverPullingTimeoutId = runtime.getWindow().setTimeout(pullSessionList, 5000);
|
||||
} else {
|
||||
runtime.log("Meh, sessionlist data broken: " + responseData);
|
||||
}
|
||||
}, function (e) {
|
||||
runtime.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
this.getSessions = function (subscriber) {
|
||||
var i,
|
||||
sessionList = [];
|
||||
|
||||
if (subscriber) {
|
||||
subscribers.push(subscriber);
|
||||
}
|
||||
|
||||
for (i in cachedSessionData) {
|
||||
if (cachedSessionData.hasOwnProperty(i)) {
|
||||
sessionList.push(cachedSessionData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return sessionList;
|
||||
};
|
||||
|
||||
this.unsubscribe = function (subscriber) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < subscribers.length; i += 1) {
|
||||
if (subscribers[i] === subscriber) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
runtime.BrowserRuntime$assert((i < subscribers.length),
|
||||
"tried to unsubscribe when not subscribed.");
|
||||
|
||||
subscribers.splice(i, 1);
|
||||
};
|
||||
|
||||
this.setUpdatesEnabled = function (enabled) {
|
||||
if (pullingActive === enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
pullingActive = enabled;
|
||||
if (pullingActive) {
|
||||
pullSessionList();
|
||||
} else {
|
||||
// cancel any running pulling timeout
|
||||
if (serverPullingTimeoutId !== null) {
|
||||
runtime.clearTimeout(serverPullingTimeoutId);
|
||||
serverPullingTimeoutId = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function init() {
|
||||
pullSessionList();
|
||||
}
|
||||
|
||||
init();
|
||||
};
|
||||
});
|
1
api/js/webodf/collab/dijit/icons/commonIcons.css
Normal file
@ -0,0 +1 @@
|
||||
.dijitIconSave,.dijitIconPrint,.dijitIconCut,.dijitIconCopy,.dijitIconClear,.dijitIconDelete,.dijitIconUndo,.dijitIconEdit,.dijitIconNewTask,.dijitIconEditTask,.dijitIconEditProperty,.dijitIconTask,.dijitIconFilter,.dijitIconConfigure,.dijitIconSearch,.dijitIconApplication,.dijitIconBookmark,.dijitIconChart,.dijitIconConnector,.dijitIconDatabase,.dijitIconDocuments,.dijitIconMail,.dijitLeaf,.dijitIconFile,.dijitIconFunction,.dijitIconKey,.dijitIconPackage,.dijitIconSample,.dijitIconTable,.dijitIconUsers,.dijitFolderClosed,.dijitIconFolderClosed,.dijitFolderOpened,.dijitIconFolderOpen,.dijitIconError {background-image: url('images/commonIconsObjActEnabled.png'); width: 16px; height: 16px;}.dj_ie6 .dijitIconSave,.dj_ie6 .dijitIconPrint,.dj_ie6 .dijitIconCut,.dj_ie6 .dijitIconCopy,.dj_ie6 .dijitIconClear,.dj_ie6 .dijitIconDelete,.dj_ie6 .dijitIconUndo,.dj_ie6 .dijitIconEdit,.dj_ie6 .dijitIconNewTask,.dj_ie6 .dijitIconEditTask,.dj_ie6 .dijitIconEditProperty,.dj_ie6 .dijitIconTask,.dj_ie6 .dijitIconFilter,.dj_ie6 .dijitIconConfigure,.dj_ie6 .dijitIconSearch,.dj_ie6 .dijitIconApplication,.dj_ie6 .dijitIconBookmark,.dj_ie6 .dijitIconChart,.dj_ie6 .dijitIconConnector,.dj_ie6 .dijitIconDatabase,.dj_ie6 .dijitIconDocuments,.dj_ie6 .dijitIconMail,.dj_ie6 .dijitLeaf,.dj_ie6 .dijitIconFile,.dj_ie6 .dijitIconFunction,.dj_ie6 .dijitIconKey,.dj_ie6 .dijitIconPackage,.dj_ie6 .dijitIconSample,.dj_ie6 .dijitIconTable,.dj_ie6 .dijitIconUsers,.dj_ie6 .dijitFolderClosed,.dj_ie6 .dijitIconFolderClosed,.dj_ie6 .dijitFolderOpened,.dj_ie6 .dijitIconFolderOpen,.dj_ie6 .dijitIconError {background-image: url('images/commonIconsObjActEnabled8bit.png');}.dijitDisabled .dijitIconSave,.dijitDisabled .dijitIconPrint,.dijitDisabled .dijitIconCut,.dijitDisabled .dijitIconCopy,.dijitDisabled .dijitIconClear,.dijitDisabled .dijitIconDelete,.dijitDisabled .dijitIconUndo,.dijitDisabled .dijitIconEdit,.dijitDisabled .dijitIconNewTask,.dijitDisabled .dijitIconEditTask,.dijitDisabled .dijitIconEditProperty,.dijitDisabled .dijitIconTask,.dijitDisabled .dijitIconFilter,.dijitDisabled .dijitIconConfigure,.dijitDisabled .dijitIconSearch,.dijitDisabled .dijitIconApplication,.dijitDisabled .dijitIconBookmark,.dijitDisabled .dijitIconChart,.dijitDisabled .dijitIconConnector,.dijitDisabled .dijitIconDatabase,.dijitDisabled .dijitIconDocuments,.dijitDisabled .dijitIconMail,.dijitDisabled .dijitLeaf,.dijitDisabled .dijitIconFile,.dijitDisabled .dijitIconFunction,.dijitDisabled .dijitIconKey,.dijitDisabled .dijitIconPackage,.dijitDisabled .dijitIconSample,.dijitDisabled .dijitIconTable,.dijitDisabled .dijitIconUsers,.dijitDisabled .dijitFolderClosed,.dijitDisabled .dijitIconFolderClosed,.dijitDisabled .dijitFolderOpened,.dijitDisabled .dijitIconFolderOpen,.dijitDisabled .dijitIconError {background-image: url('images/commonIconsObjActDisabled.png');}.dijitIconSave {background-position: 0;}.dijitIconPrint {background-position: -16px;}.dijitIconCut {background-position: -32px;}.dijitIconCopy {background-position: -48px;}.dijitIconClear {background-position: -64px;}.dijitIconDelete {background-position: -80px;}.dijitIconUndo {background-position: -96px;}.dijitIconEdit {background-position: -112px;}.dijitIconNewTask {background-position: -128px;}.dijitIconEditTask {background-position: -144px;}.dijitIconEditProperty {background-position: -160px;}.dijitIconTask {background-position: -176px;}.dijitIconFilter {background-position: -192px;}.dijitIconConfigure {background-position: -208px;}.dijitIconSearch {background-position: -224px;}.dijitIconError {background-position: -496px;} .dijitIconApplication {background-position: -240px;}.dijitIconBookmark {background-position: -256px;}.dijitIconChart {background-position: -272px;}.dijitIconConnector {background-position: -288px;}.dijitIconDatabase {background-position: -304px;}.dijitIconDocuments {background-position: -320px;}.dijitIconMail {background-position: -336px;}.dijitIconFile, .dijitLeaf {background-position: -352px;}.dijitIconFunction {background-position: -368px;}.dijitIconKey {background-position: -384px;}.dijitIconPackage{background-position: -400px;}.dijitIconSample {background-position: -416px;}.dijitIconTable {background-position: -432px;}.dijitIconUsers {background-position: -448px;}.dijitIconFolderClosed, .dijitFolderClosed {background-position: -464px;}.dijitIconFolderOpen, .dijitFolderOpened {background-position: -480px;}.dijitIconLoading {background:url('images/loadingAnimation_rtl.gif') no-repeat; height: 20px; width: 20px;}
|
1
api/js/webodf/collab/dijit/icons/commonIcons_rtl.css
Normal file
@ -0,0 +1 @@
|
||||
.dijitRtl .dijitIconSave,.dijitRtl .dijitIconPrint,.dijitRtl .dijitIconCut,.dijitRtl .dijitIconCopy,.dijitRtl .dijitIconClear,.dijitRtl .dijitIconDelete,.dijitRtl .dijitIconUndo,.dijitRtl .dijitIconEdit,.dijitRtl .dijitIconNewTask,.dijitRtl .dijitIconEditTask,.dijitRtl .dijitIconEditProperty,.dijitRtl .dijitIconTask,.dijitRtl .dijitIconFilter,.dijitRtl .dijitIconConfigure,.dijitRtl .dijitIconSearch,.dijitRtl .dijitIconApplication,.dijitRtl .dijitIconBookmark,.dijitRtl .dijitIconChart,.dijitRtl .dijitIconConnector,.dijitRtl .dijitIconDatabase,.dijitRtl .dijitIconDocuments,.dijitRtl .dijitIconMail,.dijitRtl .dijitLeaf,.dijitRtl .dijitIconFile,.dijitRtl .dijitIconFunction,.dijitRtl .dijitIconKey,.dijitRtl .dijitIconPackage,.dijitRtl .dijitIconSample,.dijitRtl .dijitIconTable,.dijitRtl .dijitIconUsers,.dijitRtl .dijitFolderClosed,.dijitRtl .dijitIconFolderClosed,.dijitRtl .dijitFolderOpened,.dijitRtl .dijitIconFolderOpen,.dijitRtl .dijitIconError {background-image: url('images/commonIconsObjActEnabled_rtl.png'); width: 16px; height: 16px;}.dj_ie6 .dijitRtl .dijitIconSave,.dj_ie6 .dijitRtl .dijitIconPrint,.dj_ie6 .dijitRtl .dijitIconCut,.dj_ie6 .dijitRtl .dijitIconCopy,.dj_ie6 .dijitRtl .dijitIconClear,.dj_ie6 .dijitRtl .dijitIconDelete,.dj_ie6 .dijitRtl .dijitIconUndo,.dj_ie6 .dijitRtl .dijitIconEdit,.dj_ie6 .dijitRtl .dijitIconNewTask,.dj_ie6 .dijitRtl .dijitIconEditTask,.dj_ie6 .dijitRtl .dijitIconEditProperty,.dj_ie6 .dijitRtl .dijitIconTask,.dj_ie6 .dijitRtl .dijitIconFilter,.dj_ie6 .dijitRtl .dijitIconConfigure,.dj_ie6 .dijitRtl .dijitIconSearch,.dj_ie6 .dijitRtl .dijitIconApplication,.dj_ie6 .dijitRtl .dijitIconBookmark,.dj_ie6 .dijitRtl .dijitIconChart,.dj_ie6 .dijitRtl .dijitIconConnector,.dj_ie6 .dijitRtl .dijitIconDatabase,.dj_ie6 .dijitRtl .dijitIconDocuments,.dj_ie6 .dijitRtl .dijitIconMail,.dj_ie6 .dijitRtl .dijitLeaf,.dj_ie6 .dijitRtl .dijitIconFile,.dj_ie6 .dijitRtl .dijitIconFunction,.dj_ie6 .dijitRtl .dijitIconKey,.dj_ie6 .dijitRtl .dijitIconPackage,.dj_ie6 .dijitRtl .dijitIconSample,.dj_ie6 .dijitRtl .dijitIconTable,.dj_ie6 .dijitRtl .dijitIconUsers,.dj_ie6 .dijitRtl .dijitFolderClosed,.dj_ie6 .dijitRtl .dijitIconFolderClosed,.dj_ie6 .dijitRtl .dijitFolderOpened,.dj_ie6 .dijitRtl .dijitIconFolderOpen,.dj_ie6 .dijitRtl .dijitIconError {background-image: url('images/commonIconsObjActEnabled8bit_rtl.png');}.dijitRtl .dijitDisabled .dijitIconSave,.dijitRtl .dijitDisabled .dijitIconPrint,.dijitRtl .dijitDisabled .dijitIconCut,.dijitRtl .dijitDisabled .dijitIconCopy,.dijitRtl .dijitDisabled .dijitIconClear,.dijitRtl .dijitDisabled .dijitIconDelete,.dijitRtl .dijitDisabled .dijitIconUndo,.dijitRtl .dijitDisabled .dijitIconEdit,.dijitRtl .dijitDisabled .dijitIconNewTask,.dijitRtl .dijitDisabled .dijitIconEditTask,.dijitRtl .dijitDisabled .dijitIconEditProperty,.dijitRtl .dijitDisabled .dijitIconTask,.dijitRtl .dijitDisabled .dijitIconFilter,.dijitRtl .dijitDisabled .dijitIconConfigure,.dijitRtl .dijitDisabled .dijitIconSearch,.dijitRtl .dijitDisabled .dijitIconApplication,.dijitRtl .dijitDisabled .dijitIconBookmark,.dijitRtl .dijitDisabled .dijitIconChart,.dijitRtl .dijitDisabled .dijitIconConnector,.dijitRtl .dijitDisabled .dijitIconDatabase,.dijitRtl .dijitDisabled .dijitIconDocuments,.dijitRtl .dijitDisabled .dijitIconMail,.dijitRtl .dijitDisabled .dijitLeaf,.dijitRtl .dijitDisabled .dijitIconFile,.dijitRtl .dijitDisabled .dijitIconFunction,.dijitRtl .dijitDisabled .dijitIconKey,.dijitRtl .dijitDisabled .dijitIconPackage,.dijitRtl .dijitDisabled .dijitIconSample,.dijitRtl .dijitDisabled .dijitIconTable,.dijitRtl .dijitDisabled .dijitIconUsers,.dijitRtl .dijitDisabled .dijitFolderClosed,.dijitRtl .dijitDisabled .dijitIconFolderClosed,.dijitRtl .dijitDisabled .dijitFolderOpened,.dijitRtl .dijitDisabled .dijitIconFolderOpen,.dijitRtl .dijitDisabled .dijitIconError {background-image: url('images/commonIconsObjActDisabled_rtl.png');}
|
1
api/js/webodf/collab/dijit/icons/editorIcons.css
Normal file
@ -0,0 +1 @@
|
||||
.dijitEditorIcon {background-image: url('images/editorIconsEnabled.png'); background-repeat: no-repeat; width: 18px; height: 18px; text-align: center;}.dijitDisabled .dijitEditorIcon {background-image: url('images/editorIconsDisabled.png');}.dijitEditorIconSep {background-position: 0;}.dijitEditorIconSave {background-position: -18px;}.dijitEditorIconPrint {background-position: -36px;}.dijitEditorIconCut {background-position: -54px;}.dijitEditorIconCopy {background-position: -72px;}.dijitEditorIconPaste {background-position: -90px;}.dijitEditorIconDelete {background-position: -108px;}.dijitEditorIconCancel {background-position: -126px;}.dijitEditorIconUndo {background-position: -144px;}.dijitEditorIconRedo {background-position: -162px;}.dijitEditorIconSelectAll {background-position: -180px;}.dijitEditorIconBold {background-position: -198px;}.dijitEditorIconItalic {background-position: -216px;}.dijitEditorIconUnderline {background-position: -234px;}.dijitEditorIconStrikethrough {background-position: -252px;}.dijitEditorIconSuperscript {background-position: -270px;}.dijitEditorIconSubscript {background-position: -288px;}.dijitEditorIconJustifyCenter {background-position: -306px;}.dijitEditorIconJustifyFull {background-position: -324px;}.dijitEditorIconJustifyLeft {background-position: -342px;}.dijitEditorIconJustifyRight {background-position: -360px;}.dijitEditorIconIndent {background-position: -378px;}.dijitEditorIconOutdent {background-position: -396px;}.dijitEditorIconListBulletIndent {background-position: -414px;}.dijitEditorIconListBulletOutdent {background-position: -432px;}.dijitEditorIconListNumIndent {background-position: -450px;}.dijitEditorIconListNumOutdent {background-position: -468px;}.dijitEditorIconTabIndent {background-position: -486px;}.dijitEditorIconLeftToRight {background-position: -504px;}.dijitEditorIconRightToLeft, .dijitEditorIconToggleDir {background-position: -522px;}.dijitEditorIconBackColor {background-position: -540px;}.dijitEditorIconForeColor {background-position: -558px;}.dijitEditorIconHiliteColor {background-position: -576px;}.dijitEditorIconNewPage {background-position: -594px;}.dijitEditorIconInsertImage {background-position: -612px;}.dijitEditorIconInsertTable {background-position: -630px;}.dijitEditorIconSpace {background-position: -648px;}.dijitEditorIconInsertHorizontalRule {background-position: -666px;}.dijitEditorIconInsertOrderedList {background-position: -684px;}.dijitEditorIconInsertUnorderedList {background-position: -702px;}.dijitEditorIconCreateLink {background-position: -720px;}.dijitEditorIconUnlink {background-position: -738px;}.dijitEditorIconViewSource {background-position: -756px;}.dijitEditorIconRemoveFormat {background-position: -774px;}.dijitEditorIconFullScreen {background-position: -792px;}.dijitEditorIconWikiword {background-position: -810px;}
|
1
api/js/webodf/collab/dijit/icons/editorIcons_rtl.css
Normal file
@ -0,0 +1 @@
|
||||
.dijitEditorRtl .dijitEditorIcon {background-image: url('images/editorIconsEnabled_rtl.png');}.dijitEditorRtlDisabled .dijitEditorIcon {background-image: url('images/editorIconsDisabled_rtl.png');}.dijitToolbarRtl .dijitToolbarSeparator {background-image: url('images/editorIconsEnabled_rtl.png');}
|
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 10 KiB |
BIN
api/js/webodf/collab/dijit/icons/images/editorIconsDisabled.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 6.8 KiB |
BIN
api/js/webodf/collab/dijit/icons/images/editorIconsEnabled.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 7.0 KiB |
BIN
api/js/webodf/collab/dijit/icons/images/loadingAnimation_rtl.gif
Normal file
After Width: | Height: | Size: 1.5 KiB |
3
api/js/webodf/collab/dijit/themes/a11y/README.txt
Normal file
@ -0,0 +1,3 @@
|
||||
This folder contains images used by all themes when in "high-contrast" mode.
|
||||
|
||||
If you think you need to put something here, please talk to Becky or Bill first.
|
BIN
api/js/webodf/collab/dijit/themes/a11y/colors3x4.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
api/js/webodf/collab/dijit/themes/a11y/colors7x10.png
Normal file
After Width: | Height: | Size: 808 B |
After Width: | Height: | Size: 2.8 KiB |
290
api/js/webodf/collab/dijit/themes/claro/Calendar.css
Normal file
@ -0,0 +1,290 @@
|
||||
/* Calendar
|
||||
*
|
||||
* Styling Calendar mainly includes:
|
||||
*
|
||||
* 1. Calendar container
|
||||
* .dijitCalendar - main container
|
||||
* .dijitCalendarHover / .dijitCalendarActive - states e.g. hover,active
|
||||
*
|
||||
* 2. Month
|
||||
* .dijitCalendarMonthContainer
|
||||
* .dijitCalendarMonthLabel
|
||||
* .dijitCalendarDecrease / .dijitCalendarDecrease - icons for switching to previous/next month
|
||||
* .dijitCalendarArrowActive .dijitCalendarDecrease - states e.g. hover,active
|
||||
*
|
||||
* 3. Date
|
||||
* .dijitCalendarDayLabelTemplate - week day column header e.g. S M T W T F S
|
||||
* .dijitCalendarDateTemplate - date label wrapper
|
||||
* .dijitCalendarPreviousMonth .dijitCalendarDateLabel - special labels for previous or next month
|
||||
* .dijitCalendarSelectedDate .dijitCalendarDateLabel - styles for selected date
|
||||
* .dijitCalendarDisabledDate .dijitCalendarDateLabel - styles for disabled date
|
||||
* .dijitCalendarActiveDate .dijitCalendarDateLabel - states e.g. hover,active
|
||||
*
|
||||
* 4. Year
|
||||
* .dijitCalendarYearContainer
|
||||
* .dijitCalendarYearLabel
|
||||
* .dijitCalendarPreviousYear /.dijitCalendarNextYear
|
||||
* .dijitCalendarNextYearHover / .dijitCalendarPreviousYearHover - states e.g. hover,active
|
||||
*
|
||||
* 5. Dropdown Month Menu
|
||||
* .dijitCalendarMonthMenu - menu container
|
||||
* .dijitCalendarMonthMenu .dijitCalendarMonthLabel - month label in menu item
|
||||
* .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover - menu item hover state
|
||||
*/
|
||||
.claro .dijitCalendar {
|
||||
border: solid 1px #b5bcc7;
|
||||
border-collapse: separate;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: #cfe5fa;
|
||||
background-image: url("images/calendar.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
text-align: center;
|
||||
padding: 6px 5px 3px 5px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendar {
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendar img {
|
||||
border: none;
|
||||
}
|
||||
.claro .dijitCalendarHover,
|
||||
.claro .dijitCalendar:hover,
|
||||
.claro .dijitCalendarActive {
|
||||
/* treat dijitCalendarActive like hover since there's
|
||||
* no concept of clicking a Calendar as a whole (although you can click things inside the calendar)
|
||||
*/
|
||||
background-color: #abd6ff;
|
||||
border: solid 1px #759dc0;
|
||||
}
|
||||
.claro .dijitCalendarMonthContainer th {
|
||||
text-align: center;
|
||||
padding-bottom: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.claro .dijitCalendarMonthLabel {
|
||||
color: #000;
|
||||
font-size: 1.091em;
|
||||
padding: 0 4px;
|
||||
}
|
||||
/* next/previous month arrows */
|
||||
.claro .dijitCalendarIncrementControl {
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
background-image: url("images/calendarArrows.png");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendarIncrementControl {
|
||||
background-image: url("images/calendarArrows8bit.png");
|
||||
}
|
||||
.claro .dijitCalendarIncrease {
|
||||
background-position: -18px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowHover .dijitCalendarDecrease,
|
||||
.claro .dijitCalendarArrow:hover .dijitCalendarDecrease {
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowHover .dijitCalendarIncrease,
|
||||
.claro .dijitCalendarArrow:hover .dijitCalendarIncrease {
|
||||
background-position: -55px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowActive .dijitCalendarDecrease,
|
||||
.claro .dijitCalendarArrow:active .dijitCalendarDecrease {
|
||||
background-position: -72px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowActive .dijitCalendarIncrease,
|
||||
.claro .dijitCalendarArrow:active .dijitCalendarIncrease {
|
||||
background-position: -91px 0;
|
||||
}
|
||||
.claro .dijitA11ySideArrow {
|
||||
/* text +/- labels instead of arrow icons, for high contrast mode */
|
||||
display: none;
|
||||
}
|
||||
.claro .dijitCalendarDayLabelTemplate {
|
||||
padding-bottom: 0;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #b5bcc7;
|
||||
padding: 0 3px 2px;
|
||||
}
|
||||
.claro .dijitCalendarDayLabel {
|
||||
padding: 0 4px 0 4px;
|
||||
font-weight: bold;
|
||||
font-size: 0.909em;
|
||||
text-align: center;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitCalendarDateTemplate {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
padding-top: 0;
|
||||
font-size: 0.909em;
|
||||
font-family: Arial;
|
||||
font-weight: bold;
|
||||
letter-spacing: .05em;
|
||||
text-align: center;
|
||||
color: #000;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendarDateTemplate {
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendarPreviousMonth,
|
||||
.claro .dijitCalendarNextMonth {
|
||||
background-color: #e5f2fe;
|
||||
background-image: none;
|
||||
border-bottom: solid 1px #d3d3d3;
|
||||
/* todo: redundant with above .dijitCalendarDateTemplate rule */
|
||||
}
|
||||
.claro .dijitCalendarDateTemplate .dijitCalendarDateLabel {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 3px 5px 3px 4px;
|
||||
border: solid 1px #fff;
|
||||
/* intentionally matches background-color, no visible border until hover/selection */
|
||||
background-color: rgba(171, 212, 251, 0);
|
||||
/* transparent causes black-flash animation problem on webkit */
|
||||
-webkit-transition-property: background-color, border;
|
||||
-moz-transition-property: background-color, border;
|
||||
transition-property: background-color, border;
|
||||
-webkit-transition-duration: 0.35s;
|
||||
-moz-transition-duration: 0.35s;
|
||||
transition-duration: 0.35s;
|
||||
}
|
||||
.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel,
|
||||
.claro .dijitCalendarNextMonth .dijitCalendarDateLabel {
|
||||
color: #759dc0;
|
||||
border-color: #e5f2fe;
|
||||
/* intentionally matches background-color, no visible border until hover/selection */
|
||||
}
|
||||
.claro .dijitCalendarYearContainer {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.claro .dijitCalendarYearControl {
|
||||
padding: 1px 2px 2px 2px;
|
||||
}
|
||||
.claro .dijitCalendarYearLabel {
|
||||
padding: 2px 0 0 0;
|
||||
margin: 0;
|
||||
font-size: 1.17em;
|
||||
}
|
||||
.claro .dijitCalendarYearLabel span {
|
||||
/* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
|
||||
vertical-align: middle;
|
||||
}
|
||||
.claro .dijitCalendarSelectedYear {
|
||||
padding: 0 3px;
|
||||
}
|
||||
.claro .dijitCalendarNextYear,
|
||||
.claro .dijitCalendarPreviousYear {
|
||||
padding: 1px 6px 1px 6px;
|
||||
font-size: 0.909em;
|
||||
}
|
||||
.claro .dijitCalendarSelectedYear {
|
||||
font-size: 1.091em;
|
||||
color: #000;
|
||||
}
|
||||
/* End Normal Calendar Style */
|
||||
/* Hovered Calendar Style */
|
||||
.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel,
|
||||
.claro .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel {
|
||||
background-color: #abd6ff;
|
||||
border: solid 1px #759dc0;
|
||||
color: #000;
|
||||
-webkit-transition-duration: 0.2s;
|
||||
-moz-transition-duration: 0.2s;
|
||||
transition-duration: 0.2s;
|
||||
}
|
||||
.claro .dijitCalendarNextYearHover,
|
||||
.claro .dijitCalendarNextYear:hover,
|
||||
.claro .dijitCalendarPreviousYearHover,
|
||||
.claro .dijitCalendarPreviousYear:hover {
|
||||
color: #000;
|
||||
border: solid 1px #fff;
|
||||
padding: 0 5px 0 5px;
|
||||
/* reduced by 1 to make room for border */
|
||||
background-color: #e5f2fe;
|
||||
}
|
||||
/* End Hovered Calendar Style */
|
||||
/* Active Calendar Style */
|
||||
.claro .dijitCalendarNextYearActive,
|
||||
.claro .dijitCalendarNextYear:active .claro .dijitCalendarPreviousYearActive,
|
||||
.claro .dijitCalendarPreviousYear:active {
|
||||
border: solid 1px #759dc0;
|
||||
padding: 0 5px 0 5px;
|
||||
/* reduced by 1 to make room for border */
|
||||
background-color: #7dbdfa;
|
||||
}
|
||||
.claro .dijitCalendarActiveDate .dijitCalendarDateLabel,
|
||||
.claro .dijitCalendarEnabledDate:active .dijitCalendarDateLabel {
|
||||
background-color: #7dbdfa;
|
||||
border: solid 1px #fff;
|
||||
-webkit-transition-duration: 0.1s;
|
||||
-moz-transition-duration: 0.1s;
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
|
||||
background-image: none;
|
||||
}
|
||||
/* End Active Calendar Style */
|
||||
/* Selected Calendar Style */
|
||||
.claro .dijitCalendarSelectedDate .dijitCalendarDateLabel {
|
||||
color: #000;
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
/* End Selected Calendar Style */
|
||||
/* Disabled Calendar Style*/
|
||||
.claro .dijitCalendarDisabledDate .dijitCalendarDateLabel {
|
||||
color: #818181;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
/* End Disabled Calendar Style */
|
||||
/* Styling for month DropDownButton */
|
||||
.claro .dijitCalendar .dijitDropDownButton {
|
||||
margin: 0;
|
||||
}
|
||||
.claro .dijitCalendar .dijitButtonText {
|
||||
padding: 1px 0 3px;
|
||||
margin-right: -4px;
|
||||
}
|
||||
.claro .dijitCalendar .dijitDropDownButton .dijitButtonNode {
|
||||
padding: 0 3px 0 2px;
|
||||
border: solid 1px #b5bcc7;
|
||||
-webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
-moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
|
||||
background-color: #e5f2fe;
|
||||
border: solid 1px #fff;
|
||||
}
|
||||
/* Styling for month drop down list */
|
||||
.claro .dijitCalendarMonthMenu {
|
||||
border-color: #759dc0;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel {
|
||||
border-top: solid 1px #fff;
|
||||
/* intentionally invisible until hover */
|
||||
border-bottom: solid 1px #fff;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover,
|
||||
.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
|
||||
border-color: #759dc0;
|
||||
border-width: 1px 0;
|
||||
background-color: #abd6ff;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr= #ffffff , endColorstr= #abd6ff );
|
||||
}
|
277
api/js/webodf/collab/dijit/themes/claro/Calendar.less
Normal file
@ -0,0 +1,277 @@
|
||||
/* Calendar
|
||||
*
|
||||
* Styling Calendar mainly includes:
|
||||
*
|
||||
* 1. Calendar container
|
||||
* .dijitCalendar - main container
|
||||
* .dijitCalendarHover / .dijitCalendarActive - states e.g. hover,active
|
||||
*
|
||||
* 2. Month
|
||||
* .dijitCalendarMonthContainer
|
||||
* .dijitCalendarMonthLabel
|
||||
* .dijitCalendarDecrease / .dijitCalendarDecrease - icons for switching to previous/next month
|
||||
* .dijitCalendarArrowActive .dijitCalendarDecrease - states e.g. hover,active
|
||||
*
|
||||
* 3. Date
|
||||
* .dijitCalendarDayLabelTemplate - week day column header e.g. S M T W T F S
|
||||
* .dijitCalendarDateTemplate - date label wrapper
|
||||
* .dijitCalendarPreviousMonth .dijitCalendarDateLabel - special labels for previous or next month
|
||||
* .dijitCalendarSelectedDate .dijitCalendarDateLabel - styles for selected date
|
||||
* .dijitCalendarDisabledDate .dijitCalendarDateLabel - styles for disabled date
|
||||
* .dijitCalendarActiveDate .dijitCalendarDateLabel - states e.g. hover,active
|
||||
*
|
||||
* 4. Year
|
||||
* .dijitCalendarYearContainer
|
||||
* .dijitCalendarYearLabel
|
||||
* .dijitCalendarPreviousYear /.dijitCalendarNextYear
|
||||
* .dijitCalendarNextYearHover / .dijitCalendarPreviousYearHover - states e.g. hover,active
|
||||
*
|
||||
* 5. Dropdown Month Menu
|
||||
* .dijitCalendarMonthMenu - menu container
|
||||
* .dijitCalendarMonthMenu .dijitCalendarMonthLabel - month label in menu item
|
||||
* .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover - menu item hover state
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitCalendar {
|
||||
border: solid 1px @border-color;
|
||||
border-collapse: separate; // in case user CSS has set border-collapse: collapse for tables
|
||||
.border-radius(4px);
|
||||
|
||||
// Background color and alpha-gradient
|
||||
background-color: @calendar-background-color;
|
||||
background-image: url("images/calendar.png"); // fallback for browsers that don't support CSS gradients
|
||||
background-repeat: repeat-x; // so bottom of calendar isn't affected by gradient image repeating
|
||||
.alpha-white-gradient(1, 0px, 0.4, 2px, 0, 100%);
|
||||
|
||||
text-align:center;
|
||||
padding:6px 5px 3px 5px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendar {
|
||||
background-image:none; // because on IE6 background-image overrides background-color
|
||||
}
|
||||
.claro .dijitCalendar img {
|
||||
border:none;
|
||||
}
|
||||
.claro .dijitCalendarHover, .claro .dijitCalendar:hover,
|
||||
.claro .dijitCalendarActive {
|
||||
/* treat dijitCalendarActive like hover since there's
|
||||
* no concept of clicking a Calendar as a whole (although you can click things inside the calendar)
|
||||
*/
|
||||
background-color: @hovered-background-color;
|
||||
border:solid 1px @hovered-border-color;
|
||||
}
|
||||
.claro .dijitCalendarMonthContainer th {
|
||||
text-align:center;
|
||||
padding-bottom:4px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
.claro .dijitCalendarMonthLabel {
|
||||
color: @text-color;
|
||||
font-size: 1.091em;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
/* next/previous month arrows */
|
||||
.claro .dijitCalendarIncrementControl {
|
||||
width:18px;
|
||||
height:16px;
|
||||
background-image: url(@image-calendar-arrows);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendarIncrementControl {
|
||||
background-image: url(@image-calendar-arrows-ie6);
|
||||
}
|
||||
.claro .dijitCalendarIncrease {
|
||||
background-position:-18px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowHover .dijitCalendarDecrease,
|
||||
.claro .dijitCalendarArrow:hover .dijitCalendarDecrease {
|
||||
background-position:-36px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowHover .dijitCalendarIncrease,
|
||||
.claro .dijitCalendarArrow:hover .dijitCalendarIncrease {
|
||||
background-position:-55px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowActive .dijitCalendarDecrease,
|
||||
.claro .dijitCalendarArrow:active .dijitCalendarDecrease {
|
||||
background-position:-72px 0;
|
||||
}
|
||||
.claro .dijitCalendarArrowActive .dijitCalendarIncrease,
|
||||
.claro .dijitCalendarArrow:active .dijitCalendarIncrease {
|
||||
background-position:-91px 0;
|
||||
}
|
||||
.claro .dijitA11ySideArrow {
|
||||
/* text +/- labels instead of arrow icons, for high contrast mode */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.claro .dijitCalendarDayLabelTemplate {
|
||||
padding-bottom:0;
|
||||
text-align:center;
|
||||
border-bottom:1px solid @border-color;
|
||||
padding:0 3px 2px;
|
||||
}
|
||||
.claro .dijitCalendarDayLabel {
|
||||
padding:0 4px 0 4px;
|
||||
font-weight:bold;
|
||||
font-size:0.909em;
|
||||
text-align:center;
|
||||
color: @text-color;
|
||||
}
|
||||
.claro .dijitCalendarDateTemplate {
|
||||
text-align:center;
|
||||
background-color:@calendar-currentmonth-background-color;
|
||||
border-bottom: 1px solid @minor-border-color;
|
||||
padding-top:0;
|
||||
font-size:0.909em;
|
||||
font-family: Arial;
|
||||
font-weight:bold;
|
||||
letter-spacing:.05em;
|
||||
text-align:center;
|
||||
color: @text-color;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendarDateTemplate {
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendarPreviousMonth,
|
||||
.claro .dijitCalendarNextMonth {
|
||||
background-color: @calendar-adjacentmonth-background-color;
|
||||
background-image:none;
|
||||
border-bottom:solid 1px @minor-border-color; /* todo: redundant with above .dijitCalendarDateTemplate rule */
|
||||
}
|
||||
.claro .dijitCalendarDateTemplate .dijitCalendarDateLabel {
|
||||
text-decoration:none;
|
||||
display:block;
|
||||
padding:3px 5px 3px 4px;
|
||||
border:solid 1px @calendar-currentmonth-background-color; /* intentionally matches background-color, no visible border until hover/selection */
|
||||
background-color:rgba(171,212,251,0); /* transparent causes black-flash animation problem on webkit */
|
||||
.transition-property(background-color, border);
|
||||
.transition-duration(.35s);
|
||||
}
|
||||
.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel,
|
||||
.claro .dijitCalendarNextMonth .dijitCalendarDateLabel{
|
||||
color: @calendar-adjacentmonth-text-color;
|
||||
border-color: @calendar-adjacentmonth-background-color; /* intentionally matches background-color, no visible border until hover/selection */
|
||||
}
|
||||
|
||||
.claro .dijitCalendarYearContainer {
|
||||
vertical-align:middle;
|
||||
}
|
||||
.claro .dijitCalendarYearControl {
|
||||
padding: 1px 2px 2px 2px;
|
||||
}
|
||||
.claro .dijitCalendarYearLabel {
|
||||
padding: 2px 0 0 0;
|
||||
margin: 0;
|
||||
font-size: 1.17em;
|
||||
}
|
||||
.claro .dijitCalendarYearLabel span {
|
||||
/* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
|
||||
vertical-align:middle;
|
||||
}
|
||||
.claro .dijitCalendarSelectedYear {
|
||||
padding:0 3px;
|
||||
}
|
||||
.claro .dijitCalendarNextYear,
|
||||
.claro .dijitCalendarPreviousYear {
|
||||
padding: 1px 6px 1px 6px;
|
||||
font-size:0.909em;
|
||||
}
|
||||
.claro .dijitCalendarSelectedYear {
|
||||
font-size:1.091em;
|
||||
color:@selected-text-color;
|
||||
}
|
||||
/* End Normal Calendar Style */
|
||||
/* Hovered Calendar Style */
|
||||
.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel,
|
||||
.claro .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel {
|
||||
background-color:@hovered-background-color;
|
||||
border:solid 1px @hovered-border-color;
|
||||
color:@hovered-text-color;
|
||||
.transition-duration(.2s);
|
||||
}
|
||||
.claro .dijitCalendarNextYearHover, .claro .dijitCalendarNextYear:hover,
|
||||
.claro .dijitCalendarPreviousYearHover, .claro .dijitCalendarPreviousYear:hover {
|
||||
color:@hovered-text-color;
|
||||
border:solid 1px @calendar-button-hovered-border-color;
|
||||
padding: 0 5px 0 5px; /* reduced by 1 to make room for border */
|
||||
background-color: @calendar-button-hovered-background-color;
|
||||
}
|
||||
/* End Hovered Calendar Style */
|
||||
/* Active Calendar Style */
|
||||
.claro .dijitCalendarNextYearActive, .claro .dijitCalendarNextYear:active
|
||||
.claro .dijitCalendarPreviousYearActive, .claro .dijitCalendarPreviousYear:active {
|
||||
border: solid 1px @calendar-button-pressed-border-color;
|
||||
padding: 0 5px 0 5px; /* reduced by 1 to make room for border */
|
||||
background-color:@calendar-button-pressed-background-color;
|
||||
}
|
||||
.claro .dijitCalendarActiveDate .dijitCalendarDateLabel,
|
||||
.claro .dijitCalendarEnabledDate:active .dijitCalendarDateLabel {
|
||||
background-color: @calendar-date-pressed-background-color;
|
||||
border:solid 1px @calendar-date-pressed-border-color;
|
||||
.transition-duration(.1s);
|
||||
}
|
||||
.dj_ie6 .claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
|
||||
background-image:none;
|
||||
}
|
||||
/* End Active Calendar Style */
|
||||
/* Selected Calendar Style */
|
||||
.claro .dijitCalendarSelectedDate .dijitCalendarDateLabel {
|
||||
color:@selected-text-color;
|
||||
background-color: @calendar-date-selected-background-color;
|
||||
border-color: @calendar-date-selected-border-color;
|
||||
}
|
||||
/* End Selected Calendar Style */
|
||||
/* Disabled Calendar Style*/
|
||||
.claro .dijitCalendarDisabledDate .dijitCalendarDateLabel {
|
||||
color: @disabled-text-color;
|
||||
text-decoration:line-through;
|
||||
}
|
||||
|
||||
/* End Disabled Calendar Style */
|
||||
|
||||
/* Styling for month DropDownButton */
|
||||
|
||||
.claro .dijitCalendar .dijitDropDownButton {
|
||||
margin: 0;
|
||||
}
|
||||
.claro .dijitCalendar .dijitButtonText {
|
||||
padding: 1px 0 3px;
|
||||
margin-right:-4px;
|
||||
}
|
||||
.claro .dijitCalendar .dijitDropDownButton .dijitButtonNode {
|
||||
padding: 0 3px 0 2px;
|
||||
border:solid 1px @border-color;
|
||||
.box-shadow(0 0 0 rgba(0,0,0,0));
|
||||
|
||||
// Override background settings from vanilla .dijitButtonNode. We want to inherit background of Calendar.
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
|
||||
background-color: @calendar-button-hovered-background-color;
|
||||
border:solid 1px @calendar-button-hovered-border-color;
|
||||
}
|
||||
|
||||
/* Styling for month drop down list */
|
||||
|
||||
.claro .dijitCalendarMonthMenu {
|
||||
border-color: @popup-border-color;
|
||||
background-color: @menu-background-color;
|
||||
text-align:center;
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel {
|
||||
border-top: solid 1px @menu-background-color; /* intentionally invisible until hover */
|
||||
border-bottom: solid 1px @menu-background-color;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover,
|
||||
.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
|
||||
border-color: @hovered-border-color;
|
||||
border-width:1px 0;
|
||||
.gradient-and-filter(@hovered-background-color, 70, 0);
|
||||
}
|
18
api/js/webodf/collab/dijit/themes/claro/Calendar_rtl.css
Normal file
@ -0,0 +1,18 @@
|
||||
.claro .dijitCalendarRtl .dijitCalendarIncrease {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarDecrease {
|
||||
background-position: -18px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarIncrease {
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarDecrease {
|
||||
background-position: -55px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarIncrease {
|
||||
background-position: -72px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarDecrease {
|
||||
background-position: -91px 0;
|
||||
}
|
19
api/js/webodf/collab/dijit/themes/claro/Calendar_rtl.less
Normal file
@ -0,0 +1,19 @@
|
||||
.claro .dijitCalendarRtl .dijitCalendarIncrease{
|
||||
background-position: 0 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarDecrease {
|
||||
background-position: -18px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarIncrease {
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarDecrease {
|
||||
background-position: -55px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarIncrease {
|
||||
background-position: -72px 0;
|
||||
}
|
||||
.claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarDecrease {
|
||||
background-position: -91px 0;
|
||||
}
|
||||
|
41
api/js/webodf/collab/dijit/themes/claro/ColorPalette.css
Normal file
@ -0,0 +1,41 @@
|
||||
/* ColorPalette
|
||||
*
|
||||
* Styling of the ColorPalette consists of the following:
|
||||
*
|
||||
* 1. the whole color palette
|
||||
* .dijitColorPalette - for outline, border, and background color of the whole color palette
|
||||
* Note: outline does not work for IE
|
||||
*
|
||||
* 2. the color swatch
|
||||
* .dijitColorPalette .dijitPaletteImg
|
||||
* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
|
||||
* displays border around a color swatch
|
||||
*
|
||||
* 3. hovered swatch
|
||||
* .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg
|
||||
* the hovered state of the color swatch - adds border
|
||||
*
|
||||
* 4. active and selected swatch
|
||||
* .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg
|
||||
* .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
|
||||
* adds border for active or selected state
|
||||
*/
|
||||
.claro .dijitColorPalette {
|
||||
border: 1px solid #b5bcc7;
|
||||
background: #fff;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.claro .dijitColorPalette .dijitPaletteImg {
|
||||
/* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
|
||||
* displays border around a color swatch
|
||||
* overrides border color in dijit.css */
|
||||
border: 1px solid #d3d3d3;
|
||||
}
|
||||
.claro .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
.claro .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,
|
||||
.claro .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
|
||||
border: 2px solid #000;
|
||||
}
|
44
api/js/webodf/collab/dijit/themes/claro/ColorPalette.less
Normal file
@ -0,0 +1,44 @@
|
||||
/* ColorPalette
|
||||
*
|
||||
* Styling of the ColorPalette consists of the following:
|
||||
*
|
||||
* 1. the whole color palette
|
||||
* .dijitColorPalette - for outline, border, and background color of the whole color palette
|
||||
* Note: outline does not work for IE
|
||||
*
|
||||
* 2. the color swatch
|
||||
* .dijitColorPalette .dijitPaletteImg
|
||||
* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
|
||||
* displays border around a color swatch
|
||||
*
|
||||
* 3. hovered swatch
|
||||
* .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg
|
||||
* the hovered state of the color swatch - adds border
|
||||
*
|
||||
* 4. active and selected swatch
|
||||
* .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg
|
||||
* .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
|
||||
* adds border for active or selected state
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitColorPalette {
|
||||
border: 1px solid @border-color;
|
||||
background: @colorpalette-background-color;
|
||||
.border-radius(0);
|
||||
}
|
||||
|
||||
.claro .dijitColorPalette .dijitPaletteImg {
|
||||
/* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
|
||||
* displays border around a color swatch
|
||||
* overrides border color in dijit.css */
|
||||
border: 1px solid @minor-border-color;
|
||||
}
|
||||
.claro .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg {
|
||||
border: 1px solid @swatch-hovered-border-color;
|
||||
}
|
||||
.claro .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,
|
||||
.claro .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
|
||||
border: 2px solid @swatch-selected-border-color;
|
||||
}
|
98
api/js/webodf/collab/dijit/themes/claro/Common.css
Normal file
@ -0,0 +1,98 @@
|
||||
/* ========= Styling rules to affect widgets ========= */
|
||||
.claro .dijitPopup {
|
||||
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.claro .dijitTooltipDialogPopup {
|
||||
/* exception popups: do not use a shadow on these because they aren't rectangular */
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
/* The highlight is shown in the ComboBox menu. TODO: move to form/Common.less */
|
||||
.claro .dijitComboBoxHighlightMatch {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitFocusedLabel {
|
||||
/* for checkboxes or radio buttons, hatch border around the corresponding label, to indicate focus */
|
||||
outline: 1px dotted #494949;
|
||||
}
|
||||
/* Drag and Drop*/
|
||||
.claro .dojoDndItem {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
-webkit-transition-duration: 0.25s;
|
||||
-moz-transition-duration: 0.25s;
|
||||
transition-duration: 0.25s;
|
||||
-webkit-transition-property: background-color, border-color;
|
||||
-moz-transition-property: background-color, border-color;
|
||||
transition-property: background-color, border-color;
|
||||
}
|
||||
.claro .dojoDndItemOver {
|
||||
background-color: #abd6ff;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 1px;
|
||||
border: solid 1px #759dc0;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dojoDndItemAnchor,
|
||||
.claro .dojoDndItemSelected {
|
||||
background-color: #cfe5fa;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 1px;
|
||||
border: solid 1px #759dc0;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dojoDndItemBefore,
|
||||
.claro .dojoDndItemAfter {
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro table.dojoDndAvatar {
|
||||
border: 1px solid #b5bcc7;
|
||||
border-collapse: collapse;
|
||||
background-color: #fff;
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.claro .dojoDndAvatarHeader td {
|
||||
height: 20px;
|
||||
padding-left: 21px;
|
||||
}
|
||||
.claro.dojoDndMove .dojoDndAvatarHeader,
|
||||
.claro.dojoDndCopy .dojoDndAvatarHeader {
|
||||
background-image: url("images/dnd.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 2px -122px;
|
||||
}
|
||||
.claro .dojoDndAvatarItem td {
|
||||
padding: 5px;
|
||||
}
|
||||
.claro.dojoDndMove .dojoDndAvatarHeader {
|
||||
background-color: #f58383;
|
||||
background-position: 2px -103px;
|
||||
}
|
||||
.claro.dojoDndCopy .dojoDndAvatarHeader {
|
||||
background-color: #f58383;
|
||||
background-position: 2px -68px;
|
||||
}
|
||||
.claro.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader {
|
||||
background-color: #97e68d;
|
||||
background-position: 2px -33px;
|
||||
}
|
||||
.claro.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader {
|
||||
background-color: #97e68d;
|
||||
background-position: 2px 2px;
|
||||
}
|
86
api/js/webodf/collab/dijit/themes/claro/Common.less
Normal file
@ -0,0 +1,86 @@
|
||||
/* ========= Styling rules to affect widgets ========= */
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitPopup {
|
||||
.box-shadow(0 1px 5px rgba(0,0,0,0.25));
|
||||
}
|
||||
.claro .dijitTooltipDialogPopup {
|
||||
/* exception popups: do not use a shadow on these because they aren't rectangular */
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
/* The highlight is shown in the ComboBox menu. TODO: move to form/Common.less */
|
||||
.claro .dijitComboBoxHighlightMatch {
|
||||
background-color: @select-matchedtext-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitFocusedLabel {
|
||||
/* for checkboxes or radio buttons, hatch border around the corresponding label, to indicate focus */
|
||||
outline: 1px dotted @focus-outline-color;
|
||||
}
|
||||
|
||||
/* Drag and Drop*/
|
||||
.claro .dojoDndItem {
|
||||
border-color: rgba(0,0,0,0); // rgba() instead of none to prevent flash on hover fade-in
|
||||
.transition-duration(.25s);
|
||||
.transition-property(background-color, border-color)
|
||||
}
|
||||
.claro .dojoDndItemOver {
|
||||
// Hovered item. Matches dijitTreeRowHover.
|
||||
background-color:@hovered-background-color;
|
||||
.standard-gradient;
|
||||
padding: 1px; // reduce from 2px in dijit.css
|
||||
border:solid 1px @hovered-border-color;
|
||||
color:@hovered-text-color;
|
||||
}
|
||||
.claro .dojoDndItemAnchor,
|
||||
.claro .dojoDndItemSelected {
|
||||
// Selected items(s). Matches dijitTreeRowSelected.
|
||||
background-color:@selected-background-color;
|
||||
.standard-gradient;
|
||||
padding: 1px; // reduce from 2px in dijit.css
|
||||
border:solid 1px @selected-border-color;
|
||||
color:@selected-text-color;
|
||||
}
|
||||
|
||||
.claro .dojoDndItemBefore,
|
||||
.claro .dojoDndItemAfter {
|
||||
// line to indicate that user is dropping before/after this dojoDndItem
|
||||
border-color: @dnd-dropseparator-color;
|
||||
}
|
||||
|
||||
.claro table.dojoDndAvatar {
|
||||
border: 1px solid @border-color;
|
||||
border-collapse: collapse;
|
||||
background-color: @dnd-avatar-background-color;
|
||||
.box-shadow(0 1px 3px rgba(0, 0, 0, .25));
|
||||
}
|
||||
.claro .dojoDndAvatarHeader td {
|
||||
height: 20px;
|
||||
padding-left:21px;
|
||||
}
|
||||
.claro.dojoDndMove .dojoDndAvatarHeader, .claro.dojoDndCopy .dojoDndAvatarHeader {
|
||||
background-image: url(@image-dnd);
|
||||
background-repeat: no-repeat;
|
||||
background-position:2px -122px;
|
||||
}
|
||||
.claro .dojoDndAvatarItem td {
|
||||
padding: 5px;
|
||||
}
|
||||
.claro.dojoDndMove .dojoDndAvatarHeader {
|
||||
background-color: @dnd-avatar-header-background-color;
|
||||
background-position:2px -103px;
|
||||
}
|
||||
.claro.dojoDndCopy .dojoDndAvatarHeader {
|
||||
background-color: @dnd-avatar-header-background-color;
|
||||
background-position:2px -68px;
|
||||
}
|
||||
.claro.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader {
|
||||
background-color: @dnd-avatar-candrop-header-background-color;
|
||||
background-position:2px -33px;
|
||||
}
|
||||
.claro.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader {
|
||||
background-color: @dnd-avatar-candrop-header-background-color;
|
||||
background-position:2px 2px;
|
||||
}
|
205
api/js/webodf/collab/dijit/themes/claro/Dialog.css
Normal file
@ -0,0 +1,205 @@
|
||||
/* Dialog
|
||||
*
|
||||
* Styling Dialog includes two sections: Dialog and Tooltip & TooltipDialog
|
||||
*
|
||||
* Dialog:
|
||||
* 1. Dialog (default styling):
|
||||
* .dijitDialog - styles for dialog's bounding box
|
||||
*
|
||||
* 2. Dialog title
|
||||
* .dijitDialogTitleBar - styles for the title container at the top of dialog
|
||||
* .dijitDialogTitle - the text container in dialog title
|
||||
*
|
||||
* 3. Dialog content
|
||||
* .dijitDialogPaneContent - main container for content area and action bar
|
||||
* .dijitDialogPaneContentArea - styles for content container
|
||||
*
|
||||
* 4. Dialog action bar
|
||||
* .dijitDialogPaneActionBar - styles for action buttons lie at the bottom of dialog pane content
|
||||
*
|
||||
* 5. Dialog underlay
|
||||
* .dijitDialogUnderlay - div under the dialog which used for separate dialog and page content
|
||||
*
|
||||
*
|
||||
* Tooltip & TooltipDialog:
|
||||
* 1. tooltip content container:
|
||||
* .dijitTooltipContainer - tooltip content container
|
||||
*
|
||||
* 2. tooltip connector:
|
||||
* .dijitTooltipConnector - tooltip anchor includes 4 direction(up, down, left, right)
|
||||
*/
|
||||
.claro .dijitDialog {
|
||||
border: 1px solid #759dc0;
|
||||
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.claro .dijitDialogPaneContent {
|
||||
background: #fff repeat-x top left;
|
||||
border-top: 1px solid #759dc0;
|
||||
padding: 10px 8px;
|
||||
position: relative;
|
||||
}
|
||||
.claro .dijitDialogPaneContentArea {
|
||||
/* trick to get action bar (gray bar at bottom with OK/cancel buttons) to span from
|
||||
* left to right but still indent dialog content
|
||||
*/
|
||||
margin: -10px -8px;
|
||||
padding: 10px 8px;
|
||||
}
|
||||
.claro .dijitDialogPaneActionBar {
|
||||
/* gray bar at bottom of dialog with OK/Cancel buttons */
|
||||
background-color: #efefef;
|
||||
padding: 3px 5px 2px 7px;
|
||||
text-align: right;
|
||||
border-top: 1px solid #d3d3d3;
|
||||
margin: 10px -8px -10px;
|
||||
}
|
||||
.claro .dijitTooltipDialog .dijitDialogPaneActionBar {
|
||||
-webkit-border-bottom-right-radius: 4px;
|
||||
-webkit-border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
-moz-border-radius-bottomright: 4px;
|
||||
-moz-border-radius-bottomleft: 4px;
|
||||
margin: 10px -10px -8px;
|
||||
}
|
||||
.claro .dijitDialogPaneActionBar .dijitButton {
|
||||
float: none;
|
||||
}
|
||||
.claro .dijitDialogTitleBar {
|
||||
/* outer container for the titlebar of the dialog */
|
||||
border: 1px solid #fff;
|
||||
border-top: none;
|
||||
background-color: #abd6ff;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 5px 7px 4px 7px;
|
||||
}
|
||||
.claro .dijitDialogTitle {
|
||||
/* typography and styling of the dialog title */
|
||||
padding: 0 1px;
|
||||
font-size: 1.091em;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitDialogCloseIcon {
|
||||
/* the default close icon for the dialog */
|
||||
background: url("images/dialogCloseIcon.png");
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
height: 15px;
|
||||
width: 21px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitDialogCloseIcon {
|
||||
background-image: url("images/dialogCloseIcon8bit.png");
|
||||
}
|
||||
.claro .dijitDialogCloseIconHover {
|
||||
background-position: -21px;
|
||||
}
|
||||
.claro .dijitDialogCloseIconActive {
|
||||
background-position: -42px;
|
||||
}
|
||||
/* Tooltip and TooltipDialog */
|
||||
.claro .dijitTooltip,
|
||||
.claro .dijitTooltipDialog {
|
||||
/* the outermost dom node, holding the connector and container */
|
||||
background: transparent;
|
||||
/* make the area on the sides of the arrow transparent */
|
||||
}
|
||||
.dijitTooltipBelow {
|
||||
/* leave room for arrow above content */
|
||||
padding-top: 13px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
}
|
||||
.dijitTooltipAbove {
|
||||
/* leave room for arrow below content */
|
||||
padding-bottom: 13px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
}
|
||||
.claro .dijitTooltipContainer {
|
||||
/* the part with the text */
|
||||
background-color: #fff;
|
||||
background-image: -moz-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #fff 10px);
|
||||
background-image: -webkit-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #fff 10px);
|
||||
background-image: -o-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #fff 10px);
|
||||
background-image: -ms-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #fff 10px);
|
||||
background-position: bottom;
|
||||
border: 1px solid #759dc0;
|
||||
padding: 6px 8px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
|
||||
font-size: 1em;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitTooltipConnector {
|
||||
/* the arrow piece */
|
||||
border: 0;
|
||||
z-index: 2;
|
||||
background-image: url("images/tooltip.png");
|
||||
background-repeat: no-repeat;
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitTooltipConnector {
|
||||
background-image: url("images/tooltip8bit.png");
|
||||
}
|
||||
.claro .dijitTooltipABRight .dijitTooltipConnector {
|
||||
/* above or below tooltip, but the arrow appears on the right,
|
||||
and the right edges of target and tooltip are aligned rather than the left */
|
||||
left: auto !important;
|
||||
right: 3px;
|
||||
}
|
||||
.claro .dijitTooltipBelow .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips below an element */
|
||||
top: 0;
|
||||
left: 3px;
|
||||
background-position: -31px 0;
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
}
|
||||
.claro .dijitTooltipAbove .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips above an element */
|
||||
bottom: 0;
|
||||
left: 3px;
|
||||
background-position: -15px 0;
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
}
|
||||
.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector,
|
||||
.dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
|
||||
bottom: -1px;
|
||||
}
|
||||
.claro .dijitTooltipLeft {
|
||||
padding-right: 14px;
|
||||
}
|
||||
.claro .dijitTooltipLeft .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
|
||||
right: 0;
|
||||
background-position: 0 0;
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
}
|
||||
.claro .dijitTooltipRight {
|
||||
padding-left: 14px;
|
||||
}
|
||||
.claro .dijitTooltipRight .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
|
||||
left: 0;
|
||||
background-position: -48px 0;
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
}
|
||||
.claro .dijitDialogUnderlay {
|
||||
background: #fff;
|
||||
}
|
209
api/js/webodf/collab/dijit/themes/claro/Dialog.less
Normal file
@ -0,0 +1,209 @@
|
||||
/* Dialog
|
||||
*
|
||||
* Styling Dialog includes two sections: Dialog and Tooltip & TooltipDialog
|
||||
*
|
||||
* Dialog:
|
||||
* 1. Dialog (default styling):
|
||||
* .dijitDialog - styles for dialog's bounding box
|
||||
*
|
||||
* 2. Dialog title
|
||||
* .dijitDialogTitleBar - styles for the title container at the top of dialog
|
||||
* .dijitDialogTitle - the text container in dialog title
|
||||
*
|
||||
* 3. Dialog content
|
||||
* .dijitDialogPaneContent - main container for content area and action bar
|
||||
* .dijitDialogPaneContentArea - styles for content container
|
||||
*
|
||||
* 4. Dialog action bar
|
||||
* .dijitDialogPaneActionBar - styles for action buttons lie at the bottom of dialog pane content
|
||||
*
|
||||
* 5. Dialog underlay
|
||||
* .dijitDialogUnderlay - div under the dialog which used for separate dialog and page content
|
||||
*
|
||||
*
|
||||
* Tooltip & TooltipDialog:
|
||||
* 1. tooltip content container:
|
||||
* .dijitTooltipContainer - tooltip content container
|
||||
*
|
||||
* 2. tooltip connector:
|
||||
* .dijitTooltipConnector - tooltip anchor includes 4 direction(up, down, left, right)
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitDialog {
|
||||
border: 1px solid @popup-border-color;
|
||||
.box-shadow(0 1px 5px rgba(0,0,0,0.25));
|
||||
}
|
||||
|
||||
.claro .dijitDialogPaneContent {
|
||||
background: @pane-background-color repeat-x top left;
|
||||
border-top: 1px solid @popup-border-color;
|
||||
padding:10px 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.claro .dijitDialogPaneContentArea {
|
||||
/* trick to get action bar (gray bar at bottom with OK/cancel buttons) to span from
|
||||
* left to right but still indent dialog content
|
||||
*/
|
||||
margin: -10px -8px;
|
||||
padding: 10px 8px;
|
||||
}
|
||||
|
||||
.claro .dijitDialogPaneActionBar {
|
||||
/* gray bar at bottom of dialog with OK/Cancel buttons */
|
||||
background-color: @bar-background-color;
|
||||
padding: 3px 5px 2px 7px;
|
||||
text-align: right;
|
||||
border-top: 1px solid @minor-border-color;
|
||||
margin: 10px -8px -10px;
|
||||
}
|
||||
.claro .dijitTooltipDialog .dijitDialogPaneActionBar {
|
||||
-webkit-border-bottom-right-radius: 4px;
|
||||
-webkit-border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
-moz-border-radius-bottomright: 4px;
|
||||
-moz-border-radius-bottomleft: 4px;
|
||||
margin: 10px -10px -8px;
|
||||
}
|
||||
.claro .dijitDialogPaneActionBar .dijitButton {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.claro .dijitDialogTitleBar {
|
||||
/* outer container for the titlebar of the dialog */
|
||||
border: 1px solid @dialog-titlebar-border-color;
|
||||
border-top:none;
|
||||
background-color: @dialog-titlebar-background-color;
|
||||
.standard-gradient;
|
||||
padding: 5px 7px 4px 7px;
|
||||
}
|
||||
|
||||
.claro .dijitDialogTitle {
|
||||
/* typography and styling of the dialog title */
|
||||
padding: 0 1px;
|
||||
font-size:1.091em;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.claro .dijitDialogCloseIcon {
|
||||
/* the default close icon for the dialog */
|
||||
background: url(@image-dialog-close);
|
||||
background-repeat:no-repeat;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
height: 15px;
|
||||
width: 21px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitDialogCloseIcon {
|
||||
background-image: url(@image-dialog-close-ie6);
|
||||
}
|
||||
.claro .dijitDialogCloseIconHover {
|
||||
background-position:-21px;
|
||||
}
|
||||
.claro .dijitDialogCloseIconActive {
|
||||
background-position:-42px;
|
||||
}
|
||||
|
||||
/* Tooltip and TooltipDialog */
|
||||
|
||||
.claro .dijitTooltip,
|
||||
.claro .dijitTooltipDialog {
|
||||
/* the outermost dom node, holding the connector and container */
|
||||
background: transparent; /* make the area on the sides of the arrow transparent */
|
||||
}
|
||||
.dijitTooltipBelow {
|
||||
/* leave room for arrow above content */
|
||||
padding-top: 13px;
|
||||
padding-left:3px;
|
||||
padding-right:3px;
|
||||
}
|
||||
|
||||
.dijitTooltipAbove {
|
||||
/* leave room for arrow below content */
|
||||
padding-bottom: 13px;
|
||||
padding-left:3px;
|
||||
padding-right:3px;
|
||||
}
|
||||
|
||||
.claro .dijitTooltipContainer {
|
||||
/* the part with the text */
|
||||
background-color:@popup-background-color;
|
||||
.linear-gradient(bottom, @tooltip-gradient-color 0px, @popup-background-color 10px);
|
||||
background-position:bottom;
|
||||
border:1px solid @popup-border-color;
|
||||
padding:6px 8px;
|
||||
.border-radius(4px);
|
||||
.box-shadow(0 1px 3px rgba(0,0,0,0.25));
|
||||
font-size: 1em;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.claro .dijitTooltipConnector {
|
||||
/* the arrow piece */
|
||||
border: 0;
|
||||
z-index: 2;
|
||||
background-image:url(@image-tooltip);
|
||||
background-repeat:no-repeat;
|
||||
width:16px;
|
||||
height:14px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitTooltipConnector {
|
||||
background-image:url(@image-tooltip-ie6);
|
||||
}
|
||||
.claro .dijitTooltipABRight .dijitTooltipConnector {
|
||||
/* above or below tooltip, but the arrow appears on the right,
|
||||
and the right edges of target and tooltip are aligned rather than the left */
|
||||
left: auto !important;
|
||||
right: 3px;
|
||||
}
|
||||
|
||||
.claro .dijitTooltipBelow .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips below an element */
|
||||
top: 0;
|
||||
left: 3px;
|
||||
background-position:-31px 0;
|
||||
width:16px;
|
||||
height:14px;
|
||||
}
|
||||
|
||||
.claro .dijitTooltipAbove .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips above an element */
|
||||
bottom: 0;
|
||||
left: 3px;
|
||||
background-position:-15px 0;
|
||||
width:16px;
|
||||
height:14px;
|
||||
}
|
||||
.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector,
|
||||
.dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
|
||||
bottom: -1px;
|
||||
}
|
||||
|
||||
.claro .dijitTooltipLeft {
|
||||
padding-right: 14px;
|
||||
}
|
||||
.claro .dijitTooltipLeft .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
|
||||
right: 0;
|
||||
background-position:0 0;
|
||||
width:16px;
|
||||
height:14px;
|
||||
}
|
||||
|
||||
.claro .dijitTooltipRight {
|
||||
padding-left: 14px;
|
||||
}
|
||||
.claro .dijitTooltipRight .dijitTooltipConnector {
|
||||
/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
|
||||
left: 0;
|
||||
background-position:-48px 0;
|
||||
width:16px;
|
||||
height:14px;
|
||||
}
|
||||
|
||||
.claro .dijitDialogUnderlay {
|
||||
background: @dialog-underlay-color;
|
||||
}
|
9
api/js/webodf/collab/dijit/themes/claro/Dialog_rtl.css
Normal file
@ -0,0 +1,9 @@
|
||||
/* Dialog */
|
||||
.claro .dijitDialogRtl .dijitDialogCloseIcon {
|
||||
right: auto;
|
||||
left: 5px;
|
||||
}
|
||||
.claro .dijitDialogRtl .dijitDialogPaneActionBar {
|
||||
text-align: left;
|
||||
padding: 3px 7px 2px 5px;
|
||||
}
|
13
api/js/webodf/collab/dijit/themes/claro/Dialog_rtl.less
Normal file
@ -0,0 +1,13 @@
|
||||
/* Dialog */
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitDialogRtl .dijitDialogCloseIcon {
|
||||
right: auto;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
.claro .dijitDialogRtl .dijitDialogPaneActionBar {
|
||||
text-align: left;
|
||||
padding: 3px 7px 2px 5px;
|
||||
}
|
55
api/js/webodf/collab/dijit/themes/claro/Editor.css
Normal file
@ -0,0 +1,55 @@
|
||||
/* Editor
|
||||
*
|
||||
* Styling Editor means styling the Editor inside iframe container (dijitEditorIFrameContainer)
|
||||
*
|
||||
* 1. Editor iframe container (default styling):
|
||||
* .dijitEditorIFrameContainer - normal state styles: background-color, border, padding
|
||||
*
|
||||
* 2. hovered Editor iframe container (ie, mouse hover on editor)
|
||||
* .dijitEditorHover .dijitEditorIFrameContainer/dijitEditorIFrame - styles when mouse hover on the container
|
||||
*
|
||||
* 3. focused Editor iframe container (ie, mouse focus on the editor pane)
|
||||
* .dijitEditorFocused .dijitEditorIFrameContainer/dijitEditorIFrame - styles when container focused
|
||||
*
|
||||
* 3. disabled Editor iframe container
|
||||
* .dijitEditorDisabled - editor's inner iframe container disable status styles: background, border
|
||||
*/
|
||||
.claro .dijitEditorIFrameContainer {
|
||||
padding: 3px 3px 1px 10px;
|
||||
}
|
||||
.claro .dijitEditorIFrame {
|
||||
background-color: #fff;
|
||||
}
|
||||
.claro .dijitEditor {
|
||||
border: 1px solid #b5bcc7;
|
||||
}
|
||||
.claro .dijitEditor .dijitEditorIFrameContainer {
|
||||
background-color: #fff;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.claro .dijitEditorHover .dijitEditorIFrameContainer,
|
||||
.claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame {
|
||||
background-color: #e5f2fe;
|
||||
}
|
||||
.claro .dijitEditorFocused .dijitEditorIFrameContainer,
|
||||
.claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame {
|
||||
background-color: #fff;
|
||||
}
|
||||
.claro .dijitEditorHover .dijitEditorIFrameContainer,
|
||||
.claro .dijitEditorFocused .dijitEditorIFrameContainer {
|
||||
background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -ms-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
}
|
||||
/* Disabled */
|
||||
.claro .dijitEditorDisabled {
|
||||
border: 1px solid #d3d3d3;
|
||||
color: #818181;
|
||||
}
|
||||
.claro .dijitDisabled .dijitEditorIFrame,
|
||||
.claro .dijitDisabled .dijitEditorIFrameContainer,
|
||||
.claro .dijitDisabled .dijitEditorIFrameContainer .dijitEditorIFrame {
|
||||
background-color: #efefef;
|
||||
background-image: none;
|
||||
}
|
57
api/js/webodf/collab/dijit/themes/claro/Editor.less
Normal file
@ -0,0 +1,57 @@
|
||||
/* Editor
|
||||
*
|
||||
* Styling Editor means styling the Editor inside iframe container (dijitEditorIFrameContainer)
|
||||
*
|
||||
* 1. Editor iframe container (default styling):
|
||||
* .dijitEditorIFrameContainer - normal state styles: background-color, border, padding
|
||||
*
|
||||
* 2. hovered Editor iframe container (ie, mouse hover on editor)
|
||||
* .dijitEditorHover .dijitEditorIFrameContainer/dijitEditorIFrame - styles when mouse hover on the container
|
||||
*
|
||||
* 3. focused Editor iframe container (ie, mouse focus on the editor pane)
|
||||
* .dijitEditorFocused .dijitEditorIFrameContainer/dijitEditorIFrame - styles when container focused
|
||||
*
|
||||
* 3. disabled Editor iframe container
|
||||
* .dijitEditorDisabled - editor's inner iframe container disable status styles: background, border
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitEditorIFrameContainer{
|
||||
padding:3px 3px 1px 10px;
|
||||
}
|
||||
.claro .dijitEditorIFrame {
|
||||
background-color: @textbox-background-color;
|
||||
}
|
||||
.claro .dijitEditor {
|
||||
border: 1px solid @border-color;
|
||||
}
|
||||
.claro .dijitEditor .dijitEditorIFrameContainer{
|
||||
background-color: @textbox-background-color;
|
||||
background-repeat:repeat-x;
|
||||
}
|
||||
.claro .dijitEditorHover .dijitEditorIFrameContainer,
|
||||
.claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame{
|
||||
background-color: @textbox-hovered-background-color;
|
||||
}
|
||||
.claro .dijitEditorFocused .dijitEditorIFrameContainer,
|
||||
.claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame{
|
||||
background-color: @textbox-focused-background-color;
|
||||
}
|
||||
.claro .dijitEditorHover .dijitEditorIFrameContainer,
|
||||
.claro .dijitEditorFocused .dijitEditorIFrameContainer {
|
||||
.textbox-background-image;
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
.claro .dijitEditorDisabled {
|
||||
border: 1px solid @disabled-border-color;
|
||||
color: @disabled-text-color;
|
||||
}
|
||||
|
||||
.claro .dijitDisabled .dijitEditorIFrame,
|
||||
.claro .dijitDisabled .dijitEditorIFrameContainer,
|
||||
.claro .dijitDisabled .dijitEditorIFrameContainer .dijitEditorIFrame {
|
||||
background-color: @textbox-disabled-background-color;
|
||||
background-image: none;
|
||||
}
|
4
api/js/webodf/collab/dijit/themes/claro/Editor_rtl.css
Normal file
@ -0,0 +1,4 @@
|
||||
/* Editor */
|
||||
.claro .dijitEditorRtl .dijitEditorIFrameContainer {
|
||||
padding: 3px 10px 1px 3px;
|
||||
}
|
9
api/js/webodf/collab/dijit/themes/claro/Editor_rtl.less
Normal file
@ -0,0 +1,9 @@
|
||||
/* Editor */
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitEditorRtl .dijitEditorIFrameContainer{
|
||||
padding:3px 10px 1px 3px;
|
||||
}
|
||||
|
||||
|
20
api/js/webodf/collab/dijit/themes/claro/InlineEditBox.css
Normal file
@ -0,0 +1,20 @@
|
||||
/* InlineEditBox
|
||||
*
|
||||
* Styling InlineEditBox mainly includes:
|
||||
*
|
||||
* 1. Normal state
|
||||
* .dijitInlineEditBoxDisplayMode - for border
|
||||
*
|
||||
* 2. Hover state
|
||||
* .dijitInlineEditBoxDisplayModeHover - for border and background color
|
||||
*/
|
||||
.claro .dijitInlineEditBoxDisplayMode {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.claro .dijitInlineEditBoxDisplayModeHover {
|
||||
background-color: #e5f2fe;
|
||||
border: solid 1px #759dc0;
|
||||
}
|
||||
.dj_ie6 .claro .dijitInlineEditBoxDisplayMode {
|
||||
border: none;
|
||||
}
|
25
api/js/webodf/collab/dijit/themes/claro/InlineEditBox.less
Normal file
@ -0,0 +1,25 @@
|
||||
/* InlineEditBox
|
||||
*
|
||||
* Styling InlineEditBox mainly includes:
|
||||
*
|
||||
* 1. Normal state
|
||||
* .dijitInlineEditBoxDisplayMode - for border
|
||||
*
|
||||
* 2. Hover state
|
||||
* .dijitInlineEditBoxDisplayModeHover - for border and background color
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitInlineEditBoxDisplayMode {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.claro .dijitInlineEditBoxDisplayModeHover {
|
||||
background-color: @textbox-hovered-background-color;
|
||||
border: solid 1px @hovered-border-color;
|
||||
}
|
||||
|
||||
.dj_ie6 .claro .dijitInlineEditBoxDisplayMode {
|
||||
border: none;
|
||||
}
|
183
api/js/webodf/collab/dijit/themes/claro/Menu.css
Normal file
@ -0,0 +1,183 @@
|
||||
/* Menu
|
||||
|
||||
There are three areas of styling for the Menu:
|
||||
|
||||
1. The menu
|
||||
There are three types of menus:
|
||||
i) Context Menu
|
||||
ii) Drop down Menu
|
||||
iii) Navigation Menu
|
||||
All three types of menus are affected by the .dijitMenu class in which you can set the background-color, padding and border
|
||||
.dijitMenu affects the drop down menu in TimeTextBox, Calendar, ComboBox and FilteringSelect
|
||||
.dijitMenuTable - for padding - also affects Select widget
|
||||
|
||||
2. The menu bar
|
||||
.dijitMenuBar - for border, margins, padding, background-color of the menu bar
|
||||
.dijitMenuBar .dijitMenuItem - for padding, text color of menu items in the menu bar (overrides .dijitMenuItem)
|
||||
|
||||
3. Menu items - items in the menu.
|
||||
.dijitMenuItem - for color
|
||||
.dijitMenuItemHover, .dijitMenuItemSelected - for background-color, border, text color, padding of a menu item or menubar item that has been hovered over or selected
|
||||
.dijitMenuItemActive - for background-color of an active (mousedown) menu item
|
||||
td.dijitMenuItemIconCell - for padding around a menu item's icon
|
||||
td.dijitMenuItemLabel - for padding around a menu item's label
|
||||
.dijitMenuSeparatorTop - for border, top border, of the separator
|
||||
.dijitMenuSeparatorBottom - for bottom margin of the separator
|
||||
|
||||
Styles specific to ComboBox and FilteringSelect widgets:
|
||||
.dijitComboBoxMenu .dijitMenuItem - for padding and border of a menu item in a ComboBox or FilteringSelect widget's menu
|
||||
.dijitComboBoxMenu .dijitMenuItemSelected- for text color, background-color and border of a menu item in a ComboBox or FilteringSelect widget's menu
|
||||
|
||||
*/
|
||||
.claro .dijitMenuBar {
|
||||
border: 1px solid #b5bcc7;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #efefef;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitMenu {
|
||||
background-color: #fff;
|
||||
border: 1px solid #759dc0;
|
||||
/* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
|
||||
margin: -1px 0;
|
||||
}
|
||||
.dj_ie6 .claro .dijitMenu {
|
||||
margin: 0;
|
||||
/* above -1px makes top/bottom borders disappear on IE6 */
|
||||
}
|
||||
.claro .dijitMenuItem {
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitMenuBar .dijitMenuItem {
|
||||
padding: 6px 10px 7px;
|
||||
margin: -1px;
|
||||
}
|
||||
.claro .dijitMenuBar .dijitMenuItemHover,
|
||||
.claro .dijitMenuBar .dijitMenuItemSelected {
|
||||
border: solid 1px #759dc0;
|
||||
padding: 5px 9px 6px;
|
||||
}
|
||||
/* this prevents jiggling upon hover of a menu item */
|
||||
.claro .dijitMenuTable {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
.claro .dijitMenuItem td {
|
||||
padding: 1px;
|
||||
}
|
||||
/* hover over a MenuItem or MenuBarItem */
|
||||
.claro .dijitSelectMenu .dijitMenuItemHover td,
|
||||
.claro .dijitSelectMenu .dijitMenuItemSelected td,
|
||||
.claro .dijitMenuItemHover,
|
||||
.claro .dijitMenuItemSelected {
|
||||
background-color: #abd6ff;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitMenuItemActive {
|
||||
background-image: url("images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.dj_ie .claro .dijitMenuActive .dijitMenuItemHover,
|
||||
.dj_ie .claro .dijitMenuActive .dijitMenuItemSelected,
|
||||
.dj_ie .claro .dijitMenuPassive .dijitMenuItemHover,
|
||||
.dj_ie .claro .dijitMenuPassive .dijitMenuItemSelected {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 5px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
.claro td.dijitMenuItemIconCell {
|
||||
padding: 2px;
|
||||
margin: 0 0 0 4px;
|
||||
}
|
||||
.claro td.dijitMenuItemLabel {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.claro .dijitMenuExpand {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background-image: url("images/spriteArrows.png");
|
||||
background-position: -14px 0;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.claro .dijitMenuItemDisabled .dijitMenuItemIconCell {
|
||||
opacity: 1;
|
||||
}
|
||||
.claro .dijitMenuSeparatorTop {
|
||||
height: auto;
|
||||
margin-top: 1px;
|
||||
/* prevents spacing above/below separator */
|
||||
border-bottom: 1px solid #b5bcc7;
|
||||
}
|
||||
.claro .dijitMenuSeparatorBottom {
|
||||
height: auto;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
/* the checked menu item */
|
||||
.claro .dijitCheckedMenuItemIconChar {
|
||||
display: none;
|
||||
}
|
||||
.claro .dijitCheckedMenuItemIcon {
|
||||
background-image: url("form/images/checkboxRadioButtonStates.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: -15px 50%;
|
||||
width: 15px;
|
||||
height: 16px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCheckedMenuItemIcon {
|
||||
background-image: url("form/images/checkboxAndRadioButtons_IE6.png");
|
||||
}
|
||||
.claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
/*ComboBox Menu*/
|
||||
.claro .dijitComboBoxMenu {
|
||||
margin-left: 0;
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitSelectMenu .dijitMenuItem td,
|
||||
.claro .dijitComboBoxMenu .dijitMenuItem {
|
||||
padding: 2px;
|
||||
border-width: 1px 0 1px 0;
|
||||
border-style: solid;
|
||||
border-color: #fff;
|
||||
}
|
||||
.claro .dijitSelectMenu .dijitMenuItemSelected td,
|
||||
.claro .dijitComboBoxMenu .dijitMenuItemSelected {
|
||||
color: #000;
|
||||
border-color: #759dc0;
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitSelectMenu .dijitMenuItemHover td,
|
||||
.claro .dijitComboBoxMenu .dijitMenuItemHover {
|
||||
color: #000000;
|
||||
border-color: #769dc0;
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitComboBoxMenuActive .dijitMenuItemSelected {
|
||||
background-color: #7dbdfa;
|
||||
/* TODO: why is this a different color than normal .dijitMenuItemSelected? */
|
||||
}
|
||||
.claro .dijitMenuPreviousButton,
|
||||
.claro .dijitMenuNextButton {
|
||||
font-style: italic;
|
||||
}
|
179
api/js/webodf/collab/dijit/themes/claro/Menu.less
Normal file
@ -0,0 +1,179 @@
|
||||
/* Menu
|
||||
|
||||
There are three areas of styling for the Menu:
|
||||
|
||||
1. The menu
|
||||
There are three types of menus:
|
||||
i) Context Menu
|
||||
ii) Drop down Menu
|
||||
iii) Navigation Menu
|
||||
All three types of menus are affected by the .dijitMenu class in which you can set the background-color, padding and border
|
||||
.dijitMenu affects the drop down menu in TimeTextBox, Calendar, ComboBox and FilteringSelect
|
||||
.dijitMenuTable - for padding - also affects Select widget
|
||||
|
||||
2. The menu bar
|
||||
.dijitMenuBar - for border, margins, padding, background-color of the menu bar
|
||||
.dijitMenuBar .dijitMenuItem - for padding, text color of menu items in the menu bar (overrides .dijitMenuItem)
|
||||
|
||||
3. Menu items - items in the menu.
|
||||
.dijitMenuItem - for color
|
||||
.dijitMenuItemHover, .dijitMenuItemSelected - for background-color, border, text color, padding of a menu item or menubar item that has been hovered over or selected
|
||||
.dijitMenuItemActive - for background-color of an active (mousedown) menu item
|
||||
td.dijitMenuItemIconCell - for padding around a menu item's icon
|
||||
td.dijitMenuItemLabel - for padding around a menu item's label
|
||||
.dijitMenuSeparatorTop - for border, top border, of the separator
|
||||
.dijitMenuSeparatorBottom - for bottom margin of the separator
|
||||
|
||||
Styles specific to ComboBox and FilteringSelect widgets:
|
||||
.dijitComboBoxMenu .dijitMenuItem - for padding and border of a menu item in a ComboBox or FilteringSelect widget's menu
|
||||
.dijitComboBoxMenu .dijitMenuItemSelected- for text color, background-color and border of a menu item in a ComboBox or FilteringSelect widget's menu
|
||||
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitMenuBar {
|
||||
border: 1px solid @border-color;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: @bar-background-color;
|
||||
.standard-gradient;
|
||||
}
|
||||
|
||||
.claro .dijitMenu {
|
||||
background-color:@menu-background-color;
|
||||
border: 1px solid @popup-border-color;
|
||||
|
||||
/* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
|
||||
margin: -1px 0;
|
||||
}
|
||||
.dj_ie6 .claro .dijitMenu {
|
||||
margin: 0; /* above -1px makes top/bottom borders disappear on IE6 */
|
||||
}
|
||||
|
||||
.claro .dijitMenuItem {
|
||||
color: @text-color;
|
||||
}
|
||||
.claro .dijitMenuBar .dijitMenuItem {
|
||||
padding: 6px 10px 7px;
|
||||
margin:-1px;
|
||||
}
|
||||
.claro .dijitMenuBar .dijitMenuItemHover,
|
||||
.claro .dijitMenuBar .dijitMenuItemSelected {
|
||||
// on hover or selection of MenuBar item, add border and reduce padding to compensate
|
||||
border:solid 1px @hovered-border-color;
|
||||
padding: 5px 9px 6px;
|
||||
}
|
||||
|
||||
/* this prevents jiggling upon hover of a menu item */
|
||||
.claro .dijitMenuTable {
|
||||
border-collapse:separate;
|
||||
border-spacing:0 0;
|
||||
padding:0;
|
||||
}
|
||||
.claro .dijitMenuItem td{
|
||||
padding:1px;
|
||||
}
|
||||
/* hover over a MenuItem or MenuBarItem */
|
||||
.claro .dijitSelectMenu .dijitMenuItemHover td,
|
||||
.claro .dijitSelectMenu .dijitMenuItemSelected td,
|
||||
.claro .dijitMenuItemHover,
|
||||
.claro .dijitMenuItemSelected {
|
||||
// note: seems like the selected MenuItem should use @pressed-background-color
|
||||
// and .active-gradient, but claro didn't to that
|
||||
background-color: @hovered-background-color;
|
||||
.standard-gradient;
|
||||
}
|
||||
.claro .dijitMenuItemActive {
|
||||
// todo: seems like the selected MenuItem should come here
|
||||
// todo: seems like should use @pressed-background-color
|
||||
.active-gradient;
|
||||
}
|
||||
.dj_ie .claro .dijitMenuActive .dijitMenuItemHover,
|
||||
.dj_ie .claro .dijitMenuActive .dijitMenuItemSelected,
|
||||
.dj_ie .claro .dijitMenuPassive .dijitMenuItemHover,
|
||||
.dj_ie .claro .dijitMenuPassive .dijitMenuItemSelected {
|
||||
// Selectivity set to override ComboBox rules below.
|
||||
// If this rule isn't present, on IE6 hovering an item in the ComboBox drop down causes two
|
||||
// items to be highlighted (except when hovering the first item in the list)
|
||||
padding-top: 6px;
|
||||
padding-bottom: 5px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.claro td.dijitMenuItemIconCell {
|
||||
padding: 2px;
|
||||
margin: 0 0 0 4px;
|
||||
}
|
||||
.claro td.dijitMenuItemLabel {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.claro .dijitMenuExpand {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background-image: url(@image-arrow-sprite);
|
||||
background-position: -14px 0;
|
||||
margin-right:3px;
|
||||
}
|
||||
.claro .dijitMenuItemDisabled .dijitMenuItemIconCell {
|
||||
opacity:1;
|
||||
}
|
||||
.claro .dijitMenuSeparatorTop {
|
||||
height: auto;
|
||||
margin-top:1px; /* prevents spacing above/below separator */
|
||||
border-bottom: 1px solid @border-color
|
||||
}
|
||||
.claro .dijitMenuSeparatorBottom{
|
||||
height: auto;
|
||||
margin-bottom:1px;
|
||||
}
|
||||
/* the checked menu item */
|
||||
.claro .dijitCheckedMenuItemIconChar {
|
||||
display: none;
|
||||
}
|
||||
.claro .dijitCheckedMenuItemIcon {
|
||||
background-image: url(@image-form-checkbox-and-radios);
|
||||
background-repeat:no-repeat;
|
||||
background-position: -15px 50%;
|
||||
width:15px;
|
||||
height:16px;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCheckedMenuItemIcon {
|
||||
background-image: url(@image-form-checkbox-and-radios-ie6);
|
||||
}
|
||||
.claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
|
||||
/*ComboBox Menu*/
|
||||
.claro .dijitComboBoxMenu {
|
||||
margin-left:0;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.claro .dijitSelectMenu .dijitMenuItem td,
|
||||
.claro .dijitComboBoxMenu .dijitMenuItem {
|
||||
padding: @textbox-padding; // Make drop down menu text line up with text in <input>.
|
||||
border-width:1px 0 1px 0;
|
||||
border-style:solid;
|
||||
border-color: @select-dropdownitem-background-color;
|
||||
}
|
||||
.claro .dijitSelectMenu .dijitMenuItemSelected td,
|
||||
.claro .dijitComboBoxMenu .dijitMenuItemSelected {
|
||||
color:@selected-text-color;
|
||||
border-color:@hovered-border-color;
|
||||
background-color:@hovered-background-color;
|
||||
}
|
||||
.claro .dijitSelectMenu .dijitMenuItemHover td,
|
||||
.claro .dijitComboBoxMenu .dijitMenuItemHover {
|
||||
color: #000000;
|
||||
border-color: #769dc0;
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitComboBoxMenuActive .dijitMenuItemSelected {
|
||||
background-color: @select-dropdownitem-hovered-background-color; /* TODO: why is this a different color than normal .dijitMenuItemSelected? */
|
||||
}
|
||||
.claro .dijitMenuPreviousButton, .claro .dijitMenuNextButton {
|
||||
font-style: italic;
|
||||
}
|
8
api/js/webodf/collab/dijit/themes/claro/Menu_rtl.css
Normal file
@ -0,0 +1,8 @@
|
||||
.claro .dijitMenuItemRtl .dijitMenuExpand {
|
||||
background-position: -7px 0;
|
||||
margin-right: 0;
|
||||
margin-left: 3px;
|
||||
}
|
||||
.claro .dijitMenuItemRtl .dijitMenuItemIcon {
|
||||
margin: 0 4px 0 0;
|
||||
}
|
11
api/js/webodf/collab/dijit/themes/claro/Menu_rtl.less
Normal file
@ -0,0 +1,11 @@
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitMenuItemRtl .dijitMenuExpand {
|
||||
background-position: -7px 0;
|
||||
margin-right: 0;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.claro .dijitMenuItemRtl .dijitMenuItemIcon {
|
||||
margin:0 4px 0 0;
|
||||
}
|
66
api/js/webodf/collab/dijit/themes/claro/ProgressBar.css
Normal file
@ -0,0 +1,66 @@
|
||||
/* ProgressBar
|
||||
*
|
||||
* Styling of the ProgressBar consists of the following:
|
||||
*
|
||||
* 1. the base progress bar
|
||||
* .dijitProgressBar - sets margins for the progress bar
|
||||
*
|
||||
* 2. the empty bar
|
||||
* .dijitProgressBarEmpty - sets background img and color for bar or parts of bar that are not finished yet
|
||||
* Also sets border color for whole bar
|
||||
*
|
||||
* 3. tile mode
|
||||
* .dijitProgressBarTile
|
||||
* inner container for finished portion when in 'tile' (image) mode
|
||||
*
|
||||
* 4. full bar mode
|
||||
* .dijitProgressBarFull
|
||||
* adds border to right side of the filled portion of bar
|
||||
*
|
||||
* 5. text for label of bar
|
||||
* .dijitProgressBarLabel - sets text color, which must contrast with both the "Empty" and "Full" parts.
|
||||
*
|
||||
* 6. indeterminate mode
|
||||
* .dijitProgressBarIndeterminate .dijitProgressBarTile
|
||||
* sets animated gif for the progress bar in 'indeterminate' mode
|
||||
*/
|
||||
.claro .dijitProgressBar {
|
||||
margin: 2px 0 2px 0;
|
||||
}
|
||||
.claro .dijitProgressBarEmpty {
|
||||
/* outer container and background of the bar that's not finished yet*/
|
||||
background-color: #fff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitProgressBarTile {
|
||||
/* inner container for finished portion when in 'tile' (image) mode */
|
||||
background-color: #abd6ff;
|
||||
background-image: url("images/progressBarFull.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
|
||||
background-attachment: scroll;
|
||||
}
|
||||
.dj_ie6 .claro .dijitProgressBarTile {
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitProgressBarFull {
|
||||
border-right: 1px solid #759dc0;
|
||||
-webkit-transition-property: width;
|
||||
-moz-transition-property: width;
|
||||
transition-property: width;
|
||||
-webkit-transition-duration: 0.25s;
|
||||
-moz-transition-duration: 0.25s;
|
||||
transition-duration: 0.25s;
|
||||
}
|
||||
.claro .dijitProgressBarLabel {
|
||||
/* Set to a color that contrasts with both the "Empty" and "Full" parts. */
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitProgressBarIndeterminate .dijitProgressBarTile {
|
||||
/* use an animated gif for the progress bar in 'indeterminate' mode;
|
||||
background-color won't appear unless user has turned off background images */
|
||||
background: #efefef url("images/progressBarAnim.gif") repeat-x top;
|
||||
}
|
64
api/js/webodf/collab/dijit/themes/claro/ProgressBar.less
Normal file
@ -0,0 +1,64 @@
|
||||
/* ProgressBar
|
||||
*
|
||||
* Styling of the ProgressBar consists of the following:
|
||||
*
|
||||
* 1. the base progress bar
|
||||
* .dijitProgressBar - sets margins for the progress bar
|
||||
*
|
||||
* 2. the empty bar
|
||||
* .dijitProgressBarEmpty - sets background img and color for bar or parts of bar that are not finished yet
|
||||
* Also sets border color for whole bar
|
||||
*
|
||||
* 3. tile mode
|
||||
* .dijitProgressBarTile
|
||||
* inner container for finished portion when in 'tile' (image) mode
|
||||
*
|
||||
* 4. full bar mode
|
||||
* .dijitProgressBarFull
|
||||
* adds border to right side of the filled portion of bar
|
||||
*
|
||||
* 5. text for label of bar
|
||||
* .dijitProgressBarLabel - sets text color, which must contrast with both the "Empty" and "Full" parts.
|
||||
*
|
||||
* 6. indeterminate mode
|
||||
* .dijitProgressBarIndeterminate .dijitProgressBarTile
|
||||
* sets animated gif for the progress bar in 'indeterminate' mode
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitProgressBar {
|
||||
margin:2px 0 2px 0;
|
||||
}
|
||||
.claro .dijitProgressBarEmpty {
|
||||
/* outer container and background of the bar that's not finished yet*/
|
||||
background-color: @progressbar-empty-background-color;
|
||||
border-color: @progressbar-border-color;
|
||||
}
|
||||
.claro .dijitProgressBarTile {
|
||||
/* inner container for finished portion when in 'tile' (image) mode */
|
||||
background-color: @progressbar-full-background-color;
|
||||
|
||||
// gradient background using CSS gradient, with fallback to image for IE
|
||||
background-image: url("images/progressBarFull.png");
|
||||
background-repeat: repeat-x;
|
||||
.alpha-white-gradient(0.93,0px, 0.41,1px, 0.7,2px, 0,100%);
|
||||
background-attachment: scroll; // override strange "fixed" setting from dijit.css
|
||||
}
|
||||
.dj_ie6 .claro .dijitProgressBarTile {
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitProgressBarFull {
|
||||
border-right:1px solid @progressbar-border-color;
|
||||
.transition-property(width);
|
||||
.transition-duration(.25s);
|
||||
}
|
||||
.claro .dijitProgressBarLabel {
|
||||
/* Set to a color that contrasts with both the "Empty" and "Full" parts. */
|
||||
color: @progressbar-text-color;
|
||||
}
|
||||
.claro .dijitProgressBarIndeterminate .dijitProgressBarTile {
|
||||
/* use an animated gif for the progress bar in 'indeterminate' mode;
|
||||
background-color won't appear unless user has turned off background images */
|
||||
background: @bar-background-color url(@image-progressbar-anim) repeat-x top;
|
||||
}
|
11
api/js/webodf/collab/dijit/themes/claro/README
Normal file
@ -0,0 +1,11 @@
|
||||
These are "less" files that compile into the CSS of claro.
|
||||
|
||||
1. Install node from http://nodejs.org/#download
|
||||
|
||||
2. To compile all the files:
|
||||
|
||||
$ cd dijit/themes/claro
|
||||
$ node compile.js
|
||||
|
||||
|
||||
See http://lesscss.org/ and https://github.com/cloudhead/less.js/ for more information.
|
127
api/js/webodf/collab/dijit/themes/claro/TimePicker.css
Normal file
@ -0,0 +1,127 @@
|
||||
/* Time Picker
|
||||
*
|
||||
* Styling the Time Picker consists of the following:
|
||||
*
|
||||
* 1. minor time values
|
||||
* .dijitTimePickerTick - set text color, size, background color of minor values
|
||||
* .dijitTimePickerTickHover - set hover style of minor time values
|
||||
* dijitTimePickerTickSelected - set selected style of minor time values
|
||||
*
|
||||
* 2. major time values - 1:00, 2:00, times on the hour
|
||||
* set text color, size, background color, left/right margins for "zoom" affect
|
||||
* .dijitTimePickerMarkerHover - to set hover style of major time values
|
||||
* .dijitTimePickerMarkerSelected - set selected style of major time values
|
||||
*
|
||||
* 3. up and down arrow buttons
|
||||
* .dijitTimePicker .dijitButtonNode - background-color, border
|
||||
* .dijitTimePicker .dijitUpArrowHover, .dijitTimePicker .dijitDownArrowHover - set background-color for hover state
|
||||
*
|
||||
* Other classes provide the fundamental structure of the TimePicker and should not be modified.
|
||||
*/
|
||||
/* override Button.css */
|
||||
.claro .dijitTimePicker .dijitButtonNode {
|
||||
padding: 0 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.claro .dijitTimePicker {
|
||||
border: 1px #b5bcc7 solid;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
background-color: #fff;
|
||||
/* TODO: useless? Appears to be overridden by settings on individual elements */
|
||||
}
|
||||
.claro .dijitTimePickerItem {
|
||||
/* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
border-top: solid 1px #b5bcc7;
|
||||
border-bottom: solid 1px #b5bcc7;
|
||||
margin-right: -1px;
|
||||
margin-left: -1px;
|
||||
margin-top: -1px;
|
||||
}
|
||||
.claro .dijitTimePickerTick {
|
||||
/* minor value */
|
||||
color: #818181;
|
||||
background-color: #efefef;
|
||||
font-size: 0.818em;
|
||||
}
|
||||
.claro .dijitTimePickerMarker {
|
||||
/* major value - 1:00, 2:00, times on the hour */
|
||||
background-color: #e5f2fe;
|
||||
font-size: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.claro .dijitTimePickerTickHover,
|
||||
.claro .dijitTimePickerMarkerHover,
|
||||
.claro .dijitTimePickerMarkerSelected,
|
||||
.claro .dijitTimePickerTickSelected {
|
||||
background-color: #7dbdfa;
|
||||
border: solid 1px #b5bcc7;
|
||||
margin-left: -7px;
|
||||
margin-right: -7px;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitTimePickerMarkerSelected,
|
||||
.claro .dijitTimePickerTickSelected {
|
||||
font-size: 1em;
|
||||
}
|
||||
.dj_ie .claro .dijitTimePickerTickHover,
|
||||
.dj_ie .claro .dijitTimePickerMarkerHover,
|
||||
.dj_ie .claro .dijitTimePickerMarkerSelected,
|
||||
.dj_ie .claro .dijitTimePickerTickSelected {
|
||||
width: 114%;
|
||||
}
|
||||
.dj_ie6 .claro .dijitTimePickerTickHover,
|
||||
.dj_ie6 .claro .dijitTimePickerMarkerHover,
|
||||
.dj_ie6 .claro .dijitTimePickerMarkerSelected,
|
||||
.dj_ie6 .claro .dijitTimePickerTickSelected {
|
||||
position: relative;
|
||||
/* creates widening of element */
|
||||
zoom: 1;
|
||||
/* creates widening of element */
|
||||
}
|
||||
.claro .dijitTimePickerTick .dijitTimePickerItemInner {
|
||||
padding: 1px;
|
||||
margin: 0;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitButtonNode {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-color: #b5bcc7;
|
||||
background-color: #efefef;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitArrowButtonInner {
|
||||
height: 100%;
|
||||
/* hack claro.button.css */
|
||||
background-image: url("form/images/commonFormArrows.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: -140px 45%;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner {
|
||||
background-position: -35px 45%;
|
||||
}
|
||||
/* hover */
|
||||
.claro .dijitTimePicker .dijitUpArrowHover,
|
||||
.claro .dijitTimePicker .dijitDownArrowHover {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitUpArrowHover .dijitArrowButtonInner {
|
||||
background-position: -175px 45%;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitDownArrowHover .dijitArrowButtonInner {
|
||||
background-position: -70px 45%;
|
||||
}
|
115
api/js/webodf/collab/dijit/themes/claro/TimePicker.less
Normal file
@ -0,0 +1,115 @@
|
||||
/* Time Picker
|
||||
*
|
||||
* Styling the Time Picker consists of the following:
|
||||
*
|
||||
* 1. minor time values
|
||||
* .dijitTimePickerTick - set text color, size, background color of minor values
|
||||
* .dijitTimePickerTickHover - set hover style of minor time values
|
||||
* dijitTimePickerTickSelected - set selected style of minor time values
|
||||
*
|
||||
* 2. major time values - 1:00, 2:00, times on the hour
|
||||
* set text color, size, background color, left/right margins for "zoom" affect
|
||||
* .dijitTimePickerMarkerHover - to set hover style of major time values
|
||||
* .dijitTimePickerMarkerSelected - set selected style of major time values
|
||||
*
|
||||
* 3. up and down arrow buttons
|
||||
* .dijitTimePicker .dijitButtonNode - background-color, border
|
||||
* .dijitTimePicker .dijitUpArrowHover, .dijitTimePicker .dijitDownArrowHover - set background-color for hover state
|
||||
*
|
||||
* Other classes provide the fundamental structure of the TimePicker and should not be modified.
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
/* override Button.css */
|
||||
.claro .dijitTimePicker .dijitButtonNode {
|
||||
padding: 0 0;
|
||||
.border-radius(0);
|
||||
}
|
||||
.claro .dijitTimePicker{
|
||||
border:1px @border-color solid;
|
||||
border-top:none;
|
||||
border-bottom:none;
|
||||
background-color:#fff; /* TODO: useless? Appears to be overridden by settings on individual elements */
|
||||
}
|
||||
.claro .dijitTimePickerItem{
|
||||
/* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
|
||||
.standard-gradient;
|
||||
border-top:solid 1px @border-color;
|
||||
border-bottom:solid 1px @border-color;
|
||||
margin-right:-1px;
|
||||
margin-left:-1px;
|
||||
margin-top:-1px;
|
||||
}
|
||||
.claro .dijitTimePickerTick {
|
||||
/* minor value */
|
||||
color:@timepicker-minorvalue-text-color;
|
||||
background-color:@timepicker-minorvalue-background-color;
|
||||
font-size:0.818em;
|
||||
}
|
||||
.claro .dijitTimePickerMarker {
|
||||
/* major value - 1:00, 2:00, times on the hour */
|
||||
background-color: @timepicker-majorvalue-background-color;
|
||||
font-size: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.claro .dijitTimePickerTickHover,
|
||||
.claro .dijitTimePickerMarkerHover,
|
||||
.claro .dijitTimePickerMarkerSelected,
|
||||
.claro .dijitTimePickerTickSelected {
|
||||
background-color: @timepicker-value-hovered-background-color;
|
||||
border:solid 1px @border-color;
|
||||
margin-left:-7px;
|
||||
margin-right:-7px;
|
||||
color:@timepicker-value-hovered-text-color;
|
||||
}
|
||||
.claro .dijitTimePickerMarkerSelected,
|
||||
.claro .dijitTimePickerTickSelected {
|
||||
font-size: 1em;
|
||||
}
|
||||
.dj_ie .claro .dijitTimePickerTickHover,
|
||||
.dj_ie .claro .dijitTimePickerMarkerHover,
|
||||
.dj_ie .claro .dijitTimePickerMarkerSelected,
|
||||
.dj_ie .claro .dijitTimePickerTickSelected {
|
||||
width: 114%;
|
||||
}
|
||||
.dj_ie6 .claro .dijitTimePickerTickHover,
|
||||
.dj_ie6 .claro .dijitTimePickerMarkerHover,
|
||||
.dj_ie6 .claro .dijitTimePickerMarkerSelected,
|
||||
.dj_ie6 .claro .dijitTimePickerTickSelected {
|
||||
position: relative; /* creates widening of element */
|
||||
zoom: 1; /* creates widening of element */
|
||||
}
|
||||
.claro .dijitTimePickerTick .dijitTimePickerItemInner {
|
||||
padding:1px;
|
||||
margin:0;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitButtonNode {
|
||||
border-left:none;
|
||||
border-right:none;
|
||||
border-color:@border-color;
|
||||
background-color: @unselected-background-color;
|
||||
.standard-gradient;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitArrowButtonInner{
|
||||
height: 100%; /* hack claro.button.css */
|
||||
background-image: url(@image-form-common-arrows);
|
||||
background-repeat: no-repeat;
|
||||
background-position:-140px 45%;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner{
|
||||
background-position:-35px 45%;
|
||||
}
|
||||
/* hover */
|
||||
.claro .dijitTimePicker .dijitUpArrowHover,
|
||||
.claro .dijitTimePicker .dijitDownArrowHover {
|
||||
background-color: @timepicker-arrow-hovered-background-color;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitUpArrowHover .dijitArrowButtonInner {
|
||||
background-position:-175px 45%;
|
||||
}
|
||||
.claro .dijitTimePicker .dijitDownArrowHover .dijitArrowButtonInner {
|
||||
background-position:-70px 45%;
|
||||
}
|
||||
|
||||
// TODO: should have active rule, for clicking a .dijitTimePickerItem
|
@ -0,0 +1,9 @@
|
||||
/* TimePicker */
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickHover,
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerHover,
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerSelected,
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickSelected {
|
||||
margin-left: -6px;
|
||||
margin-right: -8px;
|
||||
width: 114%;
|
||||
}
|
12
api/js/webodf/collab/dijit/themes/claro/TimePicker_rtl.less
Normal file
@ -0,0 +1,12 @@
|
||||
/* TimePicker */
|
||||
|
||||
@import "variables";
|
||||
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickHover,
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerHover,
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerSelected,
|
||||
.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickSelected {
|
||||
margin-left:-6px;
|
||||
margin-right:-8px;
|
||||
width: 114%;
|
||||
}
|
79
api/js/webodf/collab/dijit/themes/claro/TitlePane.css
Normal file
@ -0,0 +1,79 @@
|
||||
/* TitlePane
|
||||
*
|
||||
* Styling TitlePane means styling the TitlePane title and its content container (dijitTitlePane)
|
||||
*
|
||||
* TitlePane title:
|
||||
* 1. TitlePane title (default styling):
|
||||
* .dijitTitlePaneTitle - TitlePane's title div style: background-color, border
|
||||
*
|
||||
* 2. hovered TitlePane title (ie, mouse hover on a title bar)
|
||||
* .dijitTitlePaneTitleHover - styles when mouse hover on the title div
|
||||
*
|
||||
* 3. active TitlePane title (ie, mouse down on a title bar)
|
||||
* .dijitTitlePaneTitleActive - styles when mouse down on the title div
|
||||
*
|
||||
*
|
||||
* TitlePane Content Container:
|
||||
* 1. outer/inner container:
|
||||
* .dijitTitlePaneContentOuter / dijitTitlePaneContentInner - styles for the content outer div
|
||||
*/
|
||||
.claro .dijitTitlePaneTitle {
|
||||
background-color: #efefef;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
border: 1px solid #b5bcc7;
|
||||
padding: 0 7px 3px 7px;
|
||||
min-height: 17px;
|
||||
}
|
||||
.claro .dijitTitlePaneTitleHover {
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitTitlePaneTitleActive {
|
||||
background-color: #7dbdfa;
|
||||
border-color: #759dc0;
|
||||
background-image: url("images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitTitlePaneTitleFocus {
|
||||
margin-top: 3px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitArrowNode {
|
||||
background-image: url("images/spriteArrows.png");
|
||||
background-repeat: no-repeat;
|
||||
height: 8px;
|
||||
width: 7px;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitOpen .dijitArrowNode {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitClosed .dijitArrowNode {
|
||||
background-position: -14px 0;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitTitlePaneTextNode {
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitTitlePaneContentOuter {
|
||||
background: #fff;
|
||||
border: 1px solid #b5bcc7;
|
||||
border-top: none;
|
||||
}
|
||||
.claro .dijitTitlePaneContentInner {
|
||||
padding: 10px;
|
||||
}
|
||||
.claro .dijitTitlePaneTextNode {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
vertical-align: text-top;
|
||||
}
|
70
api/js/webodf/collab/dijit/themes/claro/TitlePane.less
Normal file
@ -0,0 +1,70 @@
|
||||
/* TitlePane
|
||||
*
|
||||
* Styling TitlePane means styling the TitlePane title and its content container (dijitTitlePane)
|
||||
*
|
||||
* TitlePane title:
|
||||
* 1. TitlePane title (default styling):
|
||||
* .dijitTitlePaneTitle - TitlePane's title div style: background-color, border
|
||||
*
|
||||
* 2. hovered TitlePane title (ie, mouse hover on a title bar)
|
||||
* .dijitTitlePaneTitleHover - styles when mouse hover on the title div
|
||||
*
|
||||
* 3. active TitlePane title (ie, mouse down on a title bar)
|
||||
* .dijitTitlePaneTitleActive - styles when mouse down on the title div
|
||||
*
|
||||
*
|
||||
* TitlePane Content Container:
|
||||
* 1. outer/inner container:
|
||||
* .dijitTitlePaneContentOuter / dijitTitlePaneContentInner - styles for the content outer div
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitTitlePaneTitle {
|
||||
background-color: @unselected-background-color; // TODO: Mailed Jason, shouldn't this toggle to @selected-background-color when pane opened?
|
||||
.standard-gradient;
|
||||
border:1px solid @border-color;
|
||||
padding: 0 7px 3px 7px;
|
||||
min-height:17px;
|
||||
}
|
||||
.claro .dijitTitlePaneTitleHover {
|
||||
background-color: @hovered-background-color;
|
||||
border-color: @hovered-border-color;
|
||||
}
|
||||
.claro .dijitTitlePaneTitleActive {
|
||||
background-color: @pressed-background-color;
|
||||
border-color: @pressed-border-color;
|
||||
.active-gradient;
|
||||
}
|
||||
.claro .dijitTitlePaneTitleFocus {
|
||||
margin-top:3px;
|
||||
padding-bottom:2px;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitArrowNode {
|
||||
background-image: url(@image-arrow-sprite);
|
||||
background-repeat: no-repeat;
|
||||
height: 8px;
|
||||
width: 7px;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitOpen .dijitArrowNode {
|
||||
background-position: 0 0;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitClosed .dijitArrowNode {
|
||||
background-position: -14px 0;
|
||||
}
|
||||
.claro .dijitTitlePane .dijitTitlePaneTextNode {
|
||||
color:@text-color;
|
||||
}
|
||||
.claro .dijitTitlePaneContentOuter {
|
||||
background: @pane-background-color;
|
||||
border:1px solid @border-color;
|
||||
border-top:none;
|
||||
}
|
||||
.claro .dijitTitlePaneContentInner {
|
||||
padding:10px;
|
||||
}
|
||||
.claro .dijitTitlePaneTextNode {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
vertical-align:text-top;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/* TitlePane */
|
||||
.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
|
||||
background-position: -7px 0;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/* TitlePane */
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
|
||||
background-position: -7px 0;
|
||||
}
|
201
api/js/webodf/collab/dijit/themes/claro/Toolbar.css
Normal file
@ -0,0 +1,201 @@
|
||||
/* Toolbar
|
||||
*
|
||||
* Styling Toolbar means styling the toolbar container and the widget inside toolbar (dijitToolbar)
|
||||
*
|
||||
* 1. toolbar (default styling):
|
||||
* .dijitToolbar - styles for outer container
|
||||
*
|
||||
* 2. widget inside toolbar
|
||||
* .dijitToolbar .dijitButtonNode - Button widget
|
||||
* .dijitComboButton - ComboButton widget
|
||||
* .dijitDropDownButton - DropDownButton widget
|
||||
* .dijitToggleButton - ToggleButton widget
|
||||
*
|
||||
* 3. hovered widget inside toolbar (ie, mouse hover on the widget inside)
|
||||
* .dijitToolbar .dijitButtonNodeHover - styles for hovered Button widget
|
||||
*
|
||||
* 4. actived widget inside toolbar (ie, mouse down on the widget inside)
|
||||
* .dijitToolbar .dijitButtonNodeActive - mouse down on Button widget
|
||||
*/
|
||||
.claro .dijitToolbar {
|
||||
border-bottom: 1px solid #b5bcc7;
|
||||
background-color: #efefef;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 2px 0 2px 4px;
|
||||
zoom: 1;
|
||||
}
|
||||
.claro .dijitToolbar label {
|
||||
padding: 0 3px 0 6px;
|
||||
}
|
||||
/** override claro/form/Button.css, and also ComboBox down arrow **/
|
||||
.claro .dijitToolbar .dijitButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
|
||||
border-width: 0;
|
||||
/* on hover/active, border-->1px, padding-->1px */
|
||||
padding: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-transition-property: background-color;
|
||||
-moz-transition-property: background-color;
|
||||
transition-property: background-color;
|
||||
-webkit-transition-duration: 0.3s;
|
||||
-moz-transition-duration: 0.3s;
|
||||
transition-duration: 0.3s;
|
||||
background-color: rgba(171, 214, 255, 0);
|
||||
background-image: none;
|
||||
/* cancel gradient for normal buttons, we don't want any gradient besides toolbar's on non-hovered buttons */
|
||||
}
|
||||
.dj_ie .claro .dijitToolbar .dijitButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
|
||||
background-color: transparent;
|
||||
/* for IE, which doesn't understand rgba(...) */
|
||||
}
|
||||
/* hover status */
|
||||
.dj_ie .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNodeHover,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover,
|
||||
.dj_ie .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode {
|
||||
/* button should still turn blue on hover, so need to override .dj_ie rules above */
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
/* active status */
|
||||
.dj_ie .claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
|
||||
/* button should still turn blue on press, so need to override .dj_ie rules above */
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButton .dijitStretch {
|
||||
/* no rounded border on side adjacent to arrow */
|
||||
-moz-border-radius: 2px 0 0 2px;
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButton .dijitArrowButton {
|
||||
/* no rounded border on side adjacent to button */
|
||||
-moz-border-radius: 0 2px 2px 0;
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
|
||||
padding: 0;
|
||||
}
|
||||
/* hover status */
|
||||
.claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode {
|
||||
border-width: 1px;
|
||||
background-color: #abd6ff;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
|
||||
background-color: #f3ffff;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover,
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
/* active status */
|
||||
.claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
|
||||
border-width: 1px;
|
||||
background-color: #7dbdfa;
|
||||
background-image: url("images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive {
|
||||
-webkit-transition-duration: 0.2s;
|
||||
-moz-transition-duration: 0.2s;
|
||||
transition-duration: 0.2s;
|
||||
border-width: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
|
||||
background-color: #f3ffff;
|
||||
padding: 2px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
|
||||
background-color: #7dbdfa;
|
||||
background-image: url("images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
|
||||
background-color: #7dbdfa;
|
||||
background-image: url("images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
/* Avoid double border between button and arrow */
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton,
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
|
||||
border-left-width: 0;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
|
||||
padding-left: 2px;
|
||||
/* since there's no left border, don't reduce from 2px --> 1px */
|
||||
}
|
||||
/* toggle button checked status */
|
||||
.claro .dijitToolbar .dijitToggleButtonChecked .dijitButtonNode {
|
||||
margin: 0;
|
||||
/* remove margin and add a border */
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
background-image: none;
|
||||
border-color: #759dc0;
|
||||
background-color: #fff;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitToolbarSeparator {
|
||||
/* separator icon in the editor sprite */
|
||||
background: url("../../icons/images/editorIconsEnabled.png");
|
||||
}
|
||||
/* Toolbar inside of disabled Editor */
|
||||
.claro .dijitDisabled .dijitToolbar {
|
||||
background: none;
|
||||
background-color: #efefef;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboBoxDisabled .dijitArrowButtonInner {
|
||||
background-position: 0 50%;
|
||||
}
|
173
api/js/webodf/collab/dijit/themes/claro/Toolbar.less
Normal file
@ -0,0 +1,173 @@
|
||||
/* Toolbar
|
||||
*
|
||||
* Styling Toolbar means styling the toolbar container and the widget inside toolbar (dijitToolbar)
|
||||
*
|
||||
* 1. toolbar (default styling):
|
||||
* .dijitToolbar - styles for outer container
|
||||
*
|
||||
* 2. widget inside toolbar
|
||||
* .dijitToolbar .dijitButtonNode - Button widget
|
||||
* .dijitComboButton - ComboButton widget
|
||||
* .dijitDropDownButton - DropDownButton widget
|
||||
* .dijitToggleButton - ToggleButton widget
|
||||
*
|
||||
* 3. hovered widget inside toolbar (ie, mouse hover on the widget inside)
|
||||
* .dijitToolbar .dijitButtonNodeHover - styles for hovered Button widget
|
||||
*
|
||||
* 4. actived widget inside toolbar (ie, mouse down on the widget inside)
|
||||
* .dijitToolbar .dijitButtonNodeActive - mouse down on Button widget
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitToolbar {
|
||||
border-bottom: 1px solid @border-color;
|
||||
background-color: @bar-background-color;
|
||||
.standard-gradient;
|
||||
padding: 2px 0 2px 4px;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.claro .dijitToolbar label {
|
||||
padding: 0 3px 0 6px;
|
||||
}
|
||||
|
||||
/** override claro/form/Button.css, and also ComboBox down arrow **/
|
||||
.claro .dijitToolbar .dijitButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
|
||||
border-width: 0; /* on hover/active, border-->1px, padding-->1px */
|
||||
padding: 2px;
|
||||
.border-radius(@toolbar-button-border-radius);
|
||||
.box-shadow(none);
|
||||
.transition-property(background-color);
|
||||
.transition-duration(.3s);
|
||||
|
||||
background-color:rgba(171,214,255,0);
|
||||
background-image: none; /* cancel gradient for normal buttons, we don't want any gradient besides toolbar's on non-hovered buttons */
|
||||
}
|
||||
.dj_ie .claro .dijitToolbar .dijitButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
|
||||
background-color: transparent; /* for IE, which doesn't understand rgba(...) */
|
||||
}
|
||||
|
||||
/* hover status */
|
||||
.dj_ie .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNodeHover,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover,
|
||||
.dj_ie .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode {
|
||||
/* button should still turn blue on hover, so need to override .dj_ie rules above */
|
||||
background-color: @button-hovered-background-color;
|
||||
}
|
||||
|
||||
/* active status */
|
||||
.dj_ie .claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
|
||||
.dj_ie .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
|
||||
/* button should still turn blue on press, so need to override .dj_ie rules above */
|
||||
background-color: @button-pressed-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboButton .dijitStretch {
|
||||
/* no rounded border on side adjacent to arrow */
|
||||
.border-radius(@toolbar-button-border-radius 0 0 @toolbar-button-border-radius);
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButton .dijitArrowButton {
|
||||
/* no rounded border on side adjacent to button */
|
||||
.border-radius(0 @toolbar-button-border-radius @toolbar-button-border-radius 0);
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* hover status */
|
||||
.claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode {
|
||||
border-width:1px;
|
||||
background-color: @hovered-background-color;
|
||||
.standard-gradient;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
|
||||
background-color: @toolbar-combobutton-hovered-unhoveredsection-background-color;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover,
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
|
||||
background-color: @hovered-background-color;
|
||||
}
|
||||
|
||||
/* active status */
|
||||
.claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
|
||||
border-width: 1px;
|
||||
background-color:@pressed-background-color;
|
||||
.active-gradient;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive {
|
||||
.transition-duration(.2s);
|
||||
border-width: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
|
||||
background-color: @toolbar-combobutton-hovered-unhoveredsection-background-color;
|
||||
padding: 2px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
|
||||
background-color: @pressed-background-color;
|
||||
.active-gradient;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
|
||||
background-color: @pressed-background-color;
|
||||
.active-gradient;
|
||||
}
|
||||
|
||||
/* Avoid double border between button and arrow */
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton,
|
||||
.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
|
||||
border-left-width: 0;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
|
||||
padding-left: 2px; /* since there's no left border, don't reduce from 2px --> 1px */
|
||||
}
|
||||
|
||||
/* toggle button checked status */
|
||||
.claro .dijitToolbar .dijitToggleButtonChecked .dijitButtonNode {
|
||||
margin: 0; /* remove margin and add a border */
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
background-image: none;
|
||||
border-color: @selected-border-color;
|
||||
background-color: @toolbar-button-checked-background-color;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.claro .dijitToolbarSeparator {
|
||||
/* separator icon in the editor sprite */
|
||||
background: url(@image-editor-icons-enabled);
|
||||
}
|
||||
|
||||
/* Toolbar inside of disabled Editor */
|
||||
.claro .dijitDisabled .dijitToolbar {
|
||||
background:none;
|
||||
background-color:@disabled-background-color;
|
||||
border-bottom: 1px solid @disabled-border-color;
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboBoxDisabled .dijitArrowButtonInner {
|
||||
background-position:0 50%;
|
||||
}
|
||||
|
29
api/js/webodf/collab/dijit/themes/claro/Toolbar_rtl.css
Normal file
@ -0,0 +1,29 @@
|
||||
/* Toolbar RTL */
|
||||
/* Repeated rules from Toolbar.css to override rule from Button_rtl.css, which is loaded after Toolbar.css */
|
||||
.claro .dijitToolbar .dijitComboButtonRtl .dijitButtonNode {
|
||||
border-width: 0;
|
||||
padding: 2px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonRtlHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonRtlActive .dijitButtonNode {
|
||||
border-width: 1px;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonRtl .dijitStretch {
|
||||
/* no rounded border on side adjacent to arrow */
|
||||
-moz-border-radius: 0 2px 2px 0;
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonRtl .dijitArrowButton {
|
||||
/* no rounded border on side adjacent to button */
|
||||
-moz-border-radius: 2px 0 0 2px;
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonRtlHover .dijitArrowButton,
|
||||
.claro .dijitToolbar .dijitComboButtonRtlActive .dijitArrowButton {
|
||||
/* border between button and arrow */
|
||||
border-left-width: 1px;
|
||||
border-right-width: 0;
|
||||
padding-left: 1px;
|
||||
padding-right: 2px;
|
||||
}
|
32
api/js/webodf/collab/dijit/themes/claro/Toolbar_rtl.less
Normal file
@ -0,0 +1,32 @@
|
||||
/* Toolbar RTL */
|
||||
|
||||
@import "variables";
|
||||
|
||||
/* Repeated rules from Toolbar.css to override rule from Button_rtl.css, which is loaded after Toolbar.css */
|
||||
.claro .dijitToolbar .dijitComboButtonRtl .dijitButtonNode {
|
||||
border-width: 0;
|
||||
padding: 2px;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonRtlHover .dijitButtonNode,
|
||||
.claro .dijitToolbar .dijitComboButtonRtlActive .dijitButtonNode {
|
||||
border-width: 1px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboButtonRtl .dijitStretch {
|
||||
/* no rounded border on side adjacent to arrow */
|
||||
.border-radius(0 2px 2px 0);
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboButtonRtl .dijitArrowButton {
|
||||
/* no rounded border on side adjacent to button */
|
||||
.border-radius(2px 0 0 2px);
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboButtonRtlHover .dijitArrowButton,
|
||||
.claro .dijitToolbar .dijitComboButtonRtlActive .dijitArrowButton {
|
||||
/* border between button and arrow */
|
||||
border-left-width: 1px;
|
||||
border-right-width: 0;
|
||||
padding-left: 1px;
|
||||
padding-right: 2px;
|
||||
}
|
143
api/js/webodf/collab/dijit/themes/claro/Tree.css
Normal file
@ -0,0 +1,143 @@
|
||||
/* Tree
|
||||
*
|
||||
* Styling Tree mostly means styling the TreeRow (dijitTreeRow)
|
||||
* There are 4 basic states to style:
|
||||
*
|
||||
* Tree Row:
|
||||
* 1. tree row (default styling):
|
||||
* .dijitTreeRow - styles for each row of the tree
|
||||
*
|
||||
* 2. hovered tree row (mouse hover on a tree row)
|
||||
* .dijitTreeRowHover - styles when mouse over on one row
|
||||
*
|
||||
* 3. active tree row (mouse down on a tree row)
|
||||
* .dijitTreeRowActive - styles when mouse down on one row
|
||||
*
|
||||
* 4. selected tree row
|
||||
* dijitTreeRowSelected - style when the row has been selected
|
||||
*
|
||||
* Tree Expando:
|
||||
* dijitTreeExpando - the expando at the left of the text of each tree row
|
||||
*
|
||||
* Drag and Drop on TreeNodes: (insert line on dijitTreeContent node so it'll aligned w/ target element)
|
||||
* .dijitTreeNode .dojoDndItemBefore/.dojoDndItemAfter - use border style simulate a separate line
|
||||
*/
|
||||
.claro .dijitTreeNode {
|
||||
zoom: 1;
|
||||
/* force layout on IE (TODO: may not be needed anymore) */
|
||||
}
|
||||
.claro .dijitTreeIsRoot {
|
||||
background-image: none;
|
||||
}
|
||||
/* Styling for basic tree node (unhovered, unselected)
|
||||
* Also use this styling when dropping between items on the tree (in other words, don't
|
||||
* use hover effect)
|
||||
*/
|
||||
.claro .dijitTreeRow,
|
||||
.claro .dijitTreeNode .dojoDndItemBefore,
|
||||
.claro .dijitTreeNode .dojoDndItemAfter {
|
||||
/* so insert line shows up on IE when dropping after a target element */
|
||||
padding: 4px 0 2px 0;
|
||||
background-color: none;
|
||||
background-color: transparent;
|
||||
background-color: rgba(171, 214, 255, 0);
|
||||
background-position: 0 0;
|
||||
background-repeat: repeat-x;
|
||||
border: solid 0 transparent;
|
||||
color: #000;
|
||||
-webkit-transition-property: background-color, border-color;
|
||||
-moz-transition-property: background-color, border-color;
|
||||
transition-property: background-color, border-color;
|
||||
-webkit-transition-duration: 0.25s;
|
||||
-moz-transition-duration: 0.25s;
|
||||
transition-duration: 0.25s;
|
||||
-webkit-transition-timing-function: ease-out;
|
||||
-moz-transition-timing-function: ease-out;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
.claro .dijitTreeRowSelected {
|
||||
background-color: #cfe5fa;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 3px 0 1px;
|
||||
border-color: #759dc0;
|
||||
border-width: 1px 0;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitTreeRowHover {
|
||||
background-color: #abd6ff;
|
||||
background-image: url("images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 3px 0 1px;
|
||||
border-color: #759dc0;
|
||||
border-width: 1px 0;
|
||||
color: #000;
|
||||
-webkit-transition-duration: 0.25s;
|
||||
-moz-transition-duration: 0.25s;
|
||||
transition-duration: 0.25s;
|
||||
}
|
||||
.claro .dijitTreeRowActive {
|
||||
background-color: #7dbdfa;
|
||||
background-image: url("images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 3px 0 1px;
|
||||
border-color: #759dc0;
|
||||
border-width: 1px 0;
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitTreeRowFocused {
|
||||
background-repeat: repeat;
|
||||
}
|
||||
/* expando (open/closed) icon */
|
||||
.claro .dijitTreeExpando {
|
||||
background-image: url("images/treeExpandImages.png");
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -35px 0;
|
||||
/* for dijitTreeExpandoOpened */
|
||||
}
|
||||
.dj_ie6 .claro .dijitTreeExpando {
|
||||
background-image: url("images/treeExpandImages8bit.png");
|
||||
}
|
||||
.claro .dijitTreeRowHover .dijitTreeExpandoOpened {
|
||||
background-position: -53px 0;
|
||||
}
|
||||
.claro .dijitTreeExpandoClosed {
|
||||
background-position: 1px 0;
|
||||
}
|
||||
.claro .dijitTreeRowHover .dijitTreeExpandoClosed {
|
||||
background-position: -17px 0;
|
||||
}
|
||||
.claro .dijitTreeExpandoLeaf,
|
||||
.dj_ie6 .claro .dijitTreeExpandoLeaf {
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitTreeExpandoLoading {
|
||||
background-image: url("images/loadingAnimation.gif");
|
||||
}
|
||||
/* Drag and Drop on TreeNodes
|
||||
* Put insert line on dijitTreeContent node so it's aligned w/
|
||||
* (ie, indented equally with) target element, even
|
||||
* though dijitTreeRowNode is the actual "drag object"
|
||||
*/
|
||||
.claro .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
|
||||
border-top: 2px solid #759dc0;
|
||||
}
|
||||
.claro .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
|
||||
border-bottom: 2px solid #759dc0;
|
||||
}
|
127
api/js/webodf/collab/dijit/themes/claro/Tree.less
Normal file
@ -0,0 +1,127 @@
|
||||
/* Tree
|
||||
*
|
||||
* Styling Tree mostly means styling the TreeRow (dijitTreeRow)
|
||||
* There are 4 basic states to style:
|
||||
*
|
||||
* Tree Row:
|
||||
* 1. tree row (default styling):
|
||||
* .dijitTreeRow - styles for each row of the tree
|
||||
*
|
||||
* 2. hovered tree row (mouse hover on a tree row)
|
||||
* .dijitTreeRowHover - styles when mouse over on one row
|
||||
*
|
||||
* 3. active tree row (mouse down on a tree row)
|
||||
* .dijitTreeRowActive - styles when mouse down on one row
|
||||
*
|
||||
* 4. selected tree row
|
||||
* dijitTreeRowSelected - style when the row has been selected
|
||||
*
|
||||
* Tree Expando:
|
||||
* dijitTreeExpando - the expando at the left of the text of each tree row
|
||||
*
|
||||
* Drag and Drop on TreeNodes: (insert line on dijitTreeContent node so it'll aligned w/ target element)
|
||||
* .dijitTreeNode .dojoDndItemBefore/.dojoDndItemAfter - use border style simulate a separate line
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
.claro .dijitTreeNode {
|
||||
zoom: 1; /* force layout on IE (TODO: may not be needed anymore) */
|
||||
}
|
||||
.claro .dijitTreeIsRoot {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
/* Styling for basic tree node (unhovered, unselected)
|
||||
* Also use this styling when dropping between items on the tree (in other words, don't
|
||||
* use hover effect)
|
||||
*/
|
||||
.claro .dijitTreeRow,
|
||||
.claro .dijitTreeNode .dojoDndItemBefore,
|
||||
.claro .dijitTreeNode .dojoDndItemAfter {
|
||||
/* so insert line shows up on IE when dropping after a target element */
|
||||
padding: 4px 0 2px 0;
|
||||
|
||||
background-color: none; // IE6 doesn't understand rgba() or transparent below
|
||||
background-color: transparent; // IE8 doesn't understand rgba() below
|
||||
background-color: rgba(171,214,255,0); // rgba() instead of transparent to prevent flash on hover fade-in
|
||||
background-position:0 0;
|
||||
background-repeat:repeat-x;
|
||||
|
||||
border: solid 0 transparent;
|
||||
|
||||
color: @text-color;
|
||||
|
||||
.transition-property(background-color, border-color);
|
||||
.transition-duration(.25s);
|
||||
.transition-timing-function(ease-out);
|
||||
}
|
||||
|
||||
.claro .dijitTreeRowSelected {
|
||||
background-color: @selected-background-color;
|
||||
.standard-gradient;
|
||||
padding: 3px 0 1px;
|
||||
border-color: @selected-border-color;
|
||||
border-width: 1px 0;
|
||||
color: @selected-text-color;
|
||||
}
|
||||
.claro .dijitTreeRowHover {
|
||||
background-color: @hovered-background-color;
|
||||
.standard-gradient;
|
||||
padding: 3px 0 1px;
|
||||
border-color: @hovered-border-color;
|
||||
border-width: 1px 0;
|
||||
color: @hovered-text-color;
|
||||
.transition-duration(.25s);
|
||||
}
|
||||
.claro .dijitTreeRowActive {
|
||||
background-color:@pressed-background-color;
|
||||
.active-gradient;
|
||||
padding: 3px 0 1px;
|
||||
border-color: @pressed-border-color;
|
||||
border-width: 1px 0;
|
||||
color: @selected-text-color;
|
||||
}
|
||||
.claro .dijitTreeRowFocused {
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
/* expando (open/closed) icon */
|
||||
|
||||
.claro .dijitTreeExpando {
|
||||
background-image: url(@image-tree-expand);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -35px 0; /* for dijitTreeExpandoOpened */
|
||||
}
|
||||
.dj_ie6 .claro .dijitTreeExpando {
|
||||
background-image: url(@image-tree-expand-ie6);
|
||||
}
|
||||
.claro .dijitTreeRowHover .dijitTreeExpandoOpened {
|
||||
background-position: -53px 0;
|
||||
}
|
||||
.claro .dijitTreeExpandoClosed {
|
||||
background-position: 1px 0;
|
||||
}
|
||||
.claro .dijitTreeRowHover .dijitTreeExpandoClosed {
|
||||
background-position: -17px 0;
|
||||
}
|
||||
.claro .dijitTreeExpandoLeaf,
|
||||
.dj_ie6 .claro .dijitTreeExpandoLeaf {
|
||||
background-image:none;
|
||||
}
|
||||
.claro .dijitTreeExpandoLoading {
|
||||
background-image: url(@image-loading-animation);
|
||||
}
|
||||
|
||||
/* Drag and Drop on TreeNodes
|
||||
* Put insert line on dijitTreeContent node so it's aligned w/
|
||||
* (ie, indented equally with) target element, even
|
||||
* though dijitTreeRowNode is the actual "drag object"
|
||||
*/
|
||||
.claro .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
|
||||
border-top: 2px solid @dnd-dropseparator-color; // TODO: normal separator is just 1px, why is this 2px?
|
||||
}
|
||||
.claro .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
|
||||
border-bottom: 2px solid @dnd-dropseparator-color; // TODO: normal separator is just 1px, why is this 2px?
|
||||
}
|
1
api/js/webodf/collab/dijit/themes/claro/claro.css
Normal file
1
api/js/webodf/collab/dijit/themes/claro/claro_rtl.css
Normal file
52
api/js/webodf/collab/dijit/themes/claro/compile.js
Normal file
@ -0,0 +1,52 @@
|
||||
// Script to process all the less files and convert them to CSS files
|
||||
// Run from themes/dijit/claro like:
|
||||
//
|
||||
// $ node compile.js
|
||||
|
||||
var fs = require('fs'), // file system access
|
||||
path = require('path'), // get directory from file name
|
||||
less = require('../../../util/less'); // less processor
|
||||
|
||||
var options = {
|
||||
compress: false,
|
||||
optimization: 1,
|
||||
silent: false
|
||||
};
|
||||
|
||||
var allFiles = [].concat(
|
||||
fs.readdirSync("."),
|
||||
fs.readdirSync("form").map(function(fname){ return "form/"+fname; }),
|
||||
fs.readdirSync("layout").map(function(fname){ return "layout/"+fname; })
|
||||
),
|
||||
lessFiles = allFiles.filter(function(name){ return name && name != "variables.less" && /\.less$/.test(name); });
|
||||
|
||||
lessFiles.forEach(function(fname){
|
||||
console.log("=== " + fname);
|
||||
fs.readFile(fname, 'utf-8', function(e, data){
|
||||
if(e){
|
||||
console.error("lessc: " + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
new(less.Parser)({
|
||||
paths: [path.dirname(fname)],
|
||||
optimization: options.optimization,
|
||||
filename: fname
|
||||
}).parse(data, function(err, tree){
|
||||
if(err){
|
||||
less.writeError(err, options);
|
||||
process.exit(1);
|
||||
}else{
|
||||
try{
|
||||
var css = tree.toCSS({ compress: options.compress }),
|
||||
outputFname = fname.replace('.less', '.css');
|
||||
var fd = fs.openSync(outputFname, "w");
|
||||
fs.writeSync(fd, css, 0, "utf8");
|
||||
}catch(e){
|
||||
less.writeError(e, options);
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
43
api/js/webodf/collab/dijit/themes/claro/document.css
Normal file
@ -0,0 +1,43 @@
|
||||
/* ======= Styling for the document itself (overriding dojo.css) ======== */
|
||||
@import url("../../../dojo/resources/dojo.css");
|
||||
.claro {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: .688em;
|
||||
color: #131313;
|
||||
}
|
||||
/* Headings */
|
||||
.claro h1 {
|
||||
font-size: 1.545em;
|
||||
margin-bottom: 0.727em;
|
||||
}
|
||||
.claro h2 {
|
||||
font-size: 1.364em;
|
||||
line-height: 1.455em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.60em;
|
||||
font-weight: normal;
|
||||
}
|
||||
.claro h3,
|
||||
.claro h4,
|
||||
.claro h5,
|
||||
.claro h6 {
|
||||
font-size: 1.091em;
|
||||
font-weight: normal;
|
||||
}
|
||||
/* paragraphs, quotes and lists */
|
||||
.claro p {
|
||||
line-height: 1.3em;
|
||||
}
|
||||
/* pre and code */
|
||||
.claro pre,
|
||||
.claro code {
|
||||
font-family: inherit;
|
||||
background-color: #efefef;
|
||||
border: 1px solid #d3d3d3;
|
||||
}
|
||||
/* tables */
|
||||
.claro table.dojoTabular thead,
|
||||
.claro table.dojoTabular tfoot {
|
||||
background-color: #efefef;
|
||||
border: 1px solid #d3d3d3;
|
||||
}
|
45
api/js/webodf/collab/dijit/themes/claro/document.less
Normal file
@ -0,0 +1,45 @@
|
||||
/* ======= Styling for the document itself (overriding dojo.css) ======== */
|
||||
|
||||
@import "variables";
|
||||
@import url("../../../dojo/resources/dojo.css");
|
||||
|
||||
.claro {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: .688em;
|
||||
color: @document-text-color;
|
||||
}
|
||||
|
||||
/* Headings */
|
||||
.claro h1 {
|
||||
font-size: 1.545em;
|
||||
margin-bottom:0.727em;
|
||||
}
|
||||
.claro h2 {
|
||||
font-size: 1.364em;
|
||||
line-height: 1.455em;
|
||||
margin-top:1em;
|
||||
margin-bottom:0.60em;
|
||||
font-weight: normal;
|
||||
}
|
||||
.claro h3, .claro h4, .claro h5, .claro h6 {
|
||||
font-size:1.091em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* paragraphs, quotes and lists */
|
||||
.claro p {
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
/* pre and code */
|
||||
.claro pre, .claro code {
|
||||
font-family:inherit;
|
||||
background-color: @document-shadedsection-background-color;
|
||||
border: 1px solid @document-border-color;
|
||||
}
|
||||
|
||||
/* tables */
|
||||
.claro table.dojoTabular thead, .claro table.dojoTabular tfoot {
|
||||
background-color: @document-shadedsection-background-color;
|
||||
border: 1px solid @document-border-color;
|
||||
}
|
164
api/js/webodf/collab/dijit/themes/claro/form/Button.css
Normal file
@ -0,0 +1,164 @@
|
||||
/* Button | DropDownButton | ComboButton | ToggleButton
|
||||
*
|
||||
* Styling Buttons mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitButton
|
||||
* .dijitDropDownButton
|
||||
* .dijitComboButton
|
||||
* .dijitButtonNode - common button/arrow wrapper shared across all three button types
|
||||
*
|
||||
* 2. Button text
|
||||
* .dijitButtonText
|
||||
*
|
||||
* 3. Arrows - only for DropDownButton and ComboButton
|
||||
* There are total four directions arrows - down, left, right, up:
|
||||
* .dijitArrowButtonInner - down arrow by default
|
||||
* .dijitLeftArrowButton .dijitArrowButtonInner - left arrow
|
||||
* .dijitRightArrowButton .dijitArrowButtonInner - right arrow
|
||||
* .dijitUpArrowButton .dijitArrowButtonInner - up arrow
|
||||
*
|
||||
* 4. States - Hover, Active, Disabled, e.g.
|
||||
* .dijitButtonHover .dijitButtonNode
|
||||
* .dijitButtonActive .dijitButtonNode
|
||||
* .dijitButtonDisabled .dijitButtonNode
|
||||
*
|
||||
* .dijitDisabled .dijitArrowButtonInner - disabled arrow states
|
||||
*/
|
||||
.claro .dijitButtonNode {
|
||||
/* rules for dijit.form.*Button widgets and arrow nodes on ComboBox, Spinner etc. */
|
||||
-webkit-transition-property: background-color;
|
||||
-moz-transition-property: background-color;
|
||||
transition-property: background-color;
|
||||
-webkit-transition-duration: 0.3s;
|
||||
-moz-transition-duration: 0.3s;
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
.claro .dijitButton .dijitButtonNode,
|
||||
.claro .dijitDropDownButton .dijitButtonNode,
|
||||
.claro .dijitComboButton .dijitButtonNode,
|
||||
.claro .dijitToggleButton .dijitButtonNode {
|
||||
/* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
|
||||
border: 1px solid #759dc0;
|
||||
padding: 2px 4px 4px 4px;
|
||||
color: #000;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
|
||||
background-color: #bcd8f4;
|
||||
background-image: url("images/buttonEnabled.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
|
||||
background-image: -webkit-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
|
||||
background-image: -o-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
|
||||
background-image: -ms-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitComboButton .dijitArrowButton {
|
||||
border-left-width: 0;
|
||||
padding: 4px 2px 4px 2px;
|
||||
/* TODO: still needed? */
|
||||
}
|
||||
/*arrow styles for down/up/left/right directions*/
|
||||
.claro .dijitArrowButtonInner {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin: 0 auto;
|
||||
background-image: url("../form/images/buttonArrows.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: -51px 53%;
|
||||
}
|
||||
.claro .dijitLeftArrowButton .dijitArrowButtonInner {
|
||||
background-position: -77px 53%;
|
||||
}
|
||||
.claro .dijitRightArrowButton .dijitArrowButtonInner {
|
||||
background-position: -26px 53%;
|
||||
}
|
||||
.claro .dijitUpArrowButton .dijitArrowButtonInner {
|
||||
background-position: 0 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitArrowButtonInner {
|
||||
background-position: -151px 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitLeftArrowButton .dijitArrowButtonInner {
|
||||
background-position: -177px 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitRightArrowButton .dijitArrowButtonInner {
|
||||
background-position: -126px 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner {
|
||||
background-position: -100px 53%;
|
||||
}
|
||||
.claro .dijitButtonText {
|
||||
padding: 0 0.3em;
|
||||
text-align: center;
|
||||
}
|
||||
/* hover status */
|
||||
.claro .dijitButtonHover .dijitButtonNode,
|
||||
.claro .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.claro .dijitComboButton .dijitButtonNodeHover,
|
||||
.claro .dijitComboButton .dijitDownArrowButtonHover,
|
||||
.claro .dijitToggleButtonHover .dijitButtonNode {
|
||||
background-color: #86bdf2;
|
||||
color: #000;
|
||||
-webkit-transition-duration: 0.2s;
|
||||
-moz-transition-duration: 0.2s;
|
||||
transition-duration: 0.2s;
|
||||
}
|
||||
/* active, checked status */
|
||||
.claro .dijitButtonActive .dijitButtonNode,
|
||||
.claro .dijitDropDownButtonActive .dijitButtonNode,
|
||||
.claro .dijitComboButtonActive .dijitButtonNode,
|
||||
.claro .dijitToggleButtonActive .dijitButtonNode,
|
||||
.claro .dijitToggleButtonChecked .dijitButtonNode {
|
||||
background-color: #86bdf2;
|
||||
-webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-transition-duration: 0.1s;
|
||||
-moz-transition-duration: 0.1s;
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
/* disabled status */
|
||||
.claro .dijitButtonDisabled,
|
||||
.claro .dijitDropDownButtonDisabled,
|
||||
.claro .dijitComboButtonDisabled,
|
||||
.claro .dijitToggleButtonDisabled {
|
||||
background-image: none;
|
||||
outline: none;
|
||||
}
|
||||
.claro .dijitButtonDisabled .dijitButtonNode,
|
||||
.claro .dijitDropDownButtonDisabled .dijitButtonNode,
|
||||
.claro .dijitComboButtonDisabled .dijitButtonNode,
|
||||
.claro .dijitToggleButtonDisabled .dijitButtonNode {
|
||||
background-color: #efefef;
|
||||
border: solid 1px #d3d3d3;
|
||||
color: #818181;
|
||||
-webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
-moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
||||
background-image: url("images/buttonDisabled.png");
|
||||
background-image: -moz-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
|
||||
background-image: -webkit-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
|
||||
background-image: -o-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
|
||||
background-image: -ms-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitComboButtonDisabled .dijitArrowButton {
|
||||
border-left-width: 0;
|
||||
}
|
||||
/* for ComboButton */
|
||||
.claro table.dijitComboButton {
|
||||
border-collapse: separate;
|
||||
/* override dijit.css so that ComboBox rounded corners work */
|
||||
}
|
||||
.claro .dijitComboButton .dijitStretch {
|
||||
-moz-border-radius: 4px 0 0 4px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
.claro .dijitComboButton .dijitArrowButton {
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
164
api/js/webodf/collab/dijit/themes/claro/form/Button.less
Normal file
@ -0,0 +1,164 @@
|
||||
/* Button | DropDownButton | ComboButton | ToggleButton
|
||||
*
|
||||
* Styling Buttons mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitButton
|
||||
* .dijitDropDownButton
|
||||
* .dijitComboButton
|
||||
* .dijitButtonNode - common button/arrow wrapper shared across all three button types
|
||||
*
|
||||
* 2. Button text
|
||||
* .dijitButtonText
|
||||
*
|
||||
* 3. Arrows - only for DropDownButton and ComboButton
|
||||
* There are total four directions arrows - down, left, right, up:
|
||||
* .dijitArrowButtonInner - down arrow by default
|
||||
* .dijitLeftArrowButton .dijitArrowButtonInner - left arrow
|
||||
* .dijitRightArrowButton .dijitArrowButtonInner - right arrow
|
||||
* .dijitUpArrowButton .dijitArrowButtonInner - up arrow
|
||||
*
|
||||
* 4. States - Hover, Active, Disabled, e.g.
|
||||
* .dijitButtonHover .dijitButtonNode
|
||||
* .dijitButtonActive .dijitButtonNode
|
||||
* .dijitButtonDisabled .dijitButtonNode
|
||||
*
|
||||
* .dijitDisabled .dijitArrowButtonInner - disabled arrow states
|
||||
*/
|
||||
|
||||
@import "../variables";
|
||||
|
||||
.claro .dijitButtonNode {
|
||||
/* rules for dijit.form.*Button widgets and arrow nodes on ComboBox, Spinner etc. */
|
||||
.transition-property(background-color);
|
||||
.transition-duration(.3s);
|
||||
}
|
||||
|
||||
.claro .dijitButton .dijitButtonNode,
|
||||
.claro .dijitDropDownButton .dijitButtonNode,
|
||||
.claro .dijitComboButton .dijitButtonNode,
|
||||
.claro .dijitToggleButton .dijitButtonNode {
|
||||
/* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
|
||||
border: 1px solid @button-border-color;
|
||||
padding: 2px 4px 4px 4px;
|
||||
color: @text-color;
|
||||
.border-radius(@button-border-radius);
|
||||
.box-shadow(0 1px 1px rgba(0,0,0,0.15));
|
||||
|
||||
background-color: desaturate(darken(@button-background-color, 10), 20);
|
||||
|
||||
// Alpha transparency layer to add gradient to above background color.
|
||||
// Use CSS gradient with fallback to image for IE.
|
||||
background-image: url("images/buttonEnabled.png");
|
||||
background-repeat: repeat-x;
|
||||
.alpha-white-gradient(1, 0px, 0, 3px, 0.75, 100%);
|
||||
_background-image: none; // IE6 can't handle background-color and background-image at once.
|
||||
}
|
||||
|
||||
|
||||
.claro .dijitComboButton .dijitArrowButton {
|
||||
border-left-width: 0;
|
||||
padding: 4px 2px 4px 2px; /* TODO: still needed? */
|
||||
}
|
||||
|
||||
/*arrow styles for down/up/left/right directions*/
|
||||
.claro .dijitArrowButtonInner {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin: 0 auto;
|
||||
background-image:url("../@{image-form-button-arrows}");
|
||||
background-repeat:no-repeat;
|
||||
background-position:-51px 53%;
|
||||
}
|
||||
.claro .dijitLeftArrowButton .dijitArrowButtonInner {
|
||||
background-position: -77px 53%;
|
||||
}
|
||||
.claro .dijitRightArrowButton .dijitArrowButtonInner {
|
||||
background-position: -26px 53%;
|
||||
}
|
||||
.claro .dijitUpArrowButton .dijitArrowButtonInner {
|
||||
background-position: 0 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitArrowButtonInner {
|
||||
background-position: -151px 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitLeftArrowButton .dijitArrowButtonInner {
|
||||
background-position: -177px 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitRightArrowButton .dijitArrowButtonInner {
|
||||
background-position: -126px 53%;
|
||||
}
|
||||
.claro .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner {
|
||||
background-position: -100px 53%;
|
||||
}
|
||||
|
||||
.claro .dijitButtonText {
|
||||
padding: 0 0.3em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* hover status */
|
||||
.claro .dijitButtonHover .dijitButtonNode,
|
||||
.claro .dijitDropDownButtonHover .dijitButtonNode,
|
||||
.claro .dijitComboButton .dijitButtonNodeHover,
|
||||
.claro .dijitComboButton .dijitDownArrowButtonHover,
|
||||
.claro .dijitToggleButtonHover .dijitButtonNode {
|
||||
background-color: desaturate(darken(@button-hovered-background-color, 10), 20);
|
||||
color:@text-color;
|
||||
.transition-duration(.2s);
|
||||
}
|
||||
|
||||
/* active, checked status */
|
||||
.claro .dijitButtonActive .dijitButtonNode,
|
||||
.claro .dijitDropDownButtonActive .dijitButtonNode,
|
||||
.claro .dijitComboButtonActive .dijitButtonNode,
|
||||
.claro .dijitToggleButtonActive .dijitButtonNode,
|
||||
.claro .dijitToggleButtonChecked .dijitButtonNode {
|
||||
background-color: desaturate(darken(@button-pressed-background-color, 10), 20);
|
||||
.box-shadow(inset 0px 1px 1px rgba(0, 0, 0, 0.2));
|
||||
.transition-duration(.1s);
|
||||
}
|
||||
|
||||
/* disabled status */
|
||||
.claro .dijitButtonDisabled,
|
||||
.claro .dijitDropDownButtonDisabled,
|
||||
.claro .dijitComboButtonDisabled,
|
||||
.claro .dijitToggleButtonDisabled {
|
||||
background-image: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.claro .dijitButtonDisabled .dijitButtonNode,
|
||||
.claro .dijitDropDownButtonDisabled .dijitButtonNode,
|
||||
.claro .dijitComboButtonDisabled .dijitButtonNode,
|
||||
.claro .dijitToggleButtonDisabled .dijitButtonNode {
|
||||
background-color: @disabled-background-color;
|
||||
border: solid 1px @disabled-border-color;
|
||||
color: @disabled-text-color;
|
||||
.box-shadow(0 0 0 rgba(0,0,0,0));
|
||||
|
||||
// Change the gradient from light to dark.
|
||||
// Again using CSS gradient with fallback to image for IE.
|
||||
background-image: url("images/buttonDisabled.png");
|
||||
.alpha-white-gradient(1, 0%, 0, 40%);
|
||||
_background-image: none; // IE6 can't handle background-color and background-image at once.
|
||||
}
|
||||
|
||||
.claro .dijitComboButtonDisabled .dijitArrowButton{
|
||||
border-left-width: 0;
|
||||
}
|
||||
/* for ComboButton */
|
||||
.claro table.dijitComboButton {
|
||||
border-collapse: separate; /* override dijit.css so that ComboBox rounded corners work */
|
||||
}
|
||||
|
||||
.claro .dijitComboButton .dijitStretch {
|
||||
.border-radius(@button-border-radius 0 0 @button-border-radius);
|
||||
}
|
||||
.claro .dijitComboButton .dijitArrowButton {
|
||||
.border-radius(0 @button-border-radius @button-border-radius 0);
|
||||
}
|
13
api/js/webodf/collab/dijit/themes/claro/form/Button_rtl.css
Normal file
@ -0,0 +1,13 @@
|
||||
/* Combo Button */
|
||||
.claro .dijitComboButtonRtl .dijitStretch {
|
||||
-moz-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
.claro .dijitComboButtonRtl .dijitArrowButton {
|
||||
-moz-border-radius: 4px 0 0 4px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
padding: 3px 0 4px;
|
||||
border-left-width: 1px;
|
||||
border-right-width: 0;
|
||||
}
|
||||
/* End Combo Button */
|
16
api/js/webodf/collab/dijit/themes/claro/form/Button_rtl.less
Normal file
@ -0,0 +1,16 @@
|
||||
@import "../variables";
|
||||
|
||||
/* Combo Button */
|
||||
|
||||
.claro .dijitComboButtonRtl .dijitStretch {
|
||||
.border-radius(0 @button-border-radius @button-border-radius 0);
|
||||
}
|
||||
|
||||
.claro .dijitComboButtonRtl .dijitArrowButton {
|
||||
.border-radius(@button-border-radius 0 0 @button-border-radius);
|
||||
padding:3px 0 4px;
|
||||
border-left-width: 1px;
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
/* End Combo Button */
|
67
api/js/webodf/collab/dijit/themes/claro/form/Checkbox.css
Normal file
@ -0,0 +1,67 @@
|
||||
/* CheckBox
|
||||
*
|
||||
* Styling CheckBox mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitCheckBox|.dijitCheckBoxIcon - for border, padding, width|height and background image
|
||||
*
|
||||
* 2. CheckBox within ToggleButton
|
||||
* .dijitToggleButton|.dijitToggleButtonChecked .* - for background image
|
||||
*
|
||||
* 3. Checked state
|
||||
* .dijitCheckBoxChecked - for checked background-color|image
|
||||
* .dijitToggleButtonChecked - for border, background-color|image, display and width|height
|
||||
*
|
||||
* 4. Hover state
|
||||
* .dijitCheckBoxHover|.dijitCheckBoxCheckedHover - for background image
|
||||
*
|
||||
* 5. Disabled state
|
||||
* .dijitCheckBoxDisabled|.dijitCheckBoxCheckedDisabled - for background image
|
||||
*/
|
||||
.claro .dijitToggleButton .dijitCheckBoxIcon {
|
||||
background-image: url("../images/checkmarkNoBorder.png");
|
||||
}
|
||||
.dj_ie6 .claro .dijitToggleButton .dijitCheckBoxIcon {
|
||||
background-image: url("../images/checkmarkNoBorder.gif");
|
||||
}
|
||||
.claro .dijitCheckBox,
|
||||
.claro .dijitCheckBoxIcon {
|
||||
background-image: url("../form/images/checkboxRadioButtonStates.png");
|
||||
/* checkbox sprite image */
|
||||
background-repeat: no-repeat;
|
||||
width: 15px;
|
||||
height: 16px;
|
||||
margin: 0 2px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
.dj_ie6 .claro .dijitCheckBox,
|
||||
.dj_ie6 .claro .dijitCheckBoxIcon {
|
||||
background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
|
||||
/* checkbox sprite image */
|
||||
}
|
||||
.claro .dijitCheckBox,
|
||||
.claro .dijitToggleButton .dijitCheckBoxIcon {
|
||||
/* unchecked */
|
||||
background-position: -15px;
|
||||
}
|
||||
.claro .dijitCheckBoxChecked,
|
||||
.claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
|
||||
/* checked */
|
||||
background-position: 0;
|
||||
}
|
||||
.claro .dijitCheckBoxDisabled {
|
||||
/* disabled */
|
||||
background-position: -75px;
|
||||
}
|
||||
.claro .dijitCheckBoxCheckedDisabled {
|
||||
/* disabled but checked */
|
||||
background-position: -60px;
|
||||
}
|
||||
.claro .dijitCheckBoxHover {
|
||||
/* hovering over an unchecked enabled checkbox */
|
||||
background-position: -45px;
|
||||
}
|
||||
.claro .dijitCheckBoxCheckedHover {
|
||||
/* hovering over an checked enabled checkbox */
|
||||
background-position: -30px;
|
||||
}
|
79
api/js/webodf/collab/dijit/themes/claro/form/Checkbox.less
Normal file
@ -0,0 +1,79 @@
|
||||
/* CheckBox
|
||||
*
|
||||
* Styling CheckBox mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitCheckBox|.dijitCheckBoxIcon - for border, padding, width|height and background image
|
||||
*
|
||||
* 2. CheckBox within ToggleButton
|
||||
* .dijitToggleButton|.dijitToggleButtonChecked .* - for background image
|
||||
*
|
||||
* 3. Checked state
|
||||
* .dijitCheckBoxChecked - for checked background-color|image
|
||||
* .dijitToggleButtonChecked - for border, background-color|image, display and width|height
|
||||
*
|
||||
* 4. Hover state
|
||||
* .dijitCheckBoxHover|.dijitCheckBoxCheckedHover - for background image
|
||||
*
|
||||
* 5. Disabled state
|
||||
* .dijitCheckBoxDisabled|.dijitCheckBoxCheckedDisabled - for background image
|
||||
*/
|
||||
|
||||
@import "../variables";
|
||||
|
||||
.claro .dijitToggleButton .dijitCheckBoxIcon {
|
||||
background-image: url("../@{image-checkmark}");
|
||||
}
|
||||
|
||||
.dj_ie6 .claro .dijitToggleButton .dijitCheckBoxIcon {
|
||||
background-image: url("../@{image-checkmark-ie6}");
|
||||
}
|
||||
|
||||
.claro .dijitCheckBox,
|
||||
.claro .dijitCheckBoxIcon /* inside a toggle button */ {
|
||||
background-image: url("../@{image-form-checkbox-and-radios}"); /* checkbox sprite image */
|
||||
background-repeat: no-repeat;
|
||||
width: 15px;
|
||||
height: 16px;
|
||||
margin: 0 2px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dj_ie6 .claro .dijitCheckBox,
|
||||
.dj_ie6 .claro .dijitCheckBoxIcon /* inside a toggle button */ {
|
||||
background-image: url("../@{image-form-checkbox-and-radios-ie6}"); /* checkbox sprite image */
|
||||
}
|
||||
|
||||
.claro .dijitCheckBox,
|
||||
.claro .dijitToggleButton .dijitCheckBoxIcon {
|
||||
/* unchecked */
|
||||
background-position: -15px;
|
||||
}
|
||||
|
||||
.claro .dijitCheckBoxChecked,
|
||||
.claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
|
||||
/* checked */
|
||||
background-position: -0;
|
||||
}
|
||||
|
||||
.claro .dijitCheckBoxDisabled {
|
||||
/* disabled */
|
||||
background-position: -75px;
|
||||
}
|
||||
|
||||
.claro .dijitCheckBoxCheckedDisabled {
|
||||
/* disabled but checked */
|
||||
background-position: -60px;
|
||||
}
|
||||
|
||||
.claro .dijitCheckBoxHover {
|
||||
/* hovering over an unchecked enabled checkbox */
|
||||
background-position: -45px;
|
||||
}
|
||||
|
||||
.claro .dijitCheckBoxCheckedHover {
|
||||
/* hovering over an checked enabled checkbox */
|
||||
background-position: -30px;
|
||||
}
|
||||
|
||||
|
220
api/js/webodf/collab/dijit/themes/claro/form/Common.css
Normal file
@ -0,0 +1,220 @@
|
||||
/* claro/form/Common.css */
|
||||
/*========================= common css =========================*/
|
||||
/* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
|
||||
.claro .dijitTextBox,
|
||||
.claro .dijitInputInner {
|
||||
color: #000;
|
||||
}
|
||||
.claro .dijitValidationTextBoxError .dijitValidationContainer {
|
||||
background-color: #d46464;
|
||||
background-image: url("../form/images/error.png");
|
||||
background-position: top center;
|
||||
border: solid #d46464 0;
|
||||
width: 9px;
|
||||
}
|
||||
.claro .dijitTextBoxError .dijitValidationContainer {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
.claro .dijitValidationTextBoxError .dijitValidationIcon {
|
||||
width: 0;
|
||||
background-color: transparent !important;
|
||||
/* so the INPUT doesn't obscure the border in rtl+a11y */
|
||||
}
|
||||
/* Padding for the input area of TextBox based widgets, and corresponding padding for the
|
||||
* down arrow button and the placeholder. placeholder is explicitly listed because
|
||||
* dijitPlaceHolder is absolutely positioned, so padding set on dijitInputField
|
||||
* won't affect it
|
||||
*/
|
||||
.claro .dijitTextArea,
|
||||
.claro .dijitInputField .dijitPlaceHolder {
|
||||
padding: 2px;
|
||||
}
|
||||
.claro .dijitSelect .dijitInputField,
|
||||
.claro .dijitTextBox .dijitInputField {
|
||||
padding: 1px 2px;
|
||||
}
|
||||
.dj_gecko .claro .dijitTextBox .dijitInputInner,
|
||||
.dj_webkit .claro .dijitTextBox .dijitInputInner {
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitSelect,
|
||||
.claro .dijitSelect .dijitButtonContents,
|
||||
.claro .dijitTextBox,
|
||||
.claro .dijitTextBox .dijitButtonNode {
|
||||
/* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
|
||||
border-color: #b5bcc7;
|
||||
-webkit-transition-property: background-color, border;
|
||||
-moz-transition-property: background-color, border;
|
||||
transition-property: background-color, border;
|
||||
-webkit-transition-duration: 0.35s;
|
||||
-moz-transition-duration: 0.35s;
|
||||
transition-duration: 0.35s;
|
||||
}
|
||||
.claro .dijitSelect,
|
||||
.claro .dijitTextBox {
|
||||
background-color: #fff;
|
||||
}
|
||||
/* hover */
|
||||
.claro .dijitSelectHover,
|
||||
.claro .dijitSelectHover .dijitButtonContents,
|
||||
.claro .dijitTextBoxHover,
|
||||
.claro .dijitTextBoxHover .dijitButtonNode {
|
||||
border-color: #759dc0;
|
||||
-webkit-transition-duration: 0.25s;
|
||||
-moz-transition-duration: 0.25s;
|
||||
transition-duration: 0.25s;
|
||||
}
|
||||
.claro .dijitTextBoxHover {
|
||||
background-color: #e5f2fe;
|
||||
background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -ms-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
}
|
||||
/* error state */
|
||||
.claro .dijitSelectError,
|
||||
.claro .dijitSelectError .dijitButtonContents,
|
||||
.claro .dijitTextBoxError,
|
||||
.claro .dijitTextBoxError .dijitButtonNode {
|
||||
border-color: #d46464;
|
||||
}
|
||||
/* focused state */
|
||||
.claro .dijitSelectFocused,
|
||||
.claro .dijitSelectFocused .dijitButtonContents,
|
||||
.claro .dijitTextBoxFocused,
|
||||
.claro .dijitTextBoxFocused .dijitButtonNode {
|
||||
border-color: #759dc0;
|
||||
-webkit-transition-duration: 0.1s;
|
||||
-moz-transition-duration: 0.1s;
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
.claro .dijitTextBoxFocused {
|
||||
background-color: #fff;
|
||||
background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -ms-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
}
|
||||
.claro .dijitTextBoxFocused .dijitInputContainer {
|
||||
background: #fff;
|
||||
}
|
||||
.claro .dijitSelectErrorFocused,
|
||||
.claro .dijitSelectErrorFocused .dijitButtonContents,
|
||||
.claro .dijitTextBoxErrorFocused,
|
||||
.claro .dijitTextBoxErrorFocused .dijitButtonNode {
|
||||
border-color: #ce5050;
|
||||
}
|
||||
/* disabled state */
|
||||
.claro .dijitSelectDisabled,
|
||||
.claro .dijitSelectDisabled .dijitButtonContents,
|
||||
.claro .dijitTextBoxDisabled,
|
||||
.claro .dijitTextBoxDisabled .dijitButtonNode {
|
||||
border-color: #d3d3d3;
|
||||
}
|
||||
.claro .dijitSelectDisabled,
|
||||
.claro .dijitTextBoxDisabled,
|
||||
.claro .dijitTextBoxDisabled .dijitInputContainer {
|
||||
background-color: #efefef;
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitSelectDisabled,
|
||||
.claro .dijitTextBoxDisabled,
|
||||
.claro .dijitTextBoxDisabled .dijitInputInner {
|
||||
color: #818181;
|
||||
}
|
||||
.dj_webkit .claro .dijitDisabled input {
|
||||
/* because WebKit lightens disabled input/textarea no matter what color you specify */
|
||||
color: #757575;
|
||||
}
|
||||
.dj_webkit .claro textarea.dijitTextAreaDisabled {
|
||||
/* because WebKit lightens disabled input/textarea no matter what color you specify */
|
||||
color: #1b1b1b;
|
||||
}
|
||||
/*========================= for special widgets =========================*/
|
||||
/* Input boxes with an arrow (for a drop down) */
|
||||
.claro .dijitSelect .dijitArrowButtonInner,
|
||||
.claro .dijitComboBox .dijitArrowButtonInner {
|
||||
background-image: url("../form/images/commonFormArrows.png");
|
||||
background-position: -35px 53%;
|
||||
background-repeat: no-repeat;
|
||||
margin: 0;
|
||||
width: 16px;
|
||||
}
|
||||
.claro .dijitComboBox .dijitArrowButtonInner {
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
|
||||
border: none;
|
||||
}
|
||||
.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
|
||||
border: none;
|
||||
}
|
||||
/* Add 1px vertical padding to the <input> where user types and the validation icon,
|
||||
to match the 1px border on arrow button */
|
||||
.claro .dijitSelectLabel,
|
||||
.claro .dijitTextBox .dijitInputInner,
|
||||
.claro .dijitValidationTextBox .dijitValidationContainer {
|
||||
padding: 1px 0;
|
||||
}
|
||||
.claro .dijitComboBox .dijitButtonNode {
|
||||
background-color: #efefef;
|
||||
background-image: url("../images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
/* Arrow "hover" effect:
|
||||
* The arrow button should change color whenever the mouse is in a position such that clicking it
|
||||
* will toggle the drop down. That's either (1) anywhere over the ComboBox or (2) over the arrow
|
||||
* button, depending on the openOnClick setting for the widget.
|
||||
*/
|
||||
.claro .dijitComboBoxOpenOnClickHover .dijitButtonNode,
|
||||
.claro .dijitComboBox .dijitDownArrowButtonHover {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner,
|
||||
.claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
|
||||
background-position: -70px 53%;
|
||||
}
|
||||
/* Arrow Button change when drop down is open */
|
||||
.claro .dijitComboBox .dijitHasDropDownOpen {
|
||||
background-color: #7dbdfa;
|
||||
background-image: url("../images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
padding: 1px;
|
||||
}
|
||||
.dj_iequirks .claro .dijitComboBox .dijitHasDropDownOpen {
|
||||
padding: 1px 0;
|
||||
}
|
||||
.claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
|
||||
background-position: -70px 53%;
|
||||
border: 0 none;
|
||||
}
|
||||
/* disabled state */
|
||||
.claro div.dijitComboBoxDisabled .dijitArrowButtonInner {
|
||||
/* specific selector set to override background-position setting from Button.js
|
||||
* (.claro .dijitComboBoxDisabled .dijitArrowButtonInner) */
|
||||
background-position: 0 50%;
|
||||
background-color: #efefef;
|
||||
}
|
||||
/*========================= hacks for browsers =========================*/
|
||||
/* it seems the input[type="hidden"] has a height (16px) too... this may cause the widget's height calculate error */
|
||||
.dj_ff3 .claro .dijitInputField input[type="hidden"] {
|
||||
display: none;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
.dj_borderbox .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
|
||||
width: 18px;
|
||||
}
|
||||
.dj_borderbox .claro .dijitComboBoxFocused .dijitHasDropDownOpen .dijitArrowButtonInner {
|
||||
width: 16px;
|
||||
}
|
241
api/js/webodf/collab/dijit/themes/claro/form/Common.less
Normal file
@ -0,0 +1,241 @@
|
||||
/* claro/form/Common.css */
|
||||
|
||||
/*========================= common css =========================*/
|
||||
|
||||
@import "../variables";
|
||||
|
||||
/* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
|
||||
|
||||
.claro .dijitTextBox,
|
||||
.claro .dijitInputInner {
|
||||
// .dijitInputInner selector needed for ValidationTextBox on IE6 because <input> doesn't inherit
|
||||
// the color setting from the ancestor div.dijitTextBox
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.claro .dijitValidationTextBoxError .dijitValidationContainer {
|
||||
background-color: @erroricon-background-color;
|
||||
background-image: url("../@{image-form-error}");
|
||||
background-position: top center;
|
||||
border: solid @erroricon-background-color 0;
|
||||
width: 9px;
|
||||
}
|
||||
|
||||
.claro .dijitTextBoxError .dijitValidationContainer {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.claro .dijitValidationTextBoxError .dijitValidationIcon {
|
||||
width: 0;
|
||||
background-color: transparent !important; /* so the INPUT doesn't obscure the border in rtl+a11y */
|
||||
}
|
||||
|
||||
/* Padding for the input area of TextBox based widgets, and corresponding padding for the
|
||||
* down arrow button and the placeholder. placeholder is explicitly listed because
|
||||
* dijitPlaceHolder is absolutely positioned, so padding set on dijitInputField
|
||||
* won't affect it
|
||||
*/
|
||||
.claro .dijitTextArea,
|
||||
.claro .dijitInputField .dijitPlaceHolder {
|
||||
padding: @textbox-padding;
|
||||
}
|
||||
|
||||
.claro .dijitSelect .dijitInputField,
|
||||
.claro .dijitTextBox .dijitInputField {
|
||||
// Subtract 1px from top/bottom because we add 1px to other nodes, see rules below.
|
||||
// Although we are theoretically only adding 1px to top/bottom browsers seem to pad inputs by 1px on left/right,
|
||||
// although that varies by so compensate for that too.
|
||||
padding: @textbox-padding - 1px @textbox-padding;
|
||||
}
|
||||
|
||||
.dj_gecko .claro .dijitTextBox .dijitInputInner,
|
||||
.dj_webkit .claro .dijitTextBox .dijitInputInner {
|
||||
// Although we are theoretically only adding 1px to top/bottom, some browsers seem to pad inputs by 1px on left/right,
|
||||
// so compensate for that too.
|
||||
padding: @textbox-padding - 1px;
|
||||
}
|
||||
|
||||
.claro .dijitSelect,
|
||||
.claro .dijitSelect .dijitButtonContents,
|
||||
.claro .dijitTextBox,
|
||||
.claro .dijitTextBox .dijitButtonNode {
|
||||
/* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
|
||||
border-color: @border-color;
|
||||
.transition-property(background-color, border);
|
||||
.transition-duration(.35s);
|
||||
}
|
||||
|
||||
.claro .dijitSelect,
|
||||
.claro .dijitTextBox {
|
||||
background-color: @textbox-background-color;
|
||||
}
|
||||
|
||||
/* hover */
|
||||
.claro .dijitSelectHover,
|
||||
.claro .dijitSelectHover .dijitButtonContents,
|
||||
.claro .dijitTextBoxHover,
|
||||
.claro .dijitTextBoxHover .dijitButtonNode {
|
||||
border-color: @hovered-border-color;
|
||||
.transition-duration(.25s);
|
||||
}
|
||||
|
||||
.claro .dijitTextBoxHover {
|
||||
background-color: @textbox-hovered-background-color;
|
||||
.textbox-background-image;
|
||||
}
|
||||
|
||||
/* error state */
|
||||
.claro .dijitSelectError,
|
||||
.claro .dijitSelectError .dijitButtonContents,
|
||||
.claro .dijitTextBoxError,
|
||||
.claro .dijitTextBoxError .dijitButtonNode {
|
||||
border-color: @error-border-color;
|
||||
}
|
||||
|
||||
/* focused state */
|
||||
.claro .dijitSelectFocused,
|
||||
.claro .dijitSelectFocused .dijitButtonContents,
|
||||
.claro .dijitTextBoxFocused,
|
||||
.claro .dijitTextBoxFocused .dijitButtonNode {
|
||||
border-color:@focused-border-color;
|
||||
.transition-duration(.1s);
|
||||
}
|
||||
|
||||
.claro .dijitTextBoxFocused {
|
||||
background-color: @textbox-focused-background-color;
|
||||
.textbox-background-image;
|
||||
}
|
||||
.claro .dijitTextBoxFocused .dijitInputContainer {
|
||||
background: @textbox-focused-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitSelectErrorFocused,
|
||||
.claro .dijitSelectErrorFocused .dijitButtonContents,
|
||||
.claro .dijitTextBoxErrorFocused,
|
||||
.claro .dijitTextBoxErrorFocused .dijitButtonNode {
|
||||
border-color: @error-focused-border-color;
|
||||
}
|
||||
|
||||
/* disabled state */
|
||||
.claro .dijitSelectDisabled,
|
||||
.claro .dijitSelectDisabled .dijitButtonContents,
|
||||
.claro .dijitTextBoxDisabled,
|
||||
.claro .dijitTextBoxDisabled .dijitButtonNode {
|
||||
border-color: @disabled-border-color;
|
||||
}
|
||||
|
||||
.claro .dijitSelectDisabled,
|
||||
.claro .dijitTextBoxDisabled,
|
||||
.claro .dijitTextBoxDisabled .dijitInputContainer {
|
||||
background-color: @textbox-disabled-background-color;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.claro .dijitSelectDisabled,
|
||||
.claro .dijitTextBoxDisabled,
|
||||
.claro .dijitTextBoxDisabled .dijitInputInner {
|
||||
color: @disabled-text-color;
|
||||
}
|
||||
|
||||
.dj_webkit .claro .dijitDisabled input {
|
||||
/* because WebKit lightens disabled input/textarea no matter what color you specify */
|
||||
color: darken(@disabled-text-color, 5%)
|
||||
}
|
||||
|
||||
.dj_webkit .claro textarea.dijitTextAreaDisabled {
|
||||
/* because WebKit lightens disabled input/textarea no matter what color you specify */
|
||||
color: darken(@disabled-text-color, 40%)
|
||||
}
|
||||
|
||||
/*========================= for special widgets =========================*/
|
||||
|
||||
/* Input boxes with an arrow (for a drop down) */
|
||||
|
||||
.claro .dijitSelect .dijitArrowButtonInner,
|
||||
.claro .dijitComboBox .dijitArrowButtonInner {
|
||||
background-image: url("../@{image-form-common-arrows}");
|
||||
background-position:-35px 53%;
|
||||
background-repeat: no-repeat;
|
||||
margin: 0;
|
||||
width:16px;
|
||||
}
|
||||
|
||||
.claro .dijitComboBox .dijitArrowButtonInner {
|
||||
border: 1px solid @arrowbutton-inner-border-color; // white gutter around the arrow button
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Add 1px vertical padding to the <input> where user types and the validation icon,
|
||||
to match the 1px border on arrow button */
|
||||
.claro .dijitSelectLabel,
|
||||
.claro .dijitTextBox .dijitInputInner,
|
||||
.claro .dijitValidationTextBox .dijitValidationContainer {
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
.claro .dijitComboBox .dijitButtonNode {
|
||||
background-color: @arrowbutton-background-color;
|
||||
.standard-gradient("../");
|
||||
}
|
||||
|
||||
/* Arrow "hover" effect:
|
||||
* The arrow button should change color whenever the mouse is in a position such that clicking it
|
||||
* will toggle the drop down. That's either (1) anywhere over the ComboBox or (2) over the arrow
|
||||
* button, depending on the openOnClick setting for the widget.
|
||||
*/
|
||||
.claro .dijitComboBoxOpenOnClickHover .dijitButtonNode,
|
||||
.claro .dijitComboBox .dijitDownArrowButtonHover {
|
||||
background-color:@arrowbutton-hovered-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner,
|
||||
.claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
|
||||
background-position:-70px 53%;
|
||||
}
|
||||
|
||||
/* Arrow Button change when drop down is open */
|
||||
.claro .dijitComboBox .dijitHasDropDownOpen { // .dijitHasDropDown is on dijitArrowButton node
|
||||
background-color: @pressed-background-color;
|
||||
.active-gradient("../");
|
||||
padding: 1px; // Since no border on arrow button (see rule below)
|
||||
}
|
||||
|
||||
.dj_iequirks .claro .dijitComboBox .dijitHasDropDownOpen {
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
.claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
|
||||
background-position:-70px 53%;
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
/* disabled state */
|
||||
.claro div.dijitComboBoxDisabled .dijitArrowButtonInner {
|
||||
/* specific selector set to override background-position setting from Button.js
|
||||
* (.claro .dijitComboBoxDisabled .dijitArrowButtonInner) */
|
||||
background-position:0 50%;
|
||||
background-color:@disabled-background-color;
|
||||
}
|
||||
|
||||
/*========================= hacks for browsers =========================*/
|
||||
/* it seems the input[type="hidden"] has a height (16px) too... this may cause the widget's height calculate error */
|
||||
.dj_ff3 .claro .dijitInputField input[type="hidden"] {
|
||||
display: none;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.dj_borderbox .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
|
||||
width:18px; // quirks mode means border-box sizing, so 18px with the border (same as 16px without border)
|
||||
}
|
||||
|
||||
.dj_borderbox .claro .dijitComboBoxFocused .dijitHasDropDownOpen .dijitArrowButtonInner {
|
||||
width:16px; // when no border, then back to 16px just like content-box sizing
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/* claro/form/Common_rtl.css */
|
||||
.claro .dijitTextBoxRtlError .dijitValidationContainer {
|
||||
border-left-width: 0 !important;
|
||||
border-right-width: 1px !important;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
/* claro/form/Common_rtl.css */
|
||||
|
||||
@import "../variables";
|
||||
|
||||
.claro .dijitTextBoxRtlError .dijitValidationContainer {
|
||||
border-left-width: 0 !important;
|
||||
border-right-width: 1px !important;
|
||||
}
|
148
api/js/webodf/collab/dijit/themes/claro/form/NumberSpinner.css
Normal file
@ -0,0 +1,148 @@
|
||||
/* NumberSpinner - namespace "dijitSpinner"
|
||||
*
|
||||
* Styling NumberSpinner mainly includes:
|
||||
*
|
||||
* 1. Arrows
|
||||
* Outer containers: .dijitSpinnerButtonContainer|.dijitSpinnerButtonInner - for border, padding and position
|
||||
* Arrows: .dijitArrowButton|.dijitUpArrowButton.|dijitDownArrowButton
|
||||
* Inner container: .dijitArrowButtonInner - for border, padding, width|height and background image
|
||||
*
|
||||
* 2. Hover state
|
||||
* .dijitUpArrowButtonHover|.dijitDownArrowButtonHover .* - for background color|image
|
||||
*
|
||||
* 3. Active state
|
||||
* .dijitUpArrowButtonActive|.dijitDownArrowButtonActive .* - for border, padding, margin and background color|image
|
||||
*
|
||||
* 4. Focused state
|
||||
* .dijitSpinnerFocused .* - for background color|image
|
||||
*
|
||||
* 5. Disabled state
|
||||
* .dijitSpinnerDisabled .* - for background color|image
|
||||
*/
|
||||
.claro .dijitSpinnerButtonContainer {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: auto;
|
||||
padding: 0 2px;
|
||||
}
|
||||
.claro .dijitSpinnerButtonContainer .dijitSpinnerButtonInner {
|
||||
border-width: 1px 0;
|
||||
/* reserve space to match the claro combobox button border with border and not padding to make IE happier */
|
||||
border-style: solid none;
|
||||
}
|
||||
/* button */
|
||||
.claro .dijitSpinner .dijitArrowButton {
|
||||
width: auto;
|
||||
background-color: #efefef;
|
||||
background-image: url("../images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.dj_iequirks .claro .dijitSpinner .dijitArrowButton {
|
||||
overflow: visible;
|
||||
/* 0 height w/o this */
|
||||
}
|
||||
.claro .dijitSpinner .dijitSpinnerButtonInner {
|
||||
width: 15px;
|
||||
}
|
||||
/* up & down button icons */
|
||||
.claro .dijitSpinner .dijitArrowButtonInner {
|
||||
border: solid 1px #fff;
|
||||
border-bottom-width: 0;
|
||||
/* 2 top borders = 1 top+bottom border in ComboBox */
|
||||
background-image: url("../form/images/commonFormArrows.png");
|
||||
background-repeat: no-repeat;
|
||||
height: 100%;
|
||||
width: 15px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
/* for up arrow */
|
||||
background-position: -139px center;
|
||||
/* override button.css (TODO: move to Common.css since ComboBox needs this too) */
|
||||
display: block;
|
||||
margin: -1px 0 -1px 0;
|
||||
/* compensate for inner border */
|
||||
}
|
||||
.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner,
|
||||
.dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner,
|
||||
.dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner,
|
||||
.dj_ie8 .claro .dijitSpinner .dijitArrowButtonInner {
|
||||
margin-top: 0;
|
||||
/* since its bottom aligned */
|
||||
}
|
||||
.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner {
|
||||
width: 19px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner {
|
||||
background-position: -34px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitArrowButtonInner .dijitInputField {
|
||||
padding: 0;
|
||||
}
|
||||
/** hover & focused status **/
|
||||
.claro .dijitUpArrowButtonActive,
|
||||
.claro .dijitDownArrowButtonActive {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitSpinner .dijitUpArrowButtonHover,
|
||||
.claro .dijitSpinner .dijitDownArrowButtonHover,
|
||||
.claro .dijitSpinnerFocused .dijitArrowButton {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitSpinner .dijitUpArrowButtonHover .dijitArrowButtonInner {
|
||||
background-position: -174px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitDownArrowButtonHover .dijitArrowButtonInner {
|
||||
background-position: -69px;
|
||||
}
|
||||
.claro .dijitSpinnerFocused {
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
}
|
||||
/* mouse down status */
|
||||
.claro .dijitSpinner .dijitDownArrowButtonActive,
|
||||
.claro .dijitSpinner .dijitUpArrowButtonActive {
|
||||
background-color: #7dbefa;
|
||||
background-image: url("../images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner,
|
||||
.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
|
||||
/* hide inner border while button is depressed */
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
margin-right: 2px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner {
|
||||
background-position: -173px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
|
||||
background-position: -68px;
|
||||
}
|
||||
/* disabled */
|
||||
.claro .dijitSpinnerDisabled .dijitArrowButtonInner {
|
||||
background-color: #efefef;
|
||||
}
|
||||
.claro .dijitSpinnerDisabled .dijitUpArrowButton .dijitArrowButtonInner {
|
||||
background-position: -104px;
|
||||
}
|
||||
.claro .dijitSpinnerDisabled .dijitDownArrowButton .dijitArrowButtonInner {
|
||||
background-position: 1px;
|
||||
}
|
||||
/** hacks for browsers **/
|
||||
/* for IE 7, when div is enlarged,
|
||||
* should be no empty space between dijitInputLayoutContainer and dijitSpinner*/
|
||||
.dj_ie7 .claro .dijitSpinner {
|
||||
overflow: visible;
|
||||
}
|
150
api/js/webodf/collab/dijit/themes/claro/form/NumberSpinner.less
Normal file
@ -0,0 +1,150 @@
|
||||
/* NumberSpinner - namespace "dijitSpinner"
|
||||
*
|
||||
* Styling NumberSpinner mainly includes:
|
||||
*
|
||||
* 1. Arrows
|
||||
* Outer containers: .dijitSpinnerButtonContainer|.dijitSpinnerButtonInner - for border, padding and position
|
||||
* Arrows: .dijitArrowButton|.dijitUpArrowButton.|dijitDownArrowButton
|
||||
* Inner container: .dijitArrowButtonInner - for border, padding, width|height and background image
|
||||
*
|
||||
* 2. Hover state
|
||||
* .dijitUpArrowButtonHover|.dijitDownArrowButtonHover .* - for background color|image
|
||||
*
|
||||
* 3. Active state
|
||||
* .dijitUpArrowButtonActive|.dijitDownArrowButtonActive .* - for border, padding, margin and background color|image
|
||||
*
|
||||
* 4. Focused state
|
||||
* .dijitSpinnerFocused .* - for background color|image
|
||||
*
|
||||
* 5. Disabled state
|
||||
* .dijitSpinnerDisabled .* - for background color|image
|
||||
*/
|
||||
|
||||
@import "../variables";
|
||||
|
||||
.claro .dijitSpinnerButtonContainer {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: auto;
|
||||
padding: 0 2px;
|
||||
}
|
||||
.claro .dijitSpinnerButtonContainer .dijitSpinnerButtonInner {
|
||||
border-width: 1px 0; /* reserve space to match the claro combobox button border with border and not padding to make IE happier */
|
||||
border-style: solid none;
|
||||
}
|
||||
|
||||
/* button */
|
||||
.claro .dijitSpinner .dijitArrowButton {
|
||||
width:auto;
|
||||
background-color: @arrowbutton-background-color;
|
||||
.standard-gradient("../");
|
||||
overflow: hidden;
|
||||
}
|
||||
.dj_iequirks .claro .dijitSpinner .dijitArrowButton {
|
||||
overflow: visible; /* 0 height w/o this */
|
||||
}
|
||||
|
||||
.claro .dijitSpinner .dijitSpinnerButtonInner {
|
||||
width: 15px;
|
||||
}
|
||||
/* up & down button icons */
|
||||
.claro .dijitSpinner .dijitArrowButtonInner {
|
||||
border:solid 1px @arrowbutton-inner-border-color;
|
||||
border-bottom-width: 0; /* 2 top borders = 1 top+bottom border in ComboBox */
|
||||
background-image: url("../@{image-form-common-arrows}");
|
||||
background-repeat: no-repeat;
|
||||
height: 100%;
|
||||
width:15px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
|
||||
/* for up arrow */
|
||||
background-position:-139px center;
|
||||
|
||||
/* override button.css (TODO: move to Common.css since ComboBox needs this too) */
|
||||
display: block;
|
||||
margin: -1px 0 -1px 0; /* compensate for inner border */
|
||||
}
|
||||
|
||||
.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner,
|
||||
.dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner,
|
||||
.dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner,
|
||||
.dj_ie8 .claro .dijitSpinner .dijitArrowButtonInner {
|
||||
margin-top: 0; /* since its bottom aligned */
|
||||
}
|
||||
|
||||
.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner {
|
||||
width: 19px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner {
|
||||
background-position:-34px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitArrowButtonInner .dijitInputField {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/** hover & focused status **/
|
||||
|
||||
.claro .dijitUpArrowButtonActive,
|
||||
.claro .dijitDownArrowButtonActive {
|
||||
background-color:@arrowbutton-pressed-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitSpinner .dijitUpArrowButtonHover,
|
||||
.claro .dijitSpinner .dijitDownArrowButtonHover,
|
||||
.claro .dijitSpinnerFocused .dijitArrowButton {
|
||||
background-color: @arrowbutton-hovered-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitSpinner .dijitUpArrowButtonHover .dijitArrowButtonInner {
|
||||
background-position:-174px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitDownArrowButtonHover .dijitArrowButtonInner {
|
||||
background-position:-69px;
|
||||
}
|
||||
|
||||
.claro .dijitSpinnerFocused {
|
||||
background-color: @textbox-focused-background-color;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
/* mouse down status */
|
||||
.claro .dijitSpinner .dijitDownArrowButtonActive,
|
||||
.claro .dijitSpinner .dijitUpArrowButtonActive {
|
||||
background-color: #7dbefa; // TODO. Mailed Jason about inconsistent ComboBox/Spinner behavior.
|
||||
.active-gradient("../");
|
||||
}
|
||||
.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner,
|
||||
.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
|
||||
/* hide inner border while button is depressed */
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
margin-right:2px;
|
||||
margin-bottom:1px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner {
|
||||
background-position:-173px;
|
||||
}
|
||||
.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
|
||||
background-position:-68px;
|
||||
}
|
||||
|
||||
/* disabled */
|
||||
|
||||
.claro .dijitSpinnerDisabled .dijitArrowButtonInner {
|
||||
background-color: @disabled-background-color;
|
||||
}
|
||||
.claro .dijitSpinnerDisabled .dijitUpArrowButton .dijitArrowButtonInner {
|
||||
background-position:-104px;
|
||||
}
|
||||
.claro .dijitSpinnerDisabled .dijitDownArrowButton .dijitArrowButtonInner {
|
||||
background-position:1px;
|
||||
}
|
||||
|
||||
/** hacks for browsers **/
|
||||
|
||||
/* for IE 7, when div is enlarged,
|
||||
* should be no empty space between dijitInputLayoutContainer and dijitSpinner*/
|
||||
.dj_ie7 .claro .dijitSpinner {
|
||||
overflow:visible;
|
||||
}
|
74
api/js/webodf/collab/dijit/themes/claro/form/RadioButton.css
Normal file
@ -0,0 +1,74 @@
|
||||
/* RadioButton
|
||||
*
|
||||
* Styling RadioButton mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitRadio|.dijitRadioIcon - for border, padding, width|height and background image
|
||||
*
|
||||
* 2. RadioButton within ToggleButton
|
||||
* .dijitToggleButton|.dijitToggleButtonChecked .* - for background image
|
||||
*
|
||||
* 3. Checked state
|
||||
* .dijitRadioChecked - for checked background-color|image
|
||||
* .dijitToggleButtonChecked - for border, background-color|image, display and width|height
|
||||
*
|
||||
* 4. Hover state
|
||||
* .dijitRadioHover|.dijitRadioCheckedHover - for background image
|
||||
*
|
||||
* 5. Disabled state
|
||||
* .dijitRadioDisabled|.dijitRadioCheckedDisabled - for background image
|
||||
*/
|
||||
.claro .dijitToggleButton .dijitRadio,
|
||||
.claro .dijitToggleButton .dijitRadioIcon {
|
||||
background-image: url("../form/images/checkboxRadioButtonStates.png");
|
||||
}
|
||||
.dj_ie6 .claro .dijitToggleButton .dijitRadio,
|
||||
.dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
|
||||
background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
|
||||
}
|
||||
.claro .dijitRadio,
|
||||
.claro .dijitRadioIcon {
|
||||
/* inside a toggle button */
|
||||
background-image: url("../form/images/checkboxRadioButtonStates.png");
|
||||
/* checkbox sprite image */
|
||||
background-repeat: no-repeat;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin: 0 2px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
.dj_ie6 .claro .dijitRadio,
|
||||
.dj_ie6 .claro .dijitRadioIcon {
|
||||
/* inside a toggle button */
|
||||
background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
|
||||
/* checkbox sprite image */
|
||||
}
|
||||
.claro .dijitRadio {
|
||||
/* unselected */
|
||||
background-position: -105px;
|
||||
}
|
||||
.claro .dijitToggleButton .dijitRadioIcon {
|
||||
/* unselected */
|
||||
background-position: -107px;
|
||||
}
|
||||
.claro .dijitRadioDisabled {
|
||||
/* unselected and disabled */
|
||||
background-position: -165px;
|
||||
}
|
||||
.claro .dijitRadioHover {
|
||||
/* hovering over an unselected enabled radio button */
|
||||
background-position: -135px;
|
||||
}
|
||||
.claro .dijitRadioChecked {
|
||||
background-position: -90px;
|
||||
}
|
||||
.claro .dijitToggleButtonChecked .dijitRadioIcon {
|
||||
background-position: -92px;
|
||||
}
|
||||
.claro .dijitRadioCheckedHover {
|
||||
background-position: -120px;
|
||||
}
|
||||
.claro .dijitRadioCheckedDisabled {
|
||||
/* selected but disabled */
|
||||
background-position: -150px;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/* RadioButton
|
||||
*
|
||||
* Styling RadioButton mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitRadio|.dijitRadioIcon - for border, padding, width|height and background image
|
||||
*
|
||||
* 2. RadioButton within ToggleButton
|
||||
* .dijitToggleButton|.dijitToggleButtonChecked .* - for background image
|
||||
*
|
||||
* 3. Checked state
|
||||
* .dijitRadioChecked - for checked background-color|image
|
||||
* .dijitToggleButtonChecked - for border, background-color|image, display and width|height
|
||||
*
|
||||
* 4. Hover state
|
||||
* .dijitRadioHover|.dijitRadioCheckedHover - for background image
|
||||
*
|
||||
* 5. Disabled state
|
||||
* .dijitRadioDisabled|.dijitRadioCheckedDisabled - for background image
|
||||
*/
|
||||
|
||||
@import "../variables";
|
||||
|
||||
.claro .dijitToggleButton .dijitRadio,
|
||||
.claro .dijitToggleButton .dijitRadioIcon {
|
||||
background-image: url("../@{image-form-checkbox-and-radios}");
|
||||
}
|
||||
|
||||
.dj_ie6 .claro .dijitToggleButton .dijitRadio,
|
||||
.dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
|
||||
background-image: url("../@{image-form-checkbox-and-radios-ie6}");
|
||||
}
|
||||
|
||||
.claro .dijitRadio,
|
||||
.claro .dijitRadioIcon { /* inside a toggle button */
|
||||
background-image: url("../@{image-form-checkbox-and-radios}"); /* checkbox sprite image */
|
||||
background-repeat: no-repeat;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin: 0 2px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dj_ie6 .claro .dijitRadio,
|
||||
.dj_ie6 .claro .dijitRadioIcon { /* inside a toggle button */
|
||||
background-image: url("../@{image-form-checkbox-and-radios-ie6}"); /* checkbox sprite image */
|
||||
}
|
||||
|
||||
.claro .dijitRadio{
|
||||
/* unselected */
|
||||
background-position: -105px;
|
||||
}
|
||||
|
||||
.claro .dijitToggleButton .dijitRadioIcon {
|
||||
/* unselected */
|
||||
background-position: -107px;
|
||||
}
|
||||
|
||||
.claro .dijitRadioDisabled {
|
||||
/* unselected and disabled */
|
||||
background-position: -165px;
|
||||
}
|
||||
|
||||
.claro .dijitRadioHover {
|
||||
/* hovering over an unselected enabled radio button */
|
||||
background-position: -135px;
|
||||
}
|
||||
|
||||
.claro .dijitRadioChecked{
|
||||
background-position: -90px;
|
||||
}
|
||||
|
||||
.claro .dijitToggleButtonChecked .dijitRadioIcon {
|
||||
background-position: -92px;
|
||||
}
|
||||
|
||||
.claro .dijitRadioCheckedHover{
|
||||
background-position: -120px;
|
||||
}
|
||||
|
||||
.claro .dijitRadioCheckedDisabled {
|
||||
/* selected but disabled */
|
||||
background-position: -150px;
|
||||
}
|
96
api/js/webodf/collab/dijit/themes/claro/form/Select.css
Normal file
@ -0,0 +1,96 @@
|
||||
/* Select
|
||||
*
|
||||
* Styling Select mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitSelect - for border, background-color
|
||||
* .dijitButtonContents - for border
|
||||
*
|
||||
* 2. Arrow
|
||||
* .dijitArrowButton - for border, padding and background-color|image
|
||||
* .dijitArrowButtonInner - for border, background-color|image, display and width|height
|
||||
*
|
||||
* 3. Menu
|
||||
* .dijitSelectMenu .* - for border, padding
|
||||
*
|
||||
* 4. Various states
|
||||
* .dijitSelectHover|.dijitSelectFocused|.dijitSelectDisabled .* - for border, padding and background-color|image
|
||||
*/
|
||||
/* normal status */
|
||||
.claro .dijitSelect .dijitArrowButtonContainer {
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
.claro .dijitSelect .dijitArrowButton {
|
||||
padding: 0;
|
||||
background-color: #efefef;
|
||||
background-image: url("../images/standardGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
|
||||
height: 16px;
|
||||
}
|
||||
/* hover status */
|
||||
.claro .dijitSelectHover {
|
||||
background-color: #e5f2fe;
|
||||
background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-image: -ms-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.claro .dijitSelectFocused,
|
||||
.claro .dijitSelectHover {
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSelectHover .dijitArrowButton {
|
||||
background-color: #abd6ff;
|
||||
}
|
||||
.claro .dijitSelectHover .dijitArrowButton .dijitArrowButtonInner {
|
||||
background-position: -70px 53%;
|
||||
}
|
||||
/* focused status */
|
||||
.claro .dijitSelectFocused .dijitArrowButton {
|
||||
background-color: #7dbefa;
|
||||
background-image: url("../images/activeGradient.png");
|
||||
background-repeat: repeat-x;
|
||||
background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
background-image: -ms-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
|
||||
_background-image: none;
|
||||
}
|
||||
.claro .dijitSelectFocused .dijitArrowButton {
|
||||
border: none;
|
||||
padding: 1px;
|
||||
}
|
||||
.claro .dijitSelectFocused .dijitArrowButton .dijitArrowButtonInner {
|
||||
background-position: -70px 53%;
|
||||
}
|
||||
/* disable status */
|
||||
.claro .dijitSelectDisabled {
|
||||
border-color: #d3d3d3;
|
||||
background-color: #efefef;
|
||||
background-image: none;
|
||||
color: #818181;
|
||||
}
|
||||
.claro .dijitSelectDisabled .dijitArrowButton .dijitArrowButtonInner {
|
||||
background-position: 0 53%;
|
||||
}
|
||||
/* Dropdown menu style for select */
|
||||
.claro .dijitSelectMenu td.dijitMenuItemIconCell,
|
||||
.claro .dijitSelectMenu td.dijitMenuArrowCell {
|
||||
/* so that arrow and icon cells from MenuItem are not displayed */
|
||||
display: none;
|
||||
}
|
||||
.claro .dijitSelectMenu td.dijitMenuItemLabel {
|
||||
/* line up menu text with text in select box (in LTR and RTL modes) */
|
||||
padding: 2px;
|
||||
}
|
||||
.claro .dijitSelectMenu .dijitMenuSeparatorTop {
|
||||
border-bottom: 1px solid #759dc0;
|
||||
}
|
98
api/js/webodf/collab/dijit/themes/claro/form/Select.less
Normal file
@ -0,0 +1,98 @@
|
||||
/* Select
|
||||
*
|
||||
* Styling Select mainly includes:
|
||||
*
|
||||
* 1. Containers
|
||||
* .dijitSelect - for border, background-color
|
||||
* .dijitButtonContents - for border
|
||||
*
|
||||
* 2. Arrow
|
||||
* .dijitArrowButton - for border, padding and background-color|image
|
||||
* .dijitArrowButtonInner - for border, background-color|image, display and width|height
|
||||
*
|
||||
* 3. Menu
|
||||
* .dijitSelectMenu .* - for border, padding
|
||||
*
|
||||
* 4. Various states
|
||||
* .dijitSelectHover|.dijitSelectFocused|.dijitSelectDisabled .* - for border, padding and background-color|image
|
||||
*/
|
||||
|
||||
@import "../variables";
|
||||
|
||||
/* normal status */
|
||||
.claro .dijitSelect .dijitArrowButtonContainer {
|
||||
border: 1px solid @arrowbutton-inner-border-color;
|
||||
}
|
||||
|
||||
.claro .dijitSelect .dijitArrowButton {
|
||||
padding: 0;
|
||||
background-color: @arrowbutton-background-color;
|
||||
.standard-gradient("../");
|
||||
}
|
||||
|
||||
.claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
|
||||
height:16px;
|
||||
}
|
||||
|
||||
/* hover status */
|
||||
.claro .dijitSelectHover {
|
||||
background-color: @textbox-hovered-background-color;
|
||||
.textbox-background-image;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.claro .dijitSelectFocused,
|
||||
.claro .dijitSelectHover {
|
||||
border-color:@hovered-border-color;
|
||||
}
|
||||
|
||||
.claro .dijitSelectHover .dijitArrowButton {
|
||||
background-color:@arrowbutton-hovered-background-color;
|
||||
}
|
||||
|
||||
.claro .dijitSelectHover .dijitArrowButton .dijitArrowButtonInner {
|
||||
background-position:-70px 53%;
|
||||
}
|
||||
|
||||
/* focused status */
|
||||
.claro .dijitSelectFocused .dijitArrowButton {
|
||||
background-color:#7dbefa; // TODO. Mailed Jason about inconsistent ComboBox/Spinner behavior.
|
||||
.active-gradient("../");
|
||||
}
|
||||
|
||||
.claro .dijitSelectFocused .dijitArrowButton {
|
||||
border: none;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.claro .dijitSelectFocused .dijitArrowButton .dijitArrowButtonInner {
|
||||
background-position:-70px 53%;
|
||||
}
|
||||
|
||||
/* disable status */
|
||||
.claro .dijitSelectDisabled {
|
||||
border-color: @disabled-border-color;
|
||||
background-color: @disabled-background-color;
|
||||
background-image: none;
|
||||
color: @disabled-text-color;
|
||||
}
|
||||
|
||||
.claro .dijitSelectDisabled .dijitArrowButton .dijitArrowButtonInner {
|
||||
background-position:0 53%
|
||||
}
|
||||
|
||||
/* Dropdown menu style for select */
|
||||
.claro .dijitSelectMenu td.dijitMenuItemIconCell,
|
||||
.claro .dijitSelectMenu td.dijitMenuArrowCell {
|
||||
/* so that arrow and icon cells from MenuItem are not displayed */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.claro .dijitSelectMenu td.dijitMenuItemLabel {
|
||||
/* line up menu text with text in select box (in LTR and RTL modes) */
|
||||
padding: @textbox-padding;
|
||||
}
|
||||
|
||||
.claro .dijitSelectMenu .dijitMenuSeparatorTop {
|
||||
border-bottom:1px solid @focused-border-color;
|
||||
}
|
345
api/js/webodf/collab/dijit/themes/claro/form/Slider.css
Normal file
@ -0,0 +1,345 @@
|
||||
/* Slider
|
||||
*
|
||||
* Styling Slider mainly includes styling the Slider progress bar (dijitSliderProgressBar)
|
||||
*
|
||||
* Slider progress bar:
|
||||
* 1. Slider progress bar (default styling):
|
||||
* .dijitSliderProgressBarH - progress bar at the middle of horizontal slider
|
||||
* .dijitSliderLeftBumper - bar at the left of horizontal slider
|
||||
* .dijitSliderRightBumper - bar at the right of horizontal slider
|
||||
* .dijitSliderProgressBarV - progress bar at the middle of vertical slider
|
||||
* .dijitSliderTopBumper - bar at the top of vertical slider
|
||||
* .dijitSliderBottomtBumper - bar at the bottom of vertical slider
|
||||
*
|
||||
* 2. hovered Slider progress bar (ie, mouse hover on progress bar)
|
||||
* .dijitSliderHover .dijitSliderProgressBarH(horizontal) - hovered bar style: background, border
|
||||
*
|
||||
* 3. focused Slider progress bar (ie, mouse focused on progress bar)
|
||||
* .dijitSliderFocused .dijitSliderProgressBarH(horizontal) - focus bar style: background, border
|
||||
*
|
||||
* 4. disabled/read-only Slider progress bar
|
||||
* .dijitSliderDisabled .dijitSliderProgressBarH(horizontal) - bar styles when slider is disabled
|
||||
*
|
||||
*
|
||||
* Slider Thumbs:
|
||||
* 1. Slider Thumbs (default styling):
|
||||
* .dijitSliderImageHandleH / .dijitSliderImageHandleV - styles for the controller on the progress bar
|
||||
*
|
||||
* 2. hovered Slider Thumbs (ie, mouse hover on slider thumbs)
|
||||
* .dijitSliderHover .dijitSliderImageHandleH - hovered controller style
|
||||
*
|
||||
* 3. focused Slider progress bar (ie, mouse focused on slider thumbs)
|
||||
* .dijitSliderFocused .dijitSliderImageHandleV - focused controller style
|
||||
*
|
||||
*
|
||||
* Slider Increment/Decrement Buttons:
|
||||
* 1. Slider Increment/Decrement Buttons (default styling):
|
||||
* .dijitSliderDecrementIconH - decrement icon which lies at the left of horizontal slider
|
||||
* .dijitSliderIncrementIconH - increment icon which lies at the right of horizontal slider
|
||||
* .dijitSliderDecrementIconV - decrement icon which lies at the bottom of vertical slider
|
||||
* .dijitSliderIncrementIconV - increment icon which lies at the top of vertical slider
|
||||
*
|
||||
* 2. hovered Slider Increment/Decrement Buttons (mouse hover on the icons)
|
||||
* .dijitSliderHover .dijitSliderDecrementIconH - for background, border
|
||||
*
|
||||
* 3. active Slider Increment/Decrement Buttons (mouse down on the icons)
|
||||
* .dijitSliderActive .dijitSliderIncrementIconV - for background, border
|
||||
*
|
||||
* 4. disabled/read-only Slider Increment/Decrement Buttons
|
||||
* .dijitSliderDisabled .dijitSliderDecrementIconH - styles for the icons in disabled slider
|
||||
* .dijitSliderReadOnly .dijitSliderIncrementIconV - styles for the icons in read-only slider
|
||||
*/
|
||||
.claro .dijitSliderBar {
|
||||
border-style: solid;
|
||||
outline: 1px;
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderBar {
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderBar {
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderDisabled .dijitSliderBar {
|
||||
background-image: none;
|
||||
border-color: #d3d3d3;
|
||||
}
|
||||
.claro .dijitRuleLabelsContainer {
|
||||
color: #000;
|
||||
}
|
||||
/* Horizontal Slider */
|
||||
.claro .dijitRuleLabelsContainerH {
|
||||
padding: 2px 0;
|
||||
}
|
||||
.claro .dijitSlider .dijitSliderProgressBarH,
|
||||
.claro .dijitSlider .dijitSliderLeftBumper {
|
||||
border-color: #b5bcc7;
|
||||
background-color: #cfe5fa;
|
||||
background-image: -moz-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
|
||||
background-image: -webkit-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
|
||||
background-image: -o-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
|
||||
background-image: -ms-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
|
||||
}
|
||||
.claro .dijitSlider .dijitSliderRemainingBarH,
|
||||
.claro .dijitSlider .dijitSliderRightBumper {
|
||||
border-color: #b5bcc7;
|
||||
background-color: #fff;
|
||||
}
|
||||
.claro .dijitSliderRightBumper {
|
||||
border-right: solid 1px #b5bcc7;
|
||||
}
|
||||
.claro .dijitSliderLeftBumper {
|
||||
border-left: solid 1px #b5bcc7;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderProgressBarH,
|
||||
.claro .dijitSliderHover .dijitSliderLeftBumper {
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderRemainingBarH,
|
||||
.claro .dijitSliderHover .dijitSliderRightBumper {
|
||||
background-color: #fff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderProgressBarH,
|
||||
.claro .dijitSliderFocused .dijitSliderLeftBumper {
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
-webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderRemainingBarH,
|
||||
.claro .dijitSliderFocused .dijitSliderRightBumper {
|
||||
background-color: #fff;
|
||||
border-color: #759dc0;
|
||||
-webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.claro .dijitSliderDisabled .dijitSliderProgressBarH,
|
||||
.claro .dijitSliderDisabled .dijitSliderLeftBumper {
|
||||
background-color: #d3d3d3;
|
||||
/* left side of slider, fill matches border */
|
||||
background-image: none;
|
||||
}
|
||||
.claro .dijitSliderDisabled .dijitSliderRemainingBarH,
|
||||
.claro .dijitSliderDisabled .dijitSliderRightBumper {
|
||||
background-color: #efefef;
|
||||
}
|
||||
/* Vertical Slider */
|
||||
.claro .dijitRuleLabelsContainerV {
|
||||
padding: 0 2px;
|
||||
}
|
||||
.claro .dijitSlider .dijitSliderProgressBarV,
|
||||
.claro .dijitSlider .dijitSliderBottomBumper {
|
||||
border-color: #b5bcc7;
|
||||
background-color: #cfe5fa;
|
||||
background-image: -moz-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
|
||||
background-image: -webkit-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
|
||||
background-image: -o-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
|
||||
background-image: -ms-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
|
||||
}
|
||||
.claro .dijitSlider .dijitSliderRemainingBarV,
|
||||
.claro .dijitSlider .dijitSliderTopBumper {
|
||||
border-color: #b5bcc7;
|
||||
background-color: #fff;
|
||||
}
|
||||
.claro .dijitSliderBottomBumper {
|
||||
border-bottom: solid 1px #b5bcc7;
|
||||
}
|
||||
.claro .dijitSliderTopBumper {
|
||||
border-top: solid 1px #b5bcc7;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderProgressBarV,
|
||||
.claro .dijitSliderHover .dijitSliderBottomBumper {
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderRemainingBarV,
|
||||
.claro .dijitSliderHover .dijitSliderTopBumper {
|
||||
background-color: #fff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderProgressBarV,
|
||||
.claro .dijitSliderFocused .dijitSliderBottomBumper {
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
-webkit-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderRemainingBarV,
|
||||
.claro .dijitSliderFocused .dijitSliderTopBumper {
|
||||
background-color: #fff;
|
||||
border-color: #759dc0;
|
||||
-webkit-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.claro .dijitSliderDisabled .dijitSliderProgressBarV,
|
||||
.claro .dijitSliderDisabled .dijitSliderBottomBumper {
|
||||
background-color: #d3d3d3;
|
||||
/* bottom side of slider, fill matches border */
|
||||
}
|
||||
.claro .dijitSliderDisabled .dijitSliderRemainingBarV,
|
||||
.claro .dijitSliderDisabled .dijitSliderTopBumper {
|
||||
background-color: #efefef;
|
||||
}
|
||||
/* ------- Thumbs ------- */
|
||||
.claro .dijitSliderImageHandleH {
|
||||
border: 0;
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
background-image: url("../form/images/sliderThumbs.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 0;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderImageHandleH {
|
||||
background-position: -18px 0;
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderImageHandleH {
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.claro .dijitSliderProgressBarH .dijitSliderThumbHover {
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.claro .dijitSliderProgressBarH .dijitSliderThumbActive {
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.claro .dijitSliderReadOnly .dijitSliderImageHandleH,
|
||||
.claro .dijitSliderDisabled .dijitSliderImageHandleH {
|
||||
background-position: -54px 0;
|
||||
}
|
||||
.claro .dijitSliderImageHandleV {
|
||||
border: 0;
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
background-image: url("../form/images/sliderThumbs.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: -289px 0;
|
||||
}
|
||||
.claro .dijitSliderHover .dijitSliderImageHandleV {
|
||||
background-position: -307px 0;
|
||||
}
|
||||
.claro .dijitSliderFocused .dijitSliderImageHandleV {
|
||||
background-position: -325px 0;
|
||||
}
|
||||
.claro .dijitSliderProgressBarV .dijitSliderThumbHover {
|
||||
background-position: -325px 0;
|
||||
}
|
||||
.claro .dijitSliderProgressBarV .dijitSliderThumbActive {
|
||||
background-position: -325px 0;
|
||||
}
|
||||
.claro .dijitSliderReadOnly .dijitSliderImageHandleV,
|
||||
.claro .dijitSliderDisabled .dijitSliderImageHandleV {
|
||||
background-position: -343px 0;
|
||||
}
|
||||
/* ---- Increment/Decrement Buttons ---- */
|
||||
.claro .dijitSliderButtonContainerH {
|
||||
padding: 1px 3px 1px 2px;
|
||||
}
|
||||
.claro .dijitSliderButtonContainerV {
|
||||
padding: 3px 1px 2px 1px;
|
||||
}
|
||||
.claro .dijitSliderDecrementIconH,
|
||||
.claro .dijitSliderIncrementIconH,
|
||||
.claro .dijitSliderDecrementIconV,
|
||||
.claro .dijitSliderIncrementIconV {
|
||||
background-image: url("../form/images/commonFormArrows.png");
|
||||
background-repeat: no-repeat;
|
||||
background-color: #efefef;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
border: solid 1px #b5bcc7;
|
||||
font-size: 1px;
|
||||
}
|
||||
.claro .dijitSliderDecrementIconH,
|
||||
.claro .dijitSliderIncrementIconH {
|
||||
height: 12px;
|
||||
width: 9px;
|
||||
}
|
||||
.claro .dijitSliderDecrementIconV,
|
||||
.claro .dijitSliderIncrementIconV {
|
||||
height: 9px;
|
||||
width: 12px;
|
||||
}
|
||||
.claro .dijitSliderActive .dijitSliderDecrementIconH,
|
||||
.claro .dijitSliderActive .dijitSliderIncrementIconH,
|
||||
.claro .dijitSliderActive .dijitSliderDecrementIconV,
|
||||
.claro .dijitSliderActive .dijitSliderIncrementIconV,
|
||||
.claro .dijitSliderHover .dijitSliderDecrementIconH,
|
||||
.claro .dijitSliderHover .dijitSliderIncrementIconH,
|
||||
.claro .dijitSliderHover .dijitSliderDecrementIconV,
|
||||
.claro .dijitSliderHover .dijitSliderIncrementIconV {
|
||||
/* dijitSliderActive should be treated as dijitSliderHover since "clicking the slider" has no meaning */
|
||||
border: solid 1px #759dc0;
|
||||
background-color: #fff;
|
||||
}
|
||||
.claro .dijitSliderDecrementIconH {
|
||||
background-position: -357px 50%;
|
||||
}
|
||||
.claro .dijitSliderActive .dijitSliderDecrementIconH .claro .dijitSliderHover .dijitSliderDecrementIconH {
|
||||
background-position: -393px 50%;
|
||||
}
|
||||
.claro .dijitSliderIncrementIconH {
|
||||
background-position: -251px 50%;
|
||||
}
|
||||
.claro .dijitSliderActive .dijitSliderIncrementIconH .claro .dijitSliderHover .dijitSliderIncrementIconH {
|
||||
background-position: -283px 50%;
|
||||
}
|
||||
.claro .dijitSliderDecrementIconV {
|
||||
background-position: -38px 50%;
|
||||
}
|
||||
.claro .dijitSliderActive .dijitSliderDecrementIconV .claro .dijitSliderHover .dijitSliderDecrementIconV {
|
||||
background-position: -73px 50%;
|
||||
}
|
||||
.claro .dijitSliderIncrementIconV {
|
||||
background-position: -143px 49%;
|
||||
}
|
||||
.claro .dijitSliderActive .dijitSliderIncrementIconV .claro .dijitSliderHover .dijitSliderIncrementIconV {
|
||||
background-position: -178px 49%;
|
||||
}
|
||||
.claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonHover,
|
||||
.claro .dijitSliderButtonContainerH .dijitSliderDecrementButtonHover,
|
||||
.claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonHover,
|
||||
.claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonHover {
|
||||
background-color: #cfe5fa;
|
||||
}
|
||||
.claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonActive,
|
||||
.claro .dijitSliderButtonContainerH .dijitSliderDecrementButtonActive,
|
||||
.claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonActive,
|
||||
.claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonActive {
|
||||
background-color: #abd6ff;
|
||||
border-color: #759dc0;
|
||||
}
|
||||
.claro .dijitSliderButtonInner {
|
||||
visibility: hidden;
|
||||
}
|
||||
.claro .dijitSliderDisabled .dijitSliderBar {
|
||||
border-color: #d3d3d3;
|
||||
}
|
||||
.claro .dijitSliderReadOnly *,
|
||||
.claro .dijitSliderDisabled * {
|
||||
border-color: #d3d3d3;
|
||||
color: #818181;
|
||||
}
|
||||
.claro .dijitSliderReadOnly .dijitSliderDecrementIconH,
|
||||
.claro .dijitSliderDisabled .dijitSliderDecrementIconH {
|
||||
background-position: -321px 50%;
|
||||
background-color: #efefef;
|
||||
}
|
||||
.claro .dijitSliderReadOnly .dijitSliderIncrementIconH,
|
||||
.claro .dijitSliderDisabled .dijitSliderIncrementIconH {
|
||||
background-position: -215px 50%;
|
||||
background-color: #efefef;
|
||||
}
|
||||
.claro .dijitSliderReadOnly .dijitSliderDecrementIconV,
|
||||
.claro .dijitSliderDisabled .dijitSliderDecrementIconV {
|
||||
background-position: -3px 49%;
|
||||
background-color: #efefef;
|
||||
}
|
||||
.claro .dijitSliderReadOnly .dijitSliderIncrementIconV,
|
||||
.claro .dijitSliderDisabled .dijitSliderIncrementIconV {
|
||||
background-position: -107px 49%;
|
||||
background-color: #efefef;
|
||||
}
|