Update wmts-hidpi, add nicer-api-docs

This commit is contained in:
Andreas Hocevar
2014-05-06 13:02:46 -05:00
parent b3ac1afd00
commit 1e25fc5585
2239 changed files with 3726515 additions and 37010 deletions

View File

@@ -0,0 +1,47 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.ArrowPalette');
goog.require('goog.math.Size');
goog.require('goog.ui.equation.Palette');
/**
* Constructs a new arrows palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @extends {goog.ui.equation.Palette}
* @constructor
*/
goog.ui.equation.ArrowPalette = function(paletteManager) {
goog.ui.equation.Palette.call(this, paletteManager,
goog.ui.equation.Palette.Type.ARROW,
0, 150, 18, 18,
['\\leftarrow',
'\\rightarrow',
'\\leftrightarrow',
'\\Leftarrow',
'\\Rightarrow',
'\\Leftrightarrow',
'\\uparrow',
'\\downarrow',
'\\updownarrow',
'\\Uparrow',
'\\Downarrow',
'\\Updownarrow']);
this.setSize(new goog.math.Size(12, 1));
};
goog.inherits(goog.ui.equation.ArrowPalette, goog.ui.equation.Palette);

View File

@@ -0,0 +1,37 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.ChangeEvent');
goog.require('goog.events.Event');
/**
* Event fired when equation changes.
* @constructor
* @param {boolean} isValid Whether the equation is valid.
* @extends {goog.events.Event}
*/
goog.ui.equation.ChangeEvent = function(isValid) {
goog.events.Event.call(this, 'change');
/**
* Whether equation is valid.
* @type {boolean}
*/
this.isValid = isValid;
};
goog.inherits(goog.ui.equation.ChangeEvent, goog.events.Event);

View File

@@ -0,0 +1,56 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.ComparisonPalette');
goog.require('goog.math.Size');
goog.require('goog.ui.equation.Palette');
/**
* Constructs a new comparison palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @extends {goog.ui.equation.Palette}
* @constructor
*/
goog.ui.equation.ComparisonPalette = function(paletteManager) {
goog.ui.equation.Palette.call(this, paletteManager,
goog.ui.equation.Palette.Type.COMPARISON,
0, 70, 18, 18,
['\\leq',
'\\geq',
'\\prec',
'\\succ',
'\\preceq',
'\\succeq',
'\\ll',
'\\gg',
'\\equiv',
'\\sim',
'\\\simeq',
'\\\asymp',
'\\approx',
'\\ne',
'\\\subset',
'\\supset',
'\\subseteq',
'\\supseteq',
'\\in',
'\\ni',
'\\notin']);
this.setSize(new goog.math.Size(7, 3));
};
goog.inherits(goog.ui.equation.ComparisonPalette, goog.ui.equation.Palette);

View File

@@ -0,0 +1,93 @@
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.EditorPane');
goog.require('goog.style');
goog.require('goog.ui.Component');
/**
* An abstract equation editor tab pane.
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* @constructor
* @extends {goog.ui.Component}
*/
goog.ui.equation.EditorPane = function(opt_domHelper) {
goog.ui.Component.call(this, opt_domHelper);
};
goog.inherits(goog.ui.equation.EditorPane, goog.ui.Component);
/**
* A link to any available help documentation to be displayed in a "Learn more"
* link. If not set through the equationeditor plugin constructor, the link
* will be omitted.
* @type {string}
* @private
*/
goog.ui.equation.EditorPane.prototype.helpUrl_ = '';
/**
* Sets the visibility of this tab pane.
* @param {boolean} visible Whether this tab should become visible.
*/
goog.ui.equation.EditorPane.prototype.setVisible =
function(visible) {
goog.style.setElementShown(this.getElement(), visible);
};
/**
* Sets the equation to show in this tab pane.
* @param {string} equation The equation.
* @protected
*/
goog.ui.equation.EditorPane.prototype.setEquation = goog.abstractMethod;
/**
* @return {string} The equation shown in this tab pane.
* @protected
*/
goog.ui.equation.EditorPane.prototype.getEquation = goog.abstractMethod;
/**
* Sets the help link URL to show in this tab pane.
* @param {string} url The help link URL.
* @protected
*/
goog.ui.equation.EditorPane.prototype.setHelpUrl = function(url) {
this.helpUrl_ = url;
};
/**
* @return {string} The help link URL.
* @protected
*/
goog.ui.equation.EditorPane.prototype.getHelpUrl = function() {
return this.helpUrl_;
};
/**
* @return {boolean} Whether the equation was modified.
* @protected
*/
goog.ui.equation.EditorPane.prototype.isModified = goog.abstractMethod;

View File

@@ -0,0 +1,220 @@
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.EquationEditor');
goog.require('goog.events');
goog.require('goog.ui.Component');
goog.require('goog.ui.TabBar');
goog.require('goog.ui.equation.ImageRenderer');
goog.require('goog.ui.equation.TexPane');
/**
* User interface for equation editor plugin.
* @constructor
* @param {Object} context The context that this equation editor runs in.
* @param {goog.dom.DomHelper=} opt_domHelper DomHelper to use.
* @param {string=} opt_helpUrl Help document URL to use in the "Learn more"
* link.
* @extends {goog.ui.Component}
*/
goog.ui.equation.EquationEditor = function(context, opt_domHelper,
opt_helpUrl) {
goog.base(this, opt_domHelper);
/**
* The context this editor runs in.
* @type {Object}
* @private
*/
this.context_ = context;
/**
* Help document URL to use in the "Learn more" link.
* @type {string}
* @private
*/
this.helpUrl_ = opt_helpUrl || '';
};
goog.inherits(goog.ui.equation.EquationEditor, goog.ui.Component);
/**
* Constants for event names.
* @enum {string}
*/
goog.ui.equation.EquationEditor.EventType = {
/**
* Dispatched when equation changes.
*/
CHANGE: 'change'
};
/**
* The index of the last active tab. Zero means first tab.
* @type {number}
* @private
*/
goog.ui.equation.EquationEditor.prototype.activeTabIndex_ = 0;
/** @override */
goog.ui.equation.EquationEditor.prototype.createDom = function() {
goog.base(this, 'createDom');
this.createDom_();
};
/**
* Creates main editor contents.
* @private
*/
goog.ui.equation.EquationEditor.prototype.createDom_ = function() {
var contentElement = this.getElement();
/** @desc Title of the visual equation editor tab. */
var MSG_VISUAL_EDITOR = goog.getMsg('Editor');
/** @desc Title of the TeX equation editor tab. */
var MSG_TEX_EDITOR = goog.getMsg('TeX');
// Create the main tabs
var dom = this.dom_;
var tabTop = dom.createDom('div',
{'class': 'goog-tab-bar goog-tab-bar-top'},
dom.createDom('div',
{'class': 'goog-tab goog-tab-selected'}, MSG_VISUAL_EDITOR),
dom.createDom('div', {'class': 'goog-tab'}, MSG_TEX_EDITOR));
var tabClear = dom.createDom('div', {'class': 'goog-tab-bar-clear'});
var tabContent = dom.createDom('div', {'class': 'ee-content'});
dom.appendChild(contentElement, tabTop);
dom.appendChild(contentElement, tabClear);
dom.appendChild(contentElement, tabContent);
var tabBar = new goog.ui.TabBar();
tabBar.decorate(tabTop);
/**
* The tab bar.
* @type {!goog.ui.TabBar}
* @private
*/
this.tabBar_ = tabBar;
goog.events.listen(tabBar, goog.ui.Component.EventType.SELECT,
goog.bind(this.handleTabSelect_, this));
var texEditor = new goog.ui.equation.TexPane(this.context_,
this.helpUrl_, this.dom_);
this.addChild(texEditor);
texEditor.render(tabContent);
this.setVisibleTab_(0); // Make first tab visible
};
/**
* Sets the visibility of the editor.
* @param {boolean} visible Whether the editor should be visible.
*/
goog.ui.equation.EquationEditor.prototype.setVisible = function(visible) {
// Show active tab if visible, or none if not
this.setVisibleTab_(visible ? this.activeTabIndex_ : -1);
};
/**
* Sets the tab at the selected index as visible and all the rest as not
* visible.
* @param {number} tabIndex The tab index that is visible. -1 means no
* tab is visible.
* @private
*/
goog.ui.equation.EquationEditor.prototype.setVisibleTab_ = function(tabIndex) {
for (var i = 0; i < this.getChildCount(); i++) {
this.getChildAt(i).setVisible(i == tabIndex);
}
};
/** @override */
goog.ui.equation.EquationEditor.prototype.decorateInternal = function(element) {
this.setElementInternal(element);
this.createDom_();
};
/**
* Returns the encoded equation.
* @return {string} The encoded equation.
*/
goog.ui.equation.EquationEditor.prototype.getEquation = function() {
var sel = this.tabBar_.getSelectedTabIndex();
return this.getChildAt(sel).getEquation();
};
/**
* @return {string} The html code to embed in the document.
*/
goog.ui.equation.EquationEditor.prototype.getHtml = function() {
return goog.ui.equation.ImageRenderer.getHtml(this.getEquation());
};
/**
* Checks whether the current equation is valid and can be used in a document.
* @return {boolean} Whether the equation is valid.
*/
goog.ui.equation.EquationEditor.prototype.isValid = function() {
return goog.ui.equation.ImageRenderer.isEquationTooLong(
this.getEquation());
};
/**
* Handles a tab selection by the user.
* @param {goog.events.Event} e The event.
* @private
*/
goog.ui.equation.EquationEditor.prototype.handleTabSelect_ = function(e) {
var sel = this.tabBar_.getSelectedTabIndex();
if (sel != this.activeTabIndex_) {
this.activeTabIndex_ = sel;
this.setVisibleTab_(sel);
}
// TODO(user) Pass equation from the tab to the other is modified
};
/**
* Parse an equation and draw it.
* Clears any previous displayed equation.
* @param {string} equation The equation text to parse.
*/
goog.ui.equation.EquationEditor.prototype.setEquation = function(equation) {
var sel = this.tabBar_.getSelectedTabIndex();
this.getChildAt(sel).setEquation(equation);
};
/** @override */
goog.ui.equation.EquationEditor.prototype.disposeInternal = function() {
this.context_ = null;
goog.base(this, 'disposeInternal');
};

View File

@@ -0,0 +1,137 @@
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.EquationEditorDialog');
goog.require('goog.dom');
goog.require('goog.dom.classes');
goog.require('goog.ui.Dialog');
goog.require('goog.ui.equation.EquationEditor');
goog.require('goog.ui.equation.PaletteManager');
goog.require('goog.ui.equation.TexEditor');
/**
* User interface for equation editor plugin standalone tests.
* @constructor
* @param {string=} opt_equation Encoded equation. If not specified, starts with
* an empty equation.
* @extends {goog.ui.Dialog}
*/
goog.ui.equation.EquationEditorDialog = function(opt_equation) {
goog.ui.Dialog.call(this);
this.setTitle('Equation Editor');
var buttonSet = new goog.ui.Dialog.ButtonSet();
buttonSet.set(goog.ui.Dialog.DefaultButtonKeys.OK,
opt_equation ? 'Save changes' : 'Insert equation',
true);
buttonSet.set(goog.ui.Dialog.DefaultButtonKeys.CANCEL,
'Cancel', false, true);
this.setButtonSet(buttonSet);
// Create the main editor contents.
var contentElement = this.getContentElement();
var domHelper = goog.dom.getDomHelper(contentElement);
var context = this.populateContext_();
/**
* The equation editor main API.
* @type {goog.ui.equation.TexEditor}
* @private
*/
this.equationEditor_ =
new goog.ui.equation.TexEditor(context, '', domHelper);
this.equationEditor_.addEventListener(
goog.ui.equation.EquationEditor.EventType.CHANGE,
this.onChange_, false, this);
this.equationEditor_.render(this.getContentElement());
this.setEquation(opt_equation || '');
goog.dom.classes.add(this.getDialogElement(), 'ee-modal-dialog');
};
goog.inherits(goog.ui.equation.EquationEditorDialog, goog.ui.Dialog);
/**
* The dialog's OK button element.
* @type {Element?}
* @private
*/
goog.ui.equation.EquationEditorDialog.prototype.okButton_;
/** @override */
goog.ui.equation.EquationEditorDialog.prototype.setVisible = function(visible) {
goog.base(this, 'setVisible', visible);
this.equationEditor_.setVisible(visible);
};
/**
* Populates the context of this dialog.
* @return {Object} The context that this dialog runs in.
* @private
*/
goog.ui.equation.EquationEditorDialog.prototype.populateContext_ = function() {
var context = {};
context.paletteManager = new goog.ui.equation.PaletteManager(
this.getDomHelper());
return context;
};
/**
* Handles CHANGE event fired when user changes equation.
* @param {goog.ui.equation.ChangeEvent} e The event object.
* @private
*/
goog.ui.equation.EquationEditorDialog.prototype.onChange_ = function(e) {
if (!this.okButton_) {
this.okButton_ = this.getButtonSet().getButton(
goog.ui.Dialog.DefaultButtonKeys.OK);
}
this.okButton_.disabled = !e.isValid;
};
/**
* Returns the encoded equation.
* @return {string} The encoded equation.
*/
goog.ui.equation.EquationEditorDialog.prototype.getEquation = function() {
return this.equationEditor_.getEquation();
};
/**
* Sets the encoded equation.
* @param {string} equation The encoded equation.
*/
goog.ui.equation.EquationEditorDialog.prototype.setEquation =
function(equation) {
this.equationEditor_.setEquation(equation);
};
/**
* @return {string} The html code to embed in the document.
*/
goog.ui.equation.EquationEditorDialog.prototype.getHtml = function() {
return this.equationEditor_.getHtml();
};

View File

@@ -0,0 +1,75 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.GreekPalette');
goog.require('goog.math.Size');
goog.require('goog.ui.equation.Palette');
/**
* Constructs a new Greek symbols palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @extends {goog.ui.equation.Palette}
* @constructor
*/
goog.ui.equation.GreekPalette = function(paletteManager) {
goog.ui.equation.Palette.call(this, paletteManager,
goog.ui.equation.Palette.Type.GREEK,
0, 30, 18, 18,
['\\alpha',
'\\beta',
'\\gamma',
'\\delta',
'\\epsilon',
'\\varepsilon',
'\\zeta',
'\\eta',
'\\theta',
'\\vartheta',
'\\iota',
'\\kappa',
'\\lambda',
'\\mu',
'\\nu',
'\\xi',
'\\pi',
'\\varpi',
'\\rho',
'\\varrho',
'\\sigma',
'\\varsigma',
'\\tau',
'\\upsilon',
'\\phi',
'\\varphi',
'\\chi',
'\\psi',
'\\omega',
'\\Gamma',
'\\Delta',
'\\Theta',
'\\Lambda',
'\\Xi',
'\\Pi',
'\\Sigma',
'\\Upsilon',
'\\Phi',
'\\Psi',
'\\Omega']);
this.setSize(new goog.math.Size(7, 6));
};
goog.inherits(goog.ui.equation.GreekPalette, goog.ui.equation.Palette);

View File

@@ -0,0 +1,190 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Functions for rendering the equation images.
*
*/
goog.provide('goog.ui.equation.ImageRenderer');
goog.require('goog.dom.TagName');
goog.require('goog.dom.classes');
goog.require('goog.string');
goog.require('goog.uri.utils');
/**
* The server name which renders the equations.
* We use https as equations may be embedded in https pages
* and using https prevents mixed content warnings. Note that
* https equations work only on google.com domains.
* @type {string}
* @private
*/
goog.ui.equation.ImageRenderer.SERVER_NAME_ =
'https://www.google.com';
/**
* The longest equation which may be displayed, in characters.
* @type {number}
*/
goog.ui.equation.ImageRenderer.MAX_EQUATION_LENGTH = 200;
/**
* Class to put on our equations IMG elements.
* @type {string}
*/
goog.ui.equation.ImageRenderer.EE_IMG_CLASS = 'ee_img';
/**
* Non-standard to put on our equations IMG elements. Useful when classes need
* to be scrubbed from the user-generated HTML, but non-standard attributes
* can be white-listed.
*
* @type {string}
*/
goog.ui.equation.ImageRenderer.EE_IMG_ATTR = 'eeimg';
/**
* Vertical alignment for the equations IMG elements.
* @type {string}
*/
goog.ui.equation.ImageRenderer.EE_IMG_VERTICAL_ALIGN = 'middle';
/**
* The default background color as used in the img url, which is fully
* transparent white.
* @type {string}
*/
goog.ui.equation.ImageRenderer.BACKGROUND_COLOR = 'FFFFFF00';
/**
* The default foreground color as used in the img url, which is black.
* @type {string}
*/
goog.ui.equation.ImageRenderer.FOREGROUND_COLOR = '000000';
/**
* Class to put on IMG elements to keep the resize property bubble from
* appearing. This is different from PLACEHOLDER_IMG_CLASS because it's
* reasonable in some cases to be able to resize a placeholder (which should
* be reflected when the placeholder is replaced with the other content).
* @type {string}
*/
goog.ui.equation.ImageRenderer.NO_RESIZE_IMG_CLASS =
goog.getCssName('tr_noresize');
/**
* Returns the equation image src url given the equation.
* @param {string} equation The equation.
* @return {string} The equation image src url (empty string in case the
* equation was empty).
*/
goog.ui.equation.ImageRenderer.getImageUrl = function(equation) {
if (!equation) {
return '';
}
var url = goog.ui.equation.ImageRenderer.SERVER_NAME_ +
'/chart?cht=tx' +
'&chf=bg,s,' +
goog.ui.equation.ImageRenderer.BACKGROUND_COLOR +
'&chco=' +
goog.ui.equation.ImageRenderer.FOREGROUND_COLOR +
'&chl=' +
encodeURIComponent(equation);
return url;
};
/**
* Returns the equation string src for given image url.
* @param {string} imageUrl The image url.
* @return {string?} The equation string, null if imageUrl cannot be parsed.
*/
goog.ui.equation.ImageRenderer.getEquationFromImageUrl = function(imageUrl) {
return goog.uri.utils.getParamValue(imageUrl, 'chl');
};
/**
* Gets the equation string from the given equation IMG node. Returns empty
* string if the src attribute of the is not a valid equation url.
* @param {Element} equationNode The equation IMG element.
* @return {string} The equation string.
*/
goog.ui.equation.ImageRenderer.getEquationFromImage = function(equationNode) {
var url = equationNode.getAttribute('src');
if (!url) {
// Should never happen.
return '';
}
return goog.ui.equation.ImageRenderer.getEquationFromImageUrl(
url) || '';
};
/**
* Checks whether given node is an equation element.
* @param {Node} node The node to check.
* @return {boolean} Whether given node is an equation element.
*/
goog.ui.equation.ImageRenderer.isEquationElement = function(node) {
return node.nodeName == goog.dom.TagName.IMG &&
(node.getAttribute(
goog.ui.equation.ImageRenderer.EE_IMG_ATTR) ||
goog.dom.classes.has(node,
goog.ui.equation.ImageRenderer.EE_IMG_CLASS));
};
/**
* Returns the html for the html image tag for the given equation.
* @param {string} equation The equation.
* @return {string} The html code to embed in the document.
*/
goog.ui.equation.ImageRenderer.getHtml = function(equation) {
var imageSrc =
goog.ui.equation.ImageRenderer.getImageUrl(equation);
if (!imageSrc) {
return '';
}
return '<img src="' + imageSrc + '" ' +
'alt="' + goog.string.htmlEscape(equation) + '" ' +
'class="' + goog.ui.equation.ImageRenderer.EE_IMG_CLASS +
' ' + goog.ui.equation.ImageRenderer.NO_RESIZE_IMG_CLASS +
'" ' + goog.ui.equation.ImageRenderer.EE_IMG_ATTR + '="1" ' +
'style="vertical-align: ' +
goog.ui.equation.ImageRenderer.EE_IMG_VERTICAL_ALIGN + '">';
};
/**
* Checks whether equation is too long to be displayed.
* @param {string} equation The equation to test.
* @return {boolean} Whether the equation is too long.
*/
goog.ui.equation.ImageRenderer.isEquationTooLong = function(equation) {
return equation.length >
goog.ui.equation.ImageRenderer.MAX_EQUATION_LENGTH;
};

View File

@@ -0,0 +1,55 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.MathPalette');
goog.require('goog.math.Size');
goog.require('goog.ui.equation.Palette');
/**
* Constructs a new math palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @extends {goog.ui.equation.Palette}
* @constructor
*/
goog.ui.equation.MathPalette = function(paletteManager) {
goog.ui.equation.Palette.call(this, paletteManager,
goog.ui.equation.Palette.Type.MATH,
0, 90, 30, 56,
['x_{a}',
'x^{b}',
'x_{a}^{b}',
'\\bar{x}',
'\\tilde{x}',
'\\frac{a}{b}',
'\\sqrt{x}',
'\\sqrt[n]{x}',
'\\bigcap_{a}^{b}',
'\\bigcup_{a}^{b}',
'\\prod_{a}^{b}',
'\\coprod_{a}^{b}',
'\\left( x \\right)',
'\\left[ x \\right]',
'\\left\\{ x \\right\\}',
'\\left| x \\right|',
'\\int_{a}^{b}',
'\\oint_{a}^{b}',
'\\sum_{a}^{b}{x}',
'\\lim_{a \\rightarrow b}{x}']);
this.setSize(new goog.math.Size(10, 2));
};
goog.inherits(goog.ui.equation.MathPalette, goog.ui.equation.Palette);

View File

@@ -0,0 +1,86 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.MenuPalette');
goog.provide('goog.ui.equation.MenuPaletteRenderer');
goog.require('goog.math.Size');
goog.require('goog.ui.PaletteRenderer');
goog.require('goog.ui.equation.Palette');
goog.require('goog.ui.equation.PaletteRenderer');
/**
* Constructs a new menu palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @extends {goog.ui.equation.Palette}
* @constructor
*/
goog.ui.equation.MenuPalette = function(paletteManager) {
goog.ui.equation.Palette.call(this, paletteManager,
goog.ui.equation.Palette.Type.MENU,
0, 0, 46, 18,
[goog.ui.equation.Palette.Type.GREEK,
goog.ui.equation.Palette.Type.SYMBOL,
goog.ui.equation.Palette.Type.COMPARISON,
goog.ui.equation.Palette.Type.MATH,
goog.ui.equation.Palette.Type.ARROW],
goog.ui.equation.MenuPaletteRenderer.getInstance());
this.setSize(new goog.math.Size(5, 1));
};
goog.inherits(goog.ui.equation.MenuPalette, goog.ui.equation.Palette);
/**
* The CSS class name for the palette.
* @type {string}
*/
goog.ui.equation.MenuPalette.CSS_CLASS = 'ee-menu-palette';
/**
* Overrides the setVisible method to make menu palette always visible.
* @param {boolean} visible Whether to show or hide the component.
* @param {boolean=} opt_force If true, doesn't check whether the component
* already has the requested visibility, and doesn't dispatch any events.
* @return {boolean} Whether the visibility was changed.
* @override
*/
goog.ui.equation.MenuPalette.prototype.setVisible = function(
visible, opt_force) {
return goog.base(this, 'setVisible', true, opt_force);
};
/**
* The renderer for menu palette.
* @extends {goog.ui.equation.PaletteRenderer}
* @constructor
*/
goog.ui.equation.MenuPaletteRenderer = function() {
goog.ui.PaletteRenderer.call(this);
};
goog.inherits(goog.ui.equation.MenuPaletteRenderer,
goog.ui.equation.PaletteRenderer);
goog.addSingletonGetter(goog.ui.equation.MenuPaletteRenderer);
/** @override */
goog.ui.equation.MenuPaletteRenderer.prototype.getCssClass =
function() {
return goog.ui.equation.MenuPalette.CSS_CLASS;
};

View File

@@ -0,0 +1,288 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview A palette of icons.
* The icons are generated from a single sprite image that
* is used for multiple palettes.
* All icons of a single palette must be on the same sprite row
* (same y coordinate) and all have the same width.
* Each item has an associated action command that should be taken
* when certain event is dispatched.
*
*/
goog.provide('goog.ui.equation.Palette');
goog.provide('goog.ui.equation.PaletteEvent');
goog.provide('goog.ui.equation.PaletteRenderer');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events.Event');
goog.require('goog.ui.Palette');
goog.require('goog.ui.PaletteRenderer');
/**
* Constructs a new palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @param {goog.ui.equation.Palette.Type} type The type of the
* palette.
* @param {number} spriteX Coordinate of first icon in sprite.
* @param {number} spriteY Coordinate of top of all icons in sprite.
* @param {number} itemWidth Pixel width of each palette icon.
* @param {number} itemHeight Pixel height of each palette icon.
* @param {Array.<string>=} opt_actions An optional action list for palette
* elements. The number of actions determine the number of palette
* elements.
* @param {goog.ui.PaletteRenderer=} opt_renderer Optional customized renderer,
* defaults to {@link goog.ui.PaletteRenderer}.
* @extends {goog.ui.Palette}
* @constructor
*/
goog.ui.equation.Palette = function(paletteManager, type, spriteX,
spriteY, itemWidth, itemHeight, opt_actions, opt_renderer) {
/**
* The type of the palette.
* @type {goog.ui.equation.Palette.Type}
* @private
*/
this.type_ = type;
/**
* The palette actions.
* @type {Array.<string>}
* @private
*/
this.actions_ = opt_actions || [];
var renderer =
opt_renderer ||
goog.ui.equation.PaletteRenderer.getInstance();
// Create a div element for each icon.
var elements = [];
var x = - spriteX;
var y = - spriteY;
for (var i = 0; i < opt_actions.length; i++) {
elements.push(paletteManager.getDomHelper().createDom(
goog.dom.TagName.DIV,
{'class': renderer.getItemCssClass(),
'style': 'width:' + itemWidth +
'px;height:' + itemHeight +
'px;' +
'background-position:' +
x + 'px ' + y + 'px;'}));
x -= itemWidth;
}
/**
* The palette manager that manages all the palettes.
* @type {goog.ui.equation.PaletteManager}
* @private
*/
this.paletteManager_ = paletteManager;
goog.ui.Palette.call(this, elements, renderer, paletteManager.getDomHelper());
};
goog.inherits(goog.ui.equation.Palette, goog.ui.Palette);
/**
* The type of possible palettes. They are made short to minimize JS size.
* @enum {string}
*/
goog.ui.equation.Palette.Type = {
MENU: 'mn',
GREEK: 'g',
SYMBOL: 's',
COMPARISON: 'c',
MATH: 'm',
ARROW: 'a'
};
/**
* The CSS class name for the palette.
* @type {string}
*/
goog.ui.equation.Palette.CSS_CLASS = 'ee-palette';
/**
* Returns the type of the palette.
* @return {goog.ui.equation.Palette.Type} The type of the palette.
*/
goog.ui.equation.Palette.prototype.getType = function() {
return this.type_;
};
/**
* Returns the palette manager.
* @return {goog.ui.equation.PaletteManager} The palette manager
* that manages all the palette.
*/
goog.ui.equation.Palette.prototype.getPaletteManager = function() {
return this.paletteManager_;
};
/**
* Returns actions for this palette.
* @return {Array.<string>} The palette actions.
*/
goog.ui.equation.Palette.prototype.getActions = function() {
return this.actions_;
};
/**
* Returns the action for a given index.
* @param {number} index The index of the action to be retrieved.
* @return {string?} The action for given index, or {@code null} if action is
* not found.
*/
goog.ui.equation.Palette.prototype.getAction = function(index) {
return (index >= 0 && index < this.actions_.length) ?
this.actions_[index] : null;
};
/**
* Handles mouseup events. Overrides {@link goog.ui.Palette#handleMouseUp}
* by dispatching a {@link goog.ui.equation.PaletteEvent}.
* @param {goog.events.Event} e Mouse event to handle.
* @override
*/
goog.ui.equation.Palette.prototype.handleMouseUp = function(e) {
goog.base(this, 'handleMouseUp', e);
this.paletteManager_.dispatchEvent(
new goog.ui.equation.PaletteEvent(
goog.ui.equation.PaletteEvent.Type.ACTION, this));
};
/**
* Handles mouse out events. Overrides {@link goog.ui.Palette#handleMouseOut}
* by deactivate the palette.
* @param {goog.events.BrowserEvent} e Mouse event to handle.
* @override
*/
goog.ui.equation.Palette.prototype.handleMouseOut = function(e) {
goog.base(this, 'handleMouseOut', e);
// Ignore mouse moves between descendants.
if (e.relatedTarget &&
!goog.dom.contains(this.getElement(), e.relatedTarget)) {
this.paletteManager_.deactivate();
}
};
/**
* Handles mouse over events. Overrides {@link goog.ui.Palette#handleMouseOver}
* by stop deactivating the palette. When mouse leaves the palettes, the
* palettes will be deactivated after a centain period of time. Reentering the
* palettes inside this time will stop the timer and cancel the deactivation.
* @param {goog.events.BrowserEvent} e Mouse event to handle.
* @override
*/
goog.ui.equation.Palette.prototype.handleMouseOver = function(e) {
goog.base(this, 'handleMouseOver', e);
// Ignore mouse moves between descendants.
if (e.relatedTarget &&
!goog.dom.contains(this.getElement(), e.relatedTarget)) {
// Stop the timer to deactivate the palettes.
this.paletteManager_.stopDeactivation();
}
};
/**
* The event that palettes dispatches.
* @param {string} type Type of the event.
* @param {goog.ui.equation.Palette} palette The palette that the
* event is fired on.
* @param {Element=} opt_target The optional target of the event.
* @constructor
* @extends {goog.events.Event}
*/
goog.ui.equation.PaletteEvent = function(type, palette, opt_target) {
goog.events.Event.call(this, type, opt_target);
/**
* The palette the event is fired from.
* @type {goog.ui.equation.Palette}
* @private
*/
this.palette_ = palette;
};
/**
* The type of events that can be fired on palettes.
* @enum {string}
*/
goog.ui.equation.PaletteEvent.Type = {
// Take the action that is associated with the palette item.
ACTION: 'a'
};
/**
* Returns the palette that this event is fired from.
* @return {goog.ui.equation.Palette} The palette this event is
* fired from.
*/
goog.ui.equation.PaletteEvent.prototype.getPalette = function() {
return this.palette_;
};
/**
* The renderer for palette.
* @extends {goog.ui.PaletteRenderer}
* @constructor
*/
goog.ui.equation.PaletteRenderer = function() {
goog.ui.PaletteRenderer.call(this);
};
goog.inherits(goog.ui.equation.PaletteRenderer, goog.ui.PaletteRenderer);
goog.addSingletonGetter(goog.ui.equation.PaletteRenderer);
/** @override */
goog.ui.equation.PaletteRenderer.prototype.getCssClass =
function() {
return goog.ui.equation.Palette.CSS_CLASS;
};
/**
* Returns the CSS class name for the palette item.
* @return {string} The CSS class name of the palette item.
*/
goog.ui.equation.PaletteRenderer.prototype.getItemCssClass = function() {
return this.getCssClass() + '-item';
};

View File

@@ -0,0 +1,203 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.PaletteManager');
goog.require('goog.Timer');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
goog.require('goog.ui.equation.ArrowPalette');
goog.require('goog.ui.equation.ComparisonPalette');
goog.require('goog.ui.equation.GreekPalette');
goog.require('goog.ui.equation.MathPalette');
goog.require('goog.ui.equation.MenuPalette');
goog.require('goog.ui.equation.Palette');
goog.require('goog.ui.equation.SymbolPalette');
/**
* Constructs the palette manager that manages all the palettes in Equation
* Editor.
* @param {!goog.dom.DomHelper} domHelper The DOM helper to be used for
* document interaction.
* @constructor
* @extends {goog.events.EventTarget}
*/
goog.ui.equation.PaletteManager = function(domHelper) {
goog.events.EventTarget.call(this);
/** @private {!goog.dom.DomHelper} */
this.domHelper_ = domHelper;
/**
* The map of palette type and instance pair.
* @type {Object.<string, goog.ui.equation.Palette>}
* @private
*/
this.paletteMap_ = {};
/**
* The current active palette.
* @type {goog.ui.equation.Palette}
* @private
*/
this.activePalette_ = null;
/**
* The event handler for managing events.
* @type {goog.events.EventHandler}
* @private
*/
this.eventHandler_ = new goog.events.EventHandler(this);
/**
* The timer used to add grace period when deactivate palettes.
* @type {goog.Timer}
* @private
*/
this.deactivationTimer_ = new goog.Timer(300);
this.eventHandler_.listen(this.deactivationTimer_, goog.Timer.TICK,
this.handleDeactivation_);
};
goog.inherits(goog.ui.equation.PaletteManager,
goog.events.EventTarget);
/**
* Clears the deactivation timer. This is used to prevent palette manager
* deactivation when mouse pointer is moved outside palettes and moved back
* quickly inside a grace period.
*/
goog.ui.equation.PaletteManager.prototype.stopDeactivation = function() {
this.deactivationTimer_.stop();
};
/**
* Returns the palette instance of given type.
* @param {goog.ui.equation.Palette.Type} type The type of palette
* to get.
* @return {goog.ui.equation.Palette} The palette instance of given
* type. A new instance will be created. If the instance doesn't exist.
*/
goog.ui.equation.PaletteManager.prototype.getPalette =
function(type) {
var paletteMap = this.paletteMap_;
var palette = paletteMap[type];
if (!palette) {
switch (type) {
case goog.ui.equation.Palette.Type.MENU:
palette = new goog.ui.equation.MenuPalette(this);
break;
case goog.ui.equation.Palette.Type.GREEK:
palette = new goog.ui.equation.GreekPalette(this);
break;
case goog.ui.equation.Palette.Type.SYMBOL:
palette = new goog.ui.equation.SymbolPalette(this);
break;
case goog.ui.equation.Palette.Type.COMPARISON:
palette = new goog.ui.equation.ComparisonPalette(this);
break;
case goog.ui.equation.Palette.Type.MATH:
palette = new goog.ui.equation.MathPalette(this);
break;
case goog.ui.equation.Palette.Type.ARROW:
palette = new goog.ui.equation.ArrowPalette(this);
break;
default:
throw new Error('Invalid palette type!');
}
paletteMap[type] = palette;
}
return palette;
};
/**
* Sets the palette instance of given type to be the active one.
* @param {goog.ui.equation.Palette.Type} type The type of the
* palette to set active.
* @return {goog.ui.equation.Palette} The palette instance of given
* type. A new instance will be created, if the instance doesn't exist.
*/
goog.ui.equation.PaletteManager.prototype.setActive =
function(type) {
var palette = this.activePalette_;
if (palette) {
palette.setVisible(false);
}
palette = this.getPalette(type);
this.activePalette_ = palette;
palette.setVisible(true);
return palette;
};
/**
* Returns the active palette.
* @return {goog.ui.equation.Palette} The active palette.
*/
goog.ui.equation.PaletteManager.prototype.getActive = function() {
return this.activePalette_;
};
/**
* Starts the deactivation of open palette.
* This method has a slight delay before doing the real deactivation. This
* helps prevent sudden disappearing of palettes when user moves mouse outside
* them just briefly (and maybe accidentally). If you really want to deactivate
* the active palette, use {@link #deactivateNow()} instead.
*/
goog.ui.equation.PaletteManager.prototype.deactivate = function() {
this.deactivationTimer_.start();
};
/**
* Deactivate the open palette immediately.
*/
goog.ui.equation.PaletteManager.prototype.deactivateNow = function() {
this.handleDeactivation_();
};
/**
* Internal process of deactivation of the manager.
* @private
*/
goog.ui.equation.PaletteManager.prototype.handleDeactivation_ = function() {
this.setActive(goog.ui.equation.Palette.Type.MENU);
};
/**
* @return {!goog.dom.DomHelper} This object's DOM helper.
*/
goog.ui.equation.PaletteManager.prototype.getDomHelper = function() {
return this.domHelper_;
};
/** @override */
goog.ui.equation.PaletteManager.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
this.activePalette_ = null;
this.paletteMap_ = null;
};

View File

@@ -0,0 +1,74 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview A palette of symbols.
*
*/
goog.provide('goog.ui.equation.SymbolPalette');
goog.require('goog.math.Size');
goog.require('goog.ui.equation.Palette');
/**
* Constructs a new symbols palette.
* @param {goog.ui.equation.PaletteManager} paletteManager The
* manager of the palette.
* @extends {goog.ui.equation.Palette}
* @constructor
*/
goog.ui.equation.SymbolPalette = function(paletteManager) {
goog.ui.equation.Palette.call(this, paletteManager,
goog.ui.equation.Palette.Type.SYMBOL,
0, 50, 18, 18,
['\\times',
'\\div',
'\\cdot',
'\\pm',
'\\mp',
'\\ast',
'\\star',
'\\circ',
'\\bullet',
'\\oplus',
'\\ominus',
'\\oslash',
'\\otimes',
'\\odot',
'\\dagger',
'\\ddagger',
'\\vee',
'\\wedge',
'\\cap',
'\\cup',
'\\aleph',
'\\Re',
'\\Im',
'\\top',
'\\bot',
'\\infty',
'\\partial',
'\\forall',
'\\exists',
'\\neg',
'\\angle',
'\\triangle',
'\\diamond']);
this.setSize(new goog.math.Size(7, 5));
};
goog.inherits(goog.ui.equation.SymbolPalette, goog.ui.equation.Palette);

View File

@@ -0,0 +1,141 @@
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.TexEditor');
goog.require('goog.ui.Component');
goog.require('goog.ui.equation.ImageRenderer');
goog.require('goog.ui.equation.TexPane');
/**
* User interface for equation editor plugin.
* @constructor
* @param {Object} context The context that this Tex editor runs in.
* @param {string} helpUrl URL pointing to help documentation.
* @param {goog.dom.DomHelper=} opt_domHelper DomHelper to use.
* @extends {goog.ui.Component}
*/
goog.ui.equation.TexEditor = function(context, helpUrl, opt_domHelper) {
goog.ui.Component.call(this, opt_domHelper);
/**
* The context that this Tex editor runs in.
* @type {Object}
* @private
*/
this.context_ = context;
/**
* A URL pointing to help documentation.
* @type {string}
* @private
*/
this.helpUrl_ = helpUrl;
};
goog.inherits(goog.ui.equation.TexEditor, goog.ui.Component);
/**
* The TeX editor pane.
* @type {goog.ui.equation.TexPane}
* @private
*/
goog.ui.equation.TexEditor.prototype.texPane_ = null;
/** @override */
goog.ui.equation.TexEditor.prototype.createDom = function() {
goog.base(this, 'createDom');
this.createDom_();
};
/**
* Creates main editor contents.
* @private
*/
goog.ui.equation.TexEditor.prototype.createDom_ = function() {
var contentElement = this.getElement();
this.texPane_ = new goog.ui.equation.TexPane(this.context_,
this.helpUrl_, this.dom_);
this.addChild(this.texPane_);
this.texPane_.render(contentElement);
this.texPane_.setVisible(true);
};
/** @override */
goog.ui.equation.TexEditor.prototype.decorateInternal = function(element) {
this.setElementInternal(element);
this.createDom_();
};
/**
* Returns the encoded equation.
* @return {string} The encoded equation.
*/
goog.ui.equation.TexEditor.prototype.getEquation = function() {
return this.texPane_.getEquation();
};
/**
* Parse an equation and draw it.
* Clears any previous displayed equation.
* @param {string} equation The equation text to parse.
*/
goog.ui.equation.TexEditor.prototype.setEquation = function(equation) {
this.texPane_.setEquation(equation);
};
/**
* @return {string} The html code to embed in the document.
*/
goog.ui.equation.TexEditor.prototype.getHtml = function() {
return goog.ui.equation.ImageRenderer.getHtml(this.getEquation());
};
/**
* Checks whether the current equation is valid and can be used in a document.
* @return {boolean} Whether the equation valid.
*/
goog.ui.equation.TexEditor.prototype.isValid = function() {
return goog.ui.equation.ImageRenderer.isEquationTooLong(
this.getEquation());
};
/**
* Sets the visibility of the editor.
* @param {boolean} visible Whether the editor should be visible.
*/
goog.ui.equation.TexEditor.prototype.setVisible = function(visible) {
this.texPane_.setVisible(visible);
};
/** @override */
goog.ui.equation.TexEditor.prototype.disposeInternal = function() {
if (this.texPane_) {
this.texPane_.dispose();
}
this.context_ = null;
goog.base(this, 'disposeInternal');
};

View File

@@ -0,0 +1,444 @@
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.ui.equation.TexPane');
goog.require('goog.Timer');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.dom.selection');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.events.InputHandler');
goog.require('goog.style');
goog.require('goog.ui.equation.ChangeEvent');
goog.require('goog.ui.equation.EditorPane');
goog.require('goog.ui.equation.ImageRenderer');
goog.require('goog.ui.equation.Palette');
goog.require('goog.ui.equation.PaletteEvent');
/**
* User interface for TeX equation editor tab pane.
* @param {Object} context The context this Tex editor pane runs in.
* @param {string} helpUrl The help link URL.
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* @constructor
* @extends {goog.ui.equation.EditorPane}
*/
goog.ui.equation.TexPane = function(
context, helpUrl, opt_domHelper) {
goog.ui.equation.EditorPane.call(this, opt_domHelper);
this.setHelpUrl(helpUrl);
/**
* The palette manager instance.
* @type {goog.ui.equation.PaletteManager}
* @private
*/
this.paletteManager_ =
/** @type {goog.ui.equation.PaletteManager} */(
context.paletteManager);
};
goog.inherits(goog.ui.equation.TexPane,
goog.ui.equation.EditorPane);
/**
* The CSS class name for the preview container.
* @type {string}
*/
goog.ui.equation.TexPane.PREVIEW_CONTAINER_CSS_CLASS =
'ee-preview-container';
/**
* The CSS class name for section titles.
* @type {string}
*/
goog.ui.equation.TexPane.SECTION_TITLE_CSS_CLASS =
'ee-section-title';
/**
* The CSS class name for section titles that float left.
* @type {string}
*/
goog.ui.equation.TexPane.SECTION_TITLE_FLOAT_CSS_CLASS =
'ee-section-title-floating';
/**
* The CSS id name for the link to "Learn more".
* @type {string}
*/
goog.ui.equation.TexPane.SECTION_LEARN_MORE_CSS_ID =
'ee-section-learn-more';
/**
* The CSS class name for the Tex editor.
* @type {string}
*/
goog.ui.equation.TexPane.TEX_EDIT_CSS_CLASS = 'ee-tex';
/**
* The CSS class name for the preview container.
* @type {string}
*/
goog.ui.equation.TexPane.WARNING_CLASS =
'ee-warning';
/**
* The content div of the TeX editor.
* @type {Element}
* @private
*/
goog.ui.equation.TexPane.prototype.texEditorElement_ = null;
/**
* The container div for the server-generated image of the equation.
* @type {Element}
* @private
*/
goog.ui.equation.TexPane.prototype.previewContainer_;
/**
* An inner container used to layout all the elements in Tex Editor.
* @type {Element}
* @private
*/
goog.ui.equation.TexPane.prototype.innerContainer_;
/**
* The textarea for free form TeX.
* @type {Element}
* @private
*/
goog.ui.equation.TexPane.prototype.texEdit_;
/**
* The input handler for Tex editor.
* @type {goog.events.InputHandler}
* @private
*/
goog.ui.equation.TexPane.prototype.texInputHandler_;
/**
* The last text that was renderred as an image.
* @type {string}
* @private
*/
goog.ui.equation.TexPane.prototype.lastRenderredText_ = '';
/**
* A sequence number for text change events. Used to delay drawing
* until the user paused typing.
* @type {number}
* @private
*/
goog.ui.equation.TexPane.prototype.changeSequence_ = 0;
/** @override */
goog.ui.equation.TexPane.prototype.createDom = function() {
/** @desc Title for TeX editor tab in the equation editor dialog. */
var MSG_EE_TEX_EQUATION = goog.getMsg('TeX Equation');
/** @desc Title for equation preview image in the equation editor dialog. */
var MSG_EE_TEX_PREVIEW = goog.getMsg('Preview');
/** @desc Link text that leads to an info page about the equation dialog. */
var MSG_EE_LEARN_MORE = goog.getMsg('Learn more');
var domHelper = this.dom_;
var innerContainer;
var texEditorEl = domHelper.createDom(goog.dom.TagName.DIV,
{'style': 'display: none;'},
domHelper.createDom(goog.dom.TagName.SPAN,
{'class':
goog.ui.equation.TexPane.SECTION_TITLE_CSS_CLASS +
' ' +
goog.ui.equation.TexPane.SECTION_TITLE_FLOAT_CSS_CLASS},
MSG_EE_TEX_EQUATION),
this.getHelpUrl() ?
domHelper.createDom(goog.dom.TagName.A,
{'id':
goog.ui.equation.TexPane.SECTION_LEARN_MORE_CSS_ID,
'target': '_blank', 'href': this.getHelpUrl()},
MSG_EE_LEARN_MORE) : null,
domHelper.createDom(goog.dom.TagName.DIV,
{'style': 'clear: both;'}),
innerContainer = this.innerContainer_ =
domHelper.createDom(goog.dom.TagName.DIV,
{'style': 'position: relative'}));
// Create menu palette.
var menuPalette =
this.paletteManager_.setActive(
goog.ui.equation.Palette.Type.MENU);
// Render the menu palette.
menuPalette.render(innerContainer);
innerContainer.appendChild(domHelper.createDom(goog.dom.TagName.DIV,
{'style': 'clear:both'}));
var texEdit = this.texEdit_ = domHelper.createDom('textarea',
{'class': goog.ui.equation.TexPane.TEX_EDIT_CSS_CLASS,
'dir': 'ltr'});
innerContainer.appendChild(texEdit);
innerContainer.appendChild(
domHelper.createDom(goog.dom.TagName.DIV,
{'class':
goog.ui.equation.TexPane.SECTION_TITLE_CSS_CLASS},
MSG_EE_TEX_PREVIEW));
var previewContainer = this.previewContainer_ = domHelper.createDom(
goog.dom.TagName.DIV,
{'class':
goog.ui.equation.TexPane.PREVIEW_CONTAINER_CSS_CLASS});
innerContainer.appendChild(previewContainer);
this.setElementInternal(texEditorEl);
};
/** @override */
goog.ui.equation.TexPane.prototype.enterDocument = function() {
this.texInputHandler_ = new goog.events.InputHandler(this.texEdit_);
// Listen to changes in the edit box to redraw equation.
goog.events.listen(this.texInputHandler_,
goog.events.InputHandler.EventType.INPUT,
this.handleTexChange_, false, this);
// Add a keyup listener for Safari that does not support the INPUT event,
// and for users pasting with ctrl+v, which does not generate an INPUT event
// in some browsers.
this.getHandler().listen(
this.texEdit_, goog.events.EventType.KEYDOWN, this.handleTexChange_);
// Listen to the action event on the active palette.
this.getHandler().listen(this.paletteManager_,
goog.ui.equation.PaletteEvent.Type.ACTION,
this.handlePaletteAction_, false, this);
};
/** @override */
goog.ui.equation.TexPane.prototype.setVisible = function(visible) {
goog.base(this, 'setVisible', visible);
if (visible) {
goog.Timer.callOnce(this.focusTexEdit_, 0, this);
}
};
/**
* Sets the focus to the TeX edit box.
* @private
*/
goog.ui.equation.TexPane.prototype.focusTexEdit_ = function() {
this.texEdit_.focus();
goog.dom.selection.setCursorPosition(this.texEdit_,
this.texEdit_.value.length);
};
/**
* Handles input change within the TeX textarea.
* @private
*/
goog.ui.equation.TexPane.prototype.handleEquationChange_ = function() {
var text = this.getEquation();
if (text == this.lastRenderredText_) {
return; // No change, no need to re-draw
}
this.lastRenderredText_ = text;
var isEquationValid =
!goog.ui.equation.ImageRenderer.isEquationTooLong(text);
// Dispatch change so that dialog might update the state of its buttons.
this.dispatchEvent(
new goog.ui.equation.ChangeEvent(
isEquationValid));
var container = this.previewContainer_;
var dom = goog.dom.getDomHelper(container);
dom.removeChildren(container);
if (text) {
var childNode;
if (isEquationValid) {
// Show equation image.
var imgSrc = goog.ui.equation.ImageRenderer.getImageUrl(text);
childNode = dom.createDom(goog.dom.TagName.IMG, {'src': imgSrc});
} else {
// Show a warning message.
/**
* @desc A warning message shown when equation the user entered is too
* long to display.
*/
var MSG_EE_TEX_EQUATION_TOO_LONG =
goog.getMsg('Equation is too long');
childNode = dom.createDom(goog.dom.TagName.DIV,
{'class': goog.ui.equation.TexPane.WARNING_CLASS},
MSG_EE_TEX_EQUATION_TOO_LONG);
}
dom.appendChild(container, childNode);
}
};
/**
* Handles a change to the equation text.
* Queues a request to handle input change within the TeX textarea.
* Refreshing the image is done only after a short timeout, to combine
* fast typing events into one draw.
* @param {goog.events.Event} e The keyboard event.
* @private
*/
goog.ui.equation.TexPane.prototype.handleTexChange_ = function(e) {
this.changeSequence_++;
goog.Timer.callOnce(
goog.bind(this.handleTexChangeTimer_, this, this.changeSequence_),
500);
};
/**
* Handles a timer timeout on delayed text change redraw.
* @param {number} seq The change sequence number when the timer started.
* @private
*/
goog.ui.equation.TexPane.prototype.handleTexChangeTimer_ =
function(seq) {
// Draw only if this was the last change. If not, just wait for the last.
if (seq == this.changeSequence_) {
this.handleEquationChange_();
}
};
/**
* Handles an action generated by a palette click.
* @param {goog.ui.equation.PaletteEvent} e The event object.
* @private
*/
goog.ui.equation.TexPane.prototype.handlePaletteAction_ = function(e) {
var palette = e.getPalette();
var paletteManager = this.paletteManager_;
var activePalette = paletteManager.getActive();
var texEdit = this.texEdit_;
// This is a click on the menu palette.
if (palette.getType() == goog.ui.equation.Palette.Type.MENU) {
var idx = palette.getHighlightedIndex();
var action = (idx != -1) ? palette.getAction(idx) : null;
// Current palette is not menu. This means there's a palette popping up.
if (activePalette != palette && activePalette.getType() == action) {
// Deactivate the palette.
paletteManager.deactivateNow();
return;
}
// We are clicking on the menu palette and there's no sub palette opening.
// Then we just open the one corresponding to the item under the mouse.
if (action) {
var subPalette = this.paletteManager_.setActive(
/** @type {goog.ui.equation.Palette.Type} */ (action));
if (!subPalette.getElement()) {
subPalette.render(this.innerContainer_);
}
var el = subPalette.getElement();
goog.style.setPosition(el, 0, - el.clientHeight);
}
} else {
activePalette = this.paletteManager_.getActive();
var action = activePalette.getAction(activePalette.getHighlightedIndex());
// If the click is on white space in the palette, do nothing.
if (!action) {
return;
}
// Do actual insert async because IE8 does not move the selection
// position and inserts in the wrong place if called in flow.
// See bug 2066876
goog.Timer.callOnce(goog.bind(this.insert_, this, action + ' '), 0);
}
// Let the tex editor always catch the focus.
texEdit.focus();
};
/**
* Inserts text into the equation at the current cursor position.
* Moves the cursor to after the inserted text.
* @param {string} text Text to insert.
* @private
*/
goog.ui.equation.TexPane.prototype.insert_ = function(text) {
var texEdit = this.texEdit_;
var pos = goog.dom.selection.getStart(texEdit);
var equation = texEdit['value'];
equation = equation.substring(0, pos) + text + equation.substring(pos);
texEdit['value'] = equation;
goog.dom.selection.setCursorPosition(texEdit, pos + text.length);
this.handleEquationChange_();
};
/** @override */
goog.ui.equation.TexPane.prototype.getEquation = function() {
return this.texEdit_['value'];
};
/** @override */
goog.ui.equation.TexPane.prototype.setEquation =
function(equation) {
this.texEdit_['value'] = equation;
this.handleEquationChange_();
};
/** @override */
goog.ui.equation.TexPane.prototype.disposeInternal = function() {
this.texInputHandler_.dispose();
this.paletteManager_ = null;
goog.base(this, 'disposeInternal');
};