diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/ui/editor')
36 files changed, 199 insertions, 6245 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/all-wcprops b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/all-wcprops deleted file mode 100644 index 4670065..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/all-wcprops +++ /dev/null @@ -1,89 +0,0 @@ -K 25 -svn:wc:ra_dav:version-url -V 47 -/svn/!svn/ver/1472/trunk/closure/goog/ui/editor -END -linkdialog_test.html -K 25 -svn:wc:ra_dav:version-url -V 68 -/svn/!svn/ver/1292/trunk/closure/goog/ui/editor/linkdialog_test.html -END -toolbarcontroller.js -K 25 -svn:wc:ra_dav:version-url -V 68 -/svn/!svn/ver/1472/trunk/closure/goog/ui/editor/toolbarcontroller.js -END -defaulttoolbar.js -K 25 -svn:wc:ra_dav:version-url -V 65 -/svn/!svn/ver/1472/trunk/closure/goog/ui/editor/defaulttoolbar.js -END -messages.js -K 25 -svn:wc:ra_dav:version-url -V 59 -/svn/!svn/ver/1292/trunk/closure/goog/ui/editor/messages.js -END -equationeditorokevent.js -K 25 -svn:wc:ra_dav:version-url -V 72 -/svn/!svn/ver/1236/trunk/closure/goog/ui/editor/equationeditorokevent.js -END -tabpane.js -K 25 -svn:wc:ra_dav:version-url -V 58 -/svn/!svn/ver/1302/trunk/closure/goog/ui/editor/tabpane.js -END -toolbarfactory.js -K 25 -svn:wc:ra_dav:version-url -V 65 -/svn/!svn/ver/1472/trunk/closure/goog/ui/editor/toolbarfactory.js -END -abstractdialog_test.html -K 25 -svn:wc:ra_dav:version-url -V 71 -/svn/!svn/ver/850/trunk/closure/goog/ui/editor/abstractdialog_test.html -END -bubble.js -K 25 -svn:wc:ra_dav:version-url -V 57 -/svn/!svn/ver/1302/trunk/closure/goog/ui/editor/bubble.js -END -equationeditordialog.js -K 25 -svn:wc:ra_dav:version-url -V 71 -/svn/!svn/ver/1302/trunk/closure/goog/ui/editor/equationeditordialog.js -END -linkdialog.js -K 25 -svn:wc:ra_dav:version-url -V 61 -/svn/!svn/ver/1302/trunk/closure/goog/ui/editor/linkdialog.js -END -toolbarfactory_test.html -K 25 -svn:wc:ra_dav:version-url -V 71 -/svn/!svn/ver/850/trunk/closure/goog/ui/editor/toolbarfactory_test.html -END -bubble_test.html -K 25 -svn:wc:ra_dav:version-url -V 63 -/svn/!svn/ver/850/trunk/closure/goog/ui/editor/bubble_test.html -END -abstractdialog.js -K 25 -svn:wc:ra_dav:version-url -V 64 -/svn/!svn/ver/850/trunk/closure/goog/ui/editor/abstractdialog.js -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/entries b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/entries deleted file mode 100644 index c72ac4a..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/entries +++ /dev/null @@ -1,504 +0,0 @@ -10 - -dir -1494 -http://closure-library.googlecode.com/svn/trunk/closure/goog/ui/editor -http://closure-library.googlecode.com/svn - - - -2011-12-13T22:20:28.000000Z -1472 -ccalabro@google.com - - - - - - - - - - - - - - -0b95b8e8-c90f-11de-9d4f-f947ee5921c8 - -linkdialog_test.html -file - - - - -2011-12-23T22:42:35.645420Z -7a91e181558549b629bd14db44166075 -2011-09-22T17:21:12.000000Z -1292 -marcosalmeida@google.com -has-props - - - - - - - - - - - - - - - - - - - - -18308 - -toolbarcontroller.js -file - - - - -2011-12-23T22:42:35.645420Z -4f3d98102d3c286c002276027f4510a9 -2011-12-13T22:20:28.000000Z -1472 -ccalabro@google.com -has-props - - - - - - - - - - - - - - - - - - - - -9123 - -defaulttoolbar.js -file - - - - -2011-12-23T22:42:35.646420Z -3d71e10ad11b183ec17d24d5146d6e3f -2011-12-13T22:20:28.000000Z -1472 -ccalabro@google.com -has-props - - - - - - - - - - - - - - - - - - - - -39517 - -messages.js -file - - - - -2011-12-23T22:42:35.647420Z -1109c60d154b31385ea8ea303ba32e1b -2011-09-22T17:21:12.000000Z -1292 -marcosalmeida@google.com -has-props - - - - - - - - - - - - - - - - - - - - -4053 - -equationeditorokevent.js -file - - - - -2011-12-23T22:42:35.647420Z -98bf468fe5a0edebae19ed80e2a7efb3 -2011-08-19T16:22:39.000000Z -1236 -bills@google.com -has-props - - - - - - - - - - - - - - - - - - - - -1494 - -tabpane.js -file - - - - -2011-12-23T22:42:35.648420Z -cdbe26087e2561ccc98b59ecd55a969f -2011-09-27T00:20:47.000000Z -1302 -bmccann@google.com -has-props - - - - - - - - - - - - - - - - - - - - -5288 - -toolbarfactory.js -file - - - - -2011-12-23T22:42:35.649420Z -67a3502cac2309d8be7c64c0cb62b809 -2011-12-13T22:20:28.000000Z -1472 -ccalabro@google.com -has-props - - - - - - - - - - - - - - - - - - - - -18248 - -abstractdialog_test.html -file - - - - -2011-12-23T22:42:35.650420Z -75c6deca389749877dfc0e8a42e94dde -2011-04-12T20:35:47.000000Z -850 -diegosalas@google.com -has-props - - - - - - - - - - - - - - - - - - - - -13904 - -bubble.js -file - - - - -2011-12-23T22:42:35.651420Z -7acd5b765d8d28095034ccf43971e2bd -2011-09-27T00:20:47.000000Z -1302 -bmccann@google.com -has-props - - - - - - - - - - - - - - - - - - - - -16171 - -equationeditordialog.js -file - - - - -2011-12-23T22:42:35.652420Z -f15fce4dc733349fc88e4b77270b7cf9 -2011-09-27T00:20:47.000000Z -1302 -bmccann@google.com -has-props - - - - - - - - - - - - - - - - - - - - -3753 - -linkdialog.js -file - - - - -2011-12-23T22:42:35.653420Z -dd114f8728e28785e9e737b771bca0bb -2011-09-27T00:20:47.000000Z -1302 -bmccann@google.com -has-props - - - - - - - - - - - - - - - - - - - - -29589 - -toolbarfactory_test.html -file - - - - -2011-12-23T22:42:35.654420Z -bcdd2db516a5174ea4b618a035ff2edf -2011-04-12T20:35:47.000000Z -850 -diegosalas@google.com -has-props - - - - - - - - - - - - - - - - - - - - -2424 - -bubble_test.html -file - - - - -2011-12-23T22:42:35.655420Z -5b43cfcf9c08e17caa36b9c4c4dfe3ff -2011-04-12T20:35:47.000000Z -850 -diegosalas@google.com -has-props - - - - - - - - - - - - - - - - - - - - -8673 - -abstractdialog.js -file - - - - -2011-12-23T22:42:35.656420Z -c307ae66a01bbb98e1cae0998afaac28 -2011-04-12T20:35:47.000000Z -850 -diegosalas@google.com -has-props - - - - - - - - - - - - - - - - - - - - -14359 - diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/abstractdialog.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/abstractdialog.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/abstractdialog.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/abstractdialog_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/abstractdialog_test.html.svn-base deleted file mode 100644 index d356868..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/abstractdialog_test.html.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 9 -text/html -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/bubble.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/bubble.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/bubble.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/bubble_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/bubble_test.html.svn-base deleted file mode 100644 index d356868..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/bubble_test.html.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 9 -text/html -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/defaulttoolbar.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/defaulttoolbar.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/defaulttoolbar.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/equationeditordialog.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/equationeditordialog.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/equationeditordialog.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/equationeditorokevent.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/equationeditorokevent.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/equationeditorokevent.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/linkdialog.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/linkdialog.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/linkdialog.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/linkdialog_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/linkdialog_test.html.svn-base deleted file mode 100644 index d356868..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/linkdialog_test.html.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 9 -text/html -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/messages.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/messages.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/messages.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/tabpane.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/tabpane.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/tabpane.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarcontroller.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarcontroller.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarcontroller.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarfactory.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarfactory.js.svn-base deleted file mode 100644 index 530636b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarfactory.js.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 15 -text/javascript -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarfactory_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarfactory_test.html.svn-base deleted file mode 100644 index d356868..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/prop-base/toolbarfactory_test.html.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 9 -text/html -END diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/abstractdialog.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/abstractdialog.js.svn-base deleted file mode 100644 index 4b73802..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/abstractdialog.js.svn-base +++ /dev/null @@ -1,443 +0,0 @@ -// 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. - -/** - * @fileoverview Wrapper around {@link goog.ui.Dialog}, to provide - * dialogs that are smarter about interacting with a rich text editor. - * - */ - -goog.provide('goog.ui.editor.AbstractDialog'); -goog.provide('goog.ui.editor.AbstractDialog.Builder'); -goog.provide('goog.ui.editor.AbstractDialog.EventType'); - -goog.require('goog.dom'); -goog.require('goog.dom.classes'); -goog.require('goog.events.EventTarget'); -goog.require('goog.ui.Dialog'); -goog.require('goog.ui.Dialog.ButtonSet'); -goog.require('goog.ui.Dialog.DefaultButtonKeys'); -goog.require('goog.ui.Dialog.Event'); -goog.require('goog.ui.Dialog.EventType'); - - -// *** Public interface ***************************************************** // - - - -/** - * Creates an object that represents a dialog box. - * @param {goog.dom.DomHelper} domHelper DomHelper to be used to create the - * dialog's dom structure. - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.ui.editor.AbstractDialog = function(domHelper) { - goog.events.EventTarget.call(this); - this.dom = domHelper; -}; -goog.inherits(goog.ui.editor.AbstractDialog, goog.events.EventTarget); - - -/** - * Causes the dialog box to appear, centered on the screen. Lazily creates the - * dialog if needed. - */ -goog.ui.editor.AbstractDialog.prototype.show = function() { - // Lazily create the wrapped dialog to be shown. - if (!this.dialogInternal_) { - this.dialogInternal_ = this.createDialogControl(); - this.dialogInternal_.addEventListener(goog.ui.Dialog.EventType.AFTER_HIDE, - this.handleAfterHide_, false, this); - } - - this.dialogInternal_.setVisible(true); -}; - - -/** - * Hides the dialog, causing AFTER_HIDE to fire. - */ -goog.ui.editor.AbstractDialog.prototype.hide = function() { - if (this.dialogInternal_) { - // This eventually fires the wrapped dialog's AFTER_HIDE event, calling our - // handleAfterHide_(). - this.dialogInternal_.setVisible(false); - } -}; - - -/** - * @return {boolean} Whether the dialog is open. - */ -goog.ui.editor.AbstractDialog.prototype.isOpen = function() { - return !!this.dialogInternal_ && this.dialogInternal_.isVisible(); -}; - - -/** - * Runs the handler registered on the OK button event and closes the dialog if - * that handler succeeds. - * This is useful in cases such as double-clicking an item in the dialog is - * equivalent to selecting it and clicking the default button. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.processOkAndClose = function() { - // Fake an OK event from the wrapped dialog control. - var evt = new goog.ui.Dialog.Event(goog.ui.Dialog.DefaultButtonKeys.OK, null); - if (this.handleOk(evt)) { - // handleOk calls dispatchEvent, so if any listener calls preventDefault it - // will return false and we won't hide the dialog. - this.hide(); - } -}; - - -// *** Dialog events ******************************************************** // - - -/** - * Event type constants for events the dialog fires. - * @enum {string} - */ -goog.ui.editor.AbstractDialog.EventType = { - // This event is fired after the dialog is hidden, no matter if it was closed - // via OK or Cancel or is being disposed without being hidden first. - AFTER_HIDE: 'afterhide', - // Either the cancel or OK events can be canceled via preventDefault or by - // returning false from their handlers to stop the dialog from closing. - CANCEL: 'cancel', - OK: 'ok' -}; - - -// *** Inner helper class *************************************************** // - - - -/** - * A builder class for the dialog control. All methods except build return this. - * @param {goog.ui.editor.AbstractDialog} editorDialog Editor dialog object - * that will wrap the wrapped dialog object this builder will create. - * @constructor - */ -goog.ui.editor.AbstractDialog.Builder = function(editorDialog) { - // We require the editor dialog to be passed in so that the builder can set up - // ok/cancel listeners by default, making it easier for most dialogs. - this.editorDialog_ = editorDialog; - this.wrappedDialog_ = new goog.ui.Dialog('', true, this.editorDialog_.dom); - this.buttonSet_ = new goog.ui.Dialog.ButtonSet(this.editorDialog_.dom); - this.buttonHandlers_ = {}; - this.addClassName(goog.getCssName('tr-dialog')); -}; - - -/** - * Sets the title of the dialog. - * @param {string} title Title HTML (escaped). - * @return {goog.ui.editor.AbstractDialog.Builder} This. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.setTitle = function(title) { - this.wrappedDialog_.setTitle(title); - return this; -}; - - -/** - * Adds an OK button to the dialog. Clicking this button will cause {@link - * handleOk} to run, subsequently dispatching an OK event. - * @param {string=} opt_label The caption for the button, if not "OK". - * @return {goog.ui.editor.AbstractDialog.Builder} This. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.addOkButton = - function(opt_label) { - var key = goog.ui.Dialog.DefaultButtonKeys.OK; - /** @desc Label for an OK button in an editor dialog. */ - var MSG_TR_DIALOG_OK = goog.getMsg('OK'); - // True means this is the default/OK button. - this.buttonSet_.set(key, opt_label || MSG_TR_DIALOG_OK, true); - this.buttonHandlers_[key] = goog.bind(this.editorDialog_.handleOk, - this.editorDialog_); - return this; -}; - - -/** - * Adds a Cancel button to the dialog. Clicking this button will cause {@link - * handleCancel} to run, subsequently dispatching a CANCEL event. - * @param {string=} opt_label The caption for the button, if not "Cancel". - * @return {goog.ui.editor.AbstractDialog.Builder} This. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.addCancelButton = - function(opt_label) { - var key = goog.ui.Dialog.DefaultButtonKeys.CANCEL; - /** @desc Label for a cancel button in an editor dialog. */ - var MSG_TR_DIALOG_CANCEL = goog.getMsg('Cancel'); - // False means it's not the OK button, true means it's the Cancel button. - this.buttonSet_.set(key, opt_label || MSG_TR_DIALOG_CANCEL, false, true); - this.buttonHandlers_[key] = goog.bind(this.editorDialog_.handleCancel, - this.editorDialog_); - return this; -}; - - -/** - * Adds a custom button to the dialog. - * @param {string} label The caption for the button. - * @param {function(goog.ui.Dialog.EventType):*} handler Function called when - * the button is clicked. It is recommended that this function be a method - * in the concrete subclass of AbstractDialog using this Builder, and that - * it dispatch an event (see {@link handleOk}). - * @param {string=} opt_buttonId Identifier to be used to access the button when - * calling AbstractDialog.getButtonElement(). - * @return {goog.ui.editor.AbstractDialog.Builder} This. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.addButton = - function(label, handler, opt_buttonId) { - // We don't care what the key is, just that we can match the button with the - // handler function later. - var key = opt_buttonId || goog.string.createUniqueString(); - this.buttonSet_.set(key, label); - this.buttonHandlers_[key] = handler; - return this; -}; - - -/** - * Puts a CSS class on the dialog's main element. - * @param {string} className The class to add. - * @return {goog.ui.editor.AbstractDialog.Builder} This. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.addClassName = - function(className) { - goog.dom.classes.add(this.wrappedDialog_.getDialogElement(), className); - return this; -}; - - -/** - * Sets the content element of the dialog. - * @param {Element} contentElem An element for the main body. - * @return {goog.ui.editor.AbstractDialog.Builder} This. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.setContent = - function(contentElem) { - goog.dom.appendChild(this.wrappedDialog_.getContentElement(), contentElem); - return this; -}; - - -/** - * Builds the wrapped dialog control. May only be called once, after which - * no more methods may be called on this builder. - * @return {goog.ui.Dialog} The wrapped dialog control. - */ -goog.ui.editor.AbstractDialog.Builder.prototype.build = function() { - if (this.buttonSet_.isEmpty()) { - // If caller didn't set any buttons, add an OK and Cancel button by default. - this.addOkButton(); - this.addCancelButton(); - } - this.wrappedDialog_.setButtonSet(this.buttonSet_); - - var handlers = this.buttonHandlers_; - this.buttonHandlers_ = null; - this.wrappedDialog_.addEventListener(goog.ui.Dialog.EventType.SELECT, - // Listen for the SELECT event, which means a button was clicked, and - // call the handler associated with that button via the key property. - function(e) { - if (handlers[e.key]) { - return handlers[e.key](e); - } - }); - - // All editor dialogs are modal. - this.wrappedDialog_.setModal(true); - - var dialog = this.wrappedDialog_; - this.wrappedDialog_ = null; - return dialog; -}; - - -/** - * Editor dialog that will wrap the wrapped dialog this builder will create. - * @type {goog.ui.editor.AbstractDialog} - * @private - */ -goog.ui.editor.AbstractDialog.Builder.prototype.editorDialog_; - - -/** - * wrapped dialog control being built by this builder. - * @type {goog.ui.Dialog} - * @private - */ -goog.ui.editor.AbstractDialog.Builder.prototype.wrappedDialog_; - - -/** - * Set of buttons to be added to the wrapped dialog control. - * @type {goog.ui.Dialog.ButtonSet} - * @private - */ -goog.ui.editor.AbstractDialog.Builder.prototype.buttonSet_; - - -/** - * Map from keys that will be returned in the wrapped dialog SELECT events to - * handler functions to be called to handle those events. - * @type {Object} - * @private - */ -goog.ui.editor.AbstractDialog.Builder.prototype.buttonHandlers_; - - -// *** Protected interface ************************************************** // - - -/** - * The DOM helper for the parent document. - * @type {goog.dom.DomHelper} - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.dom; - - -/** - * Creates and returns the goog.ui.Dialog control that is being wrapped - * by this object. - * @return {goog.ui.Dialog} Created Dialog control. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.createDialogControl = - goog.abstractMethod; - - -/** - * Returns the HTML Button element for the OK button in this dialog. - * @return {Element} The button element if found, else null. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.getOkButtonElement = function() { - return this.getButtonElement(goog.ui.Dialog.DefaultButtonKeys.OK); -}; - - -/** - * Returns the HTML Button element for the Cancel button in this dialog. - * @return {Element} The button element if found, else null. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.getCancelButtonElement = function() { - return this.getButtonElement(goog.ui.Dialog.DefaultButtonKeys.CANCEL); -}; - - -/** - * Returns the HTML Button element for the button added to this dialog with - * the given button id. - * @param {string} buttonId The id of the button to get. - * @return {Element} The button element if found, else null. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.getButtonElement = function(buttonId) { - return this.dialogInternal_.getButtonSet().getButton(buttonId); -}; - - -/** - * Creates and returns the event object to be used when dispatching the OK - * event to listeners, or returns null to prevent the dialog from closing. - * Subclasses should override this to return their own subclass of - * goog.events.Event that includes all data a plugin would need from the dialog. - * @param {goog.events.Event} e The event object dispatched by the wrapped - * dialog. - * @return {goog.events.Event} The event object to be used when dispatching the - * OK event to listeners. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.createOkEvent = goog.abstractMethod; - - -/** - * Handles the event dispatched by the wrapped dialog control when the user - * clicks the OK button. Attempts to create the OK event object and dispatches - * it if successful. - * @param {goog.ui.Dialog.Event} e wrapped dialog OK event object. - * @return {boolean} Whether the default action (closing the dialog) should - * still be executed. This will be false if the OK event could not be - * created to be dispatched, or if any listener to that event returs false - * or calls preventDefault. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.handleOk = function(e) { - var eventObj = this.createOkEvent(e); - if (eventObj) { - return this.dispatchEvent(eventObj); - } else { - return false; - } -}; - - -/** - * Handles the event dispatched by the wrapped dialog control when the user - * clicks the Cancel button. Simply dispatches a CANCEL event. - * @return {boolean} Returns false if any of the handlers called prefentDefault - * on the event or returned false themselves. - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.handleCancel = function() { - return this.dispatchEvent(goog.ui.editor.AbstractDialog.EventType.CANCEL); -}; - - -/** - * Disposes of the dialog. If the dialog is open, it will be hidden and - * AFTER_HIDE will be dispatched. - * @override - * @protected - */ -goog.ui.editor.AbstractDialog.prototype.disposeInternal = function() { - if (this.dialogInternal_) { - this.hide(); - - this.dialogInternal_.dispose(); - this.dialogInternal_ = null; - } - - goog.ui.editor.AbstractDialog.superClass_.disposeInternal.call(this); -}; - - -// *** Private implementation *********************************************** // - - -/** - * The wrapped dialog widget. - * @type {goog.ui.Dialog} - * @private - */ -goog.ui.editor.AbstractDialog.prototype.dialogInternal_; - - -/** - * Cleans up after the dialog is hidden and fires the AFTER_HIDE event. Should - * be a listener for the wrapped dialog's AFTER_HIDE event. - * @private - */ -goog.ui.editor.AbstractDialog.prototype.handleAfterHide_ = function() { - this.dispatchEvent(goog.ui.editor.AbstractDialog.EventType.AFTER_HIDE); -}; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/abstractdialog_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/abstractdialog_test.html.svn-base deleted file mode 100644 index 97aa447..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/abstractdialog_test.html.svn-base +++ /dev/null @@ -1,473 +0,0 @@ -<!DOCTYPE html> -<!-- - All Rights Reserved. - - @author nicksantos@google.com (Nick Santos) - @author marcosalmeida@google.com (Marcos Almeida) ---> -<html> -<!-- -Copyright 2008 The Closure Library Authors. All Rights Reserved. - -Use of this source code is governed by the Apache License, Version 2.0. -See the COPYING file for details. ---> -<head> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<title>Closure Unit Tests - goog.ui.editor.AbstractDialog</title> -<script src="../../base.js"></script> -<script> - goog.require('goog.dom.DomHelper'); - goog.require('goog.events.EventHandler'); - goog.require('goog.events.KeyCodes'); - goog.require('goog.testing.MockControl'); - goog.require('goog.testing.events'); - goog.require('goog.testing.jsunit'); - goog.require('goog.testing.mockmatchers.ArgumentMatcher'); - goog.require('goog.ui.editor.AbstractDialog'); - goog.require('goog.ui.editor.AbstractDialog.Builder'); - goog.require('goog.ui.editor.AbstractDialog.EventType'); - goog.require('goog.userAgent'); -</script> -</head> -<body> -<script> - -function shouldRunTests() { - // Test disabled in IE7 due to flakiness. See b/4269021. - return !(goog.userAgent.IE && goog.userAgent.isVersion('7')); -} - -var dialog; -var builder; - -var mockCtrl; -var mockAfterHideHandler; -var mockOkHandler; -var mockCancelHandler; -var mockCustomButtonHandler; - -var CUSTOM_EVENT = 'customEvent'; -var CUSTOM_BUTTON_ID = 'customButton'; - - -function setUp() { - mockCtrl = new goog.testing.MockControl(); - mockAfterHideHandler = mockCtrl.createLooseMock(goog.events.EventHandler); - mockOkHandler = mockCtrl.createLooseMock(goog.events.EventHandler); - mockCancelHandler = mockCtrl.createLooseMock(goog.events.EventHandler); - mockCustomButtonHandler = mockCtrl.createLooseMock(goog.events.EventHandler); -} - -function tearDown() { - if (dialog) { - mockAfterHideHandler.$setIgnoreUnexpectedCalls(true); - dialog.dispose(); - } -} - -/** - * Sets up the mock event handler to expect an AFTER_HIDE event. - */ -function expectAfterHide() { - mockAfterHideHandler.handleEvent( - new goog.testing.mockmatchers.ArgumentMatcher(function(arg) { - return arg.type == - goog.ui.editor.AbstractDialog.EventType.AFTER_HIDE; - })); -} - -/** - * Sets up the mock event handler to expect an OK event. - */ -function expectOk() { - mockOkHandler.handleEvent(new goog.testing.mockmatchers.ArgumentMatcher( - function(arg) { - return arg.type == goog.ui.editor.AbstractDialog.EventType.OK; - })); -} - -/** - * Sets up the mock event handler to expect an OK event and to call - * preventDefault when handling it. - */ -function expectOkPreventDefault() { - expectOk(); - mockOkHandler.$does(function(e) { - e.preventDefault(); - }); -} - -/** - * Sets up the mock event handler to expect an OK event and to return false - * when handling it. - */ -function expectOkReturnFalse() { - expectOk(); - mockOkHandler.$returns(false); -} - -/** - * Sets up the mock event handler to expect a CANCEL event. - */ -function expectCancel() { - mockCancelHandler.handleEvent(new goog.testing.mockmatchers.ArgumentMatcher( - function(arg) { - return arg.type == goog.ui.editor.AbstractDialog.EventType.CANCEL; - })); -} - -/** - * Sets up the mock event handler to expect a custom button event. - */ -function expectCustomButton() { - mockCustomButtonHandler.handleEvent( - new goog.testing.mockmatchers.ArgumentMatcher(function(arg) { - return arg.type == CUSTOM_EVENT; - })); -} - -/** - * Helper to create the dialog being tested in each test. Since NewDialog is - * abstract, needs to add a concrete version of any abstract methods. Also - * creates up the global builder variable which should be set up after the call - * to this method. - * @return {goog.ui.editor.AbstractDialog} The dialog. - */ -function createTestDialog() { - var dialog = new goog.ui.editor.AbstractDialog(new goog.dom.DomHelper()); - builder = new goog.ui.editor.AbstractDialog.Builder(dialog); - dialog.createDialogControl = function() { - return builder.build(); - }; - dialog.createOkEvent = function(e) { - return new goog.events.Event(goog.ui.editor.AbstractDialog.EventType.OK); - }; - dialog.addEventListener(goog.ui.editor.AbstractDialog.EventType.AFTER_HIDE, - mockAfterHideHandler); - dialog.addEventListener(goog.ui.editor.AbstractDialog.EventType.OK, - mockOkHandler); - dialog.addEventListener(goog.ui.editor.AbstractDialog.EventType.CANCEL, - mockCancelHandler); - dialog.addEventListener(CUSTOM_EVENT, mockCustomButtonHandler); - return dialog; -} - - -/** - * Asserts that the given dialog is open. - * @param {string} msg Message to be printed in case of failure. - * @param {goog.ui.editor.AbstractDialog} dialog Dialog to be tested. - */ -function assertOpen(msg, dialog) { - assertTrue(msg + ' [AbstractDialog.isOpen()]', dialog && dialog.isOpen()); -} - -/** - * Asserts that the given dialog is closed. - * @param {string} msg Message to be printed in case of failure. - * @param {goog.ui.editor.AbstractDialog} dialog Dialog to be tested. - */ -function assertNotOpen(msg, dialog) { - assertFalse(msg + ' [AbstractDialog.isOpen()]', dialog && dialog.isOpen()); -} - - -/** - * Tests that if you create a dialog and hide it without having shown it, no - * errors occur. - */ -function testCreateAndHide() { - dialog = createTestDialog(); - mockCtrl.$replayAll(); - - assertNotOpen('Dialog should not be open after creation', dialog); - dialog.hide(); - assertNotOpen('Dialog should not be open after hide()', dialog); - - mockCtrl.$verifyAll(); // Verifies AFTER_HIDE was not dispatched. -} - -/** - * Tests that when you show and hide a dialog the flags indicating open are - * correct and the AFTER_HIDE event is dispatched (and no errors happen). - */ -function testShowAndHide() { - dialog = createTestDialog(); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - assertNotOpen('Dialog should not be open before show()', dialog); - dialog.show(); - assertOpen('Dialog should be open after show()', dialog); - dialog.hide(); - assertNotOpen('Dialog should not be open after hide()', dialog); - - mockCtrl.$verifyAll(); // Verifies AFTER_HIDE was dispatched. -} - -/** - * Tests that when you show and dispose a dialog (without hiding it first) the - * flags indicating open are correct and the AFTER_HIDE event is dispatched (and - * no errors happen). - */ -function testShowAndDispose() { - dialog = createTestDialog(); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - assertNotOpen('Dialog should not be open before show()', dialog); - dialog.show(); - assertOpen('Dialog should be open after show()', dialog); - dialog.dispose(); - assertNotOpen('Dialog should not be open after dispose()', dialog); - - mockCtrl.$verifyAll(); // Verifies AFTER_HIDE was dispatched. -} - -/** - * Tests that when you dispose a dialog (without ever showing it first) the - * flags indicating open are correct and the AFTER_HIDE event is never - * dispatched (and no errors happen). - */ -function testDisposeWithoutShow() { - dialog = createTestDialog(); - mockCtrl.$replayAll(); - - assertNotOpen('Dialog should not be open before dispose()', dialog); - dialog.dispose(); - assertNotOpen('Dialog should not be open after dispose()', dialog); - - mockCtrl.$verifyAll(); // Verifies AFTER_HIDE was NOT dispatched. -} - -/** - * Tests that labels set in the builder can be found in the resulting dialog's - * HTML. - */ -function testBasicLayout() { - dialog = createTestDialog(); - mockCtrl.$replayAll(); - - // create some dialog content - var content = goog.dom.createDom('div', null, 'The Content'); - builder.setTitle('The Title') - .setContent(content) - .addOkButton('The OK Button') - .addCancelButton() - .addButton('The Apply Button', goog.nullFunction) - .addClassName('myClassName'); - dialog.show(); - - var dialogElem = dialog.dialogInternal_.getElement(); - var html = dialogElem.innerHTML; - // TODO(user): This is really insufficient. If the title and content - // were swapped this test would still pass! - assertContains('Dialog html should contain title', '>The Title<', html); - assertContains('Dialog html should contain content', '>The Content<', html); - assertContains('Dialog html should contain custom OK button label', - '>The OK Button<', - html); - assertContains('Dialog html should contain default Cancel button label', - '>Cancel<', - html); - assertContains('Dialog html should contain custom button label', - '>The Apply Button<', - html); - assertTrue('Dialog should have default Closure class', - goog.dom.classes.has(dialogElem, 'modal-dialog')); - assertTrue('Dialog should have our custom class', - goog.dom.classes.has(dialogElem, 'myClassName')); - - mockCtrl.$verifyAll(); -} - - -/** - * Tests that clicking the OK button dispatches the OK event and closes the - * dialog (dispatching the AFTER_HIDE event too). - */ -function testOk() { - dialog = createTestDialog(); - expectOk(dialog); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - assertNotOpen('Dialog should not be open after clicking OK', dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that hitting the enter key dispatches the OK event and closes the - * dialog (dispatching the AFTER_HIDE event too). - */ -function testEnter() { - dialog = createTestDialog(); - expectOk(dialog); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - goog.testing.events.fireKeySequence(dialog.dialogInternal_.getElement(), - goog.events.KeyCodes.ENTER); - assertNotOpen('Dialog should not be open after hitting enter', dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that clicking the Cancel button dispatches the CANCEL event and closes - * the dialog (dispatching the AFTER_HIDE event too). - */ -function testCancel() { - dialog = createTestDialog(); - expectCancel(dialog); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - builder.addCancelButton('My Cancel Button'); - - dialog.show(); - goog.testing.events.fireClickSequence(dialog.getCancelButtonElement()); - assertNotOpen('Dialog should not be open after clicking Cancel', dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that hitting the escape key dispatches the CANCEL event and closes - * the dialog (dispatching the AFTER_HIDE event too). - */ -function testEscape() { - dialog = createTestDialog(); - expectCancel(dialog); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - goog.testing.events.fireKeySequence(dialog.dialogInternal_.getElement(), - goog.events.KeyCodes.ESC); - assertNotOpen('Dialog should not be open after hitting escape', dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that clicking the custom button dispatches the custom event and closes - * the dialog (dispatching the AFTER_HIDE event too). - */ -function testCustomButton() { - dialog = createTestDialog(); - expectCustomButton(dialog); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - builder.addButton('My Custom Button', - function() { - dialog.dispatchEvent(CUSTOM_EVENT) - }, - CUSTOM_BUTTON_ID); - - dialog.show(); - goog.testing.events.fireClickSequence( - dialog.getButtonElement(CUSTOM_BUTTON_ID)); - assertNotOpen('Dialog should not be open after clicking custom button', - dialog); - - mockCtrl.$verifyAll(); -} - - -/** - * Tests that if the OK handler calls preventDefault, the dialog doesn't close. - */ -function testOkPreventDefault() { - dialog = createTestDialog(); - expectOkPreventDefault(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - assertOpen('Dialog should not be closed because preventDefault was called', - dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that if the OK handler returns false, the dialog doesn't close. - */ -function testOkReturnFalse() { - dialog = createTestDialog(); - expectOkReturnFalse(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - assertOpen('Dialog should not be closed because handler returned false', - dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that if creating the OK event fails, no event is dispatched and the - * dialog doesn't close. - */ -function testCreateOkEventFail() { - dialog = createTestDialog(); - dialog.createOkEvent = function() { // Override our mock createOkEvent. - return null; - }; - mockCtrl.$replayAll(); - - dialog.show(); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - assertOpen('Dialog should not be closed because OK event creation failed', - dialog); - - mockCtrl.$verifyAll(); // Verifies that no event was dispatched. -} - - -/** - * Tests that processOkAndClose() dispatches the OK event and closes the - * dialog (dispatching the AFTER_HIDE event too). - */ -function testProcessOkAndClose() { - dialog = createTestDialog(); - expectOk(dialog); - expectAfterHide(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - dialog.processOkAndClose(); - assertNotOpen('Dialog should not be open after processOkAndClose()', dialog); - - mockCtrl.$verifyAll(); -} - -/** - * Tests that if the OK handler triggered by processOkAndClose calls - * preventDefault, the dialog doesn't close (in the old implementation this - * failed due to not great design, so this is sort of a regression test). - */ -function testProcessOkAndClosePreventDefault() { - dialog = createTestDialog(); - expectOkPreventDefault(dialog); - mockCtrl.$replayAll(); - - dialog.show(); - dialog.processOkAndClose(); - assertOpen('Dialog should not be closed because preventDefault was called', - dialog); - - mockCtrl.$verifyAll(); -} - -</script> -</body> -</html> diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/bubble.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/bubble.js.svn-base deleted file mode 100644 index 0928948..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/bubble.js.svn-base +++ /dev/null @@ -1,520 +0,0 @@ -// Copyright 2005 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 Bubble component - handles display, hiding, etc. of the - * actual bubble UI. - * - * This is used exclusively by code within the editor package, and should not - * be used directly. - * - * @author robbyw@google.com (Robby Walker) - * @author tildahl@google.com (Michael Tildahl) - */ - -goog.provide('goog.ui.editor.Bubble'); - -goog.require('goog.debug.Logger'); -goog.require('goog.dom'); -goog.require('goog.dom.ViewportSizeMonitor'); -goog.require('goog.editor.style'); -goog.require('goog.events'); -goog.require('goog.events.EventHandler'); -goog.require('goog.events.EventType'); -goog.require('goog.positioning'); -goog.require('goog.string'); -goog.require('goog.style'); -goog.require('goog.ui.Component.EventType'); -goog.require('goog.ui.PopupBase'); -goog.require('goog.ui.PopupBase.EventType'); -goog.require('goog.userAgent'); - - - -/** - * Property bubble UI element. - * @param {Element} parent The parent element for this bubble. - * @param {number} zIndex The z index to draw the bubble at. - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.ui.editor.Bubble = function(parent, zIndex) { - goog.base(this); - - /** - * Dom helper for the document the bubble should be shown in. - * @type {!goog.dom.DomHelper} - * @private - */ - this.dom_ = goog.dom.getDomHelper(parent); - - /** - * Event handler for this bubble. - * @type {goog.events.EventHandler} - * @private - */ - this.eventHandler_ = new goog.events.EventHandler(this); - - /** - * Object that monitors the application window for size changes. - * @type {goog.dom.ViewportSizeMonitor} - * @private - */ - this.viewPortSizeMonitor_ = new goog.dom.ViewportSizeMonitor( - this.dom_.getWindow()); - - /** - * Maps panel ids to panels. - * @type {Object.<goog.ui.editor.Bubble.Panel_>} - * @private - */ - this.panels_ = {}; - - /** - * Container element for the entire bubble. This may contain elements related - * to look and feel or styling of the bubble. - * @type {Element} - * @private - */ - this.bubbleContainer_ = - this.dom_.createDom(goog.dom.TagName.DIV, - {'className': goog.ui.editor.Bubble.BUBBLE_CLASSNAME}); - - goog.style.showElement(this.bubbleContainer_, false); - goog.dom.appendChild(parent, this.bubbleContainer_); - goog.style.setStyle(this.bubbleContainer_, 'zIndex', zIndex); - - /** - * Container element for the bubble panels - this should be some inner element - * within (or equal to) bubbleContainer. - * @type {Element} - * @private - */ - this.bubbleContents_ = this.createBubbleDom(this.dom_, this.bubbleContainer_); - - /** - * Element showing the close box. - * @type {!Element} - * @private - */ - this.closeBox_ = this.dom_.createDom(goog.dom.TagName.DIV, { - 'className': goog.getCssName('tr_bubble_closebox'), - 'innerHTML': ' ' - }); - this.bubbleContents_.appendChild(this.closeBox_); - - // We make bubbles unselectable so that clicking on them does not steal focus - // or move the cursor away from the element the bubble is attached to. - goog.editor.style.makeUnselectable(this.bubbleContainer_, this.eventHandler_); - - /** - * Popup that controls showing and hiding the bubble at the appropriate - * position. - * @type {goog.ui.PopupBase} - * @private - */ - this.popup_ = new goog.ui.PopupBase(this.bubbleContainer_); -}; -goog.inherits(goog.ui.editor.Bubble, goog.events.EventTarget); - - -/** - * The css class name of the bubble container element. - * @type {string} - */ -goog.ui.editor.Bubble.BUBBLE_CLASSNAME = goog.getCssName('tr_bubble'); - - -/** - * Creates and adds DOM for the bubble UI to the given container. This default - * implementation just returns the container itself. - * @param {!goog.dom.DomHelper} dom DOM helper to use. - * @param {!Element} container Element to add the new elements to. - * @return {!Element} The element where bubble content should be added. - * @protected - */ -goog.ui.editor.Bubble.prototype.createBubbleDom = function(dom, container) { - return container; -}; - - -/** - * A logger for goog.ui.editor.Bubble. - * @type {goog.debug.Logger} - * @protected - */ -goog.ui.editor.Bubble.prototype.logger = - goog.debug.Logger.getLogger('goog.ui.editor.Bubble'); - - -/** @override */ -goog.ui.editor.Bubble.prototype.disposeInternal = function() { - goog.base(this, 'disposeInternal'); - - goog.dom.removeNode(this.bubbleContainer_); - this.bubbleContainer_ = null; - - this.eventHandler_.dispose(); - this.eventHandler_ = null; - - this.viewPortSizeMonitor_.dispose(); - this.viewPortSizeMonitor_ = null; -}; - - -/** - * @return {Element} The element that where the bubble's contents go. - * @protected - */ -goog.ui.editor.Bubble.prototype.getContentElement = function() { - return this.bubbleContents_; -}; - - -/** - * @return {Element} The element that contains the bubble. - * @protected - */ -goog.ui.editor.Bubble.prototype.getContainerElement = function() { - return this.bubbleContainer_; -}; - - -/** - * @return {goog.events.EventHandler} The event handler. - * @protected - */ -goog.ui.editor.Bubble.prototype.getEventHandler = function() { - return this.eventHandler_; -}; - - -/** - * Handles user resizing of window. - * @private - */ -goog.ui.editor.Bubble.prototype.handleWindowResize_ = function() { - if (this.isVisible()) { - this.reposition(); - } -}; - - -/** - * Returns whether there is already a panel of the given type. - * @param {string} type Type of panel to check. - * @return {boolean} Whether there is already a panel of the given type. - */ -goog.ui.editor.Bubble.prototype.hasPanelOfType = function(type) { - return goog.object.some(this.panels_, function(panel) { - return panel.type == type; - }); -}; - - -/** - * Adds a panel to the bubble. - * @param {string} type The type of bubble panel this is. Should usually be - * the same as the tagName of the targetElement. This ensures multiple - * bubble panels don't appear for the same element. - * @param {string} title The title of the panel. - * @param {Element} targetElement The target element of the bubble. - * @param {function(Element): void} contentFn Function that when called with - * a container element, will add relevant panel content to it. - * @param {boolean=} opt_preferTopPosition Whether to prefer placing the bubble - * above the element instead of below it. Defaults to preferring below. - * If any panel prefers the top position, the top position is used. - * @return {string} The id of the panel. - */ -goog.ui.editor.Bubble.prototype.addPanel = function(type, title, targetElement, - contentFn, opt_preferTopPosition) { - var id = goog.string.createUniqueString(); - var panel = new goog.ui.editor.Bubble.Panel_(this.dom_, id, type, title, - targetElement, !opt_preferTopPosition); - this.panels_[id] = panel; - - // Insert the panel in string order of type. Technically we could use binary - // search here but n is really small (probably 0 - 2) so it's not worth it. - // The last child of bubbleContents_ is the close box so we take care not - // to treat it as a panel element, and we also ensure it stays as the last - // element. The intention here is not to create any artificial order, but - // just to ensure that it is always consistent. - var nextElement; - for (var i = 0, len = this.bubbleContents_.childNodes.length - 1; i < len; - i++) { - var otherChild = this.bubbleContents_.childNodes[i]; - var otherPanel = this.panels_[otherChild.id]; - if (otherPanel.type > type) { - nextElement = otherChild; - break; - } - } - goog.dom.insertSiblingBefore(panel.element, - nextElement || this.bubbleContents_.lastChild); - - contentFn(panel.getContentElement()); - goog.editor.style.makeUnselectable(panel.element, this.eventHandler_); - - var numPanels = goog.object.getCount(this.panels_); - if (numPanels == 1) { - this.openBubble_(); - } else if (numPanels == 2) { - goog.dom.classes.add(this.bubbleContainer_, - goog.getCssName('tr_multi_bubble')); - } - this.reposition(); - - return id; -}; - - -/** - * Removes the panel with the given id. - * @param {string} id The id of the panel. - */ -goog.ui.editor.Bubble.prototype.removePanel = function(id) { - var panel = this.panels_[id]; - goog.dom.removeNode(panel.element); - delete this.panels_[id]; - - var numPanels = goog.object.getCount(this.panels_); - if (numPanels <= 1) { - goog.dom.classes.remove(this.bubbleContainer_, - goog.getCssName('tr_multi_bubble')); - } - - if (numPanels == 0) { - this.closeBubble_(); - } else { - this.reposition(); - } -}; - - -/** - * Opens the bubble. - * @private - */ -goog.ui.editor.Bubble.prototype.openBubble_ = function() { - this.eventHandler_. - listen(this.closeBox_, goog.events.EventType.CLICK, - this.closeBubble_). - listen(this.viewPortSizeMonitor_, - goog.events.EventType.RESIZE, this.handleWindowResize_). - listen(this.popup_, goog.ui.PopupBase.EventType.HIDE, - this.handlePopupHide); - - this.popup_.setVisible(true); - this.reposition(); -}; - - -/** - * Closes the bubble. - * @private - */ -goog.ui.editor.Bubble.prototype.closeBubble_ = function() { - this.popup_.setVisible(false); -}; - - -/** - * Handles the popup's hide event by removing all panels and dispatching a - * HIDE event. - * @protected - */ -goog.ui.editor.Bubble.prototype.handlePopupHide = function() { - // Remove the panel elements. - for (var panelId in this.panels_) { - goog.dom.removeNode(this.panels_[panelId].element); - } - - // Update the state to reflect no panels. - this.panels_ = {}; - goog.dom.classes.remove(this.bubbleContainer_, - goog.getCssName('tr_multi_bubble')); - - this.eventHandler_.removeAll(); - this.dispatchEvent(goog.ui.Component.EventType.HIDE); -}; - - -/** - * Returns the visibility of the bubble. - * @return {boolean} True if visible false if not. - */ -goog.ui.editor.Bubble.prototype.isVisible = function() { - return this.popup_.isVisible(); -}; - - -/** - * The vertical clearance in pixels between the bottom of the targetElement - * and the edge of the bubble. - * @type {number} - * @private - */ -goog.ui.editor.Bubble.VERTICAL_CLEARANCE_ = goog.userAgent.IE ? 4 : 2; - - -/** - * Bubble's margin box to be passed to goog.positioning. - * @type {goog.math.Box} - * @private - */ -goog.ui.editor.Bubble.MARGIN_BOX_ = new goog.math.Box( - goog.ui.editor.Bubble.VERTICAL_CLEARANCE_, 0, - goog.ui.editor.Bubble.VERTICAL_CLEARANCE_, 0); - - -/** - * Positions and displays this bubble below its targetElement. Assumes that - * the bubbleContainer is already contained in the document object it applies - * to. - */ -goog.ui.editor.Bubble.prototype.reposition = function() { - var targetElement = null; - var preferBottomPosition = true; - for (var panelId in this.panels_) { - var panel = this.panels_[panelId]; - // We don't care which targetElement we get, so we just take the last one. - targetElement = panel.targetElement; - preferBottomPosition = preferBottomPosition && panel.preferBottomPosition; - } - var status = goog.positioning.OverflowStatus.FAILED; - - // Fix for bug when bubbleContainer and targetElement have - // opposite directionality, the bubble should anchor to the END of - // the targetElement instead of START. - var reverseLayout = (goog.style.isRightToLeft(this.bubbleContainer_) != - goog.style.isRightToLeft(targetElement)); - - // Try to put the bubble at the bottom of the target unless the plugin has - // requested otherwise. - if (preferBottomPosition) { - status = this.positionAtAnchor_(reverseLayout ? - goog.positioning.Corner.BOTTOM_END : - goog.positioning.Corner.BOTTOM_START, - goog.positioning.Corner.TOP_START, - goog.positioning.Overflow.ADJUST_X | goog.positioning.Overflow.FAIL_Y); - } - - if (status & goog.positioning.OverflowStatus.FAILED) { - // Try to put it at the top of the target if there is not enough - // space at the bottom. - status = this.positionAtAnchor_(reverseLayout ? - goog.positioning.Corner.TOP_END : goog.positioning.Corner.TOP_START, - goog.positioning.Corner.BOTTOM_START, - goog.positioning.Overflow.ADJUST_X | goog.positioning.Overflow.FAIL_Y); - } - - if (status & goog.positioning.OverflowStatus.FAILED) { - // Put it at the bottom again with adjustment if there is no - // enough space at the top. - status = this.positionAtAnchor_(reverseLayout ? - goog.positioning.Corner.BOTTOM_END : - goog.positioning.Corner.BOTTOM_START, - goog.positioning.Corner.TOP_START, - goog.positioning.Overflow.ADJUST_X | - goog.positioning.Overflow.ADJUST_Y); - if (status & goog.positioning.OverflowStatus.FAILED) { - this.logger.warning( - 'reposition(): positionAtAnchor() failed with ' + status); - } - } -}; - - -/** - * A helper for reposition() - positions the bubble in regards to the position - * of the elements the bubble is attached to. - * @param {goog.positioning.Corner} targetCorner The corner of - * the target element. - * @param {goog.positioning.Corner} bubbleCorner The corner of the bubble. - * @param {number} overflow Overflow handling mode bitmap, - * {@see goog.positioning.Overflow}. - * @return {number} Status bitmap, {@see goog.positioning.OverflowStatus}. - * @private - */ -goog.ui.editor.Bubble.prototype.positionAtAnchor_ = function( - targetCorner, bubbleCorner, overflow) { - var targetElement = null; - for (var panelId in this.panels_) { - // For now, we use the outermost element. This assumes the multiple - // elements this panel is showing for contain each other - in the event - // that is not generally the case this may need to be updated to pick - // the lowest or highest element depending on targetCorner. - var candidate = this.panels_[panelId].targetElement; - if (!targetElement || goog.dom.contains(candidate, targetElement)) { - targetElement = this.panels_[panelId].targetElement; - } - } - return goog.positioning.positionAtAnchor( - targetElement, targetCorner, this.bubbleContainer_, - bubbleCorner, null, goog.ui.editor.Bubble.MARGIN_BOX_, overflow); -}; - - - -/** - * Private class used to describe a bubble panel. - * @param {goog.dom.DomHelper} dom DOM helper used to create the panel. - * @param {string} id ID of the panel. - * @param {string} type Type of the panel. - * @param {string} title Title of the panel. - * @param {Element} targetElement Element the panel is showing for. - * @param {boolean} preferBottomPosition Whether this panel prefers to show - * below the target element. - * @constructor - * @private - */ -goog.ui.editor.Bubble.Panel_ = function(dom, id, type, title, targetElement, - preferBottomPosition) { - /** - * The type of bubble panel. - * @type {string} - */ - this.type = type; - - /** - * The target element of this bubble panel. - * @type {Element} - */ - this.targetElement = targetElement; - - /** - * Whether the panel prefers to be placed below the target element. - * @type {boolean} - */ - this.preferBottomPosition = preferBottomPosition; - - /** - * The element containing this panel. - */ - this.element = dom.createDom(goog.dom.TagName.DIV, - {className: goog.getCssName('tr_bubble_panel'), id: id}, - dom.createDom(goog.dom.TagName.DIV, - {className: goog.getCssName('tr_bubble_panel_title')}, - title + ':'), // TODO(robbyw): Does this work properly in bidi? - dom.createDom(goog.dom.TagName.DIV, - {className: goog.getCssName('tr_bubble_panel_content')})); -}; - - -/** - * @return {Element} The element in the panel where content should go. - */ -goog.ui.editor.Bubble.Panel_.prototype.getContentElement = function() { - return /** @type {Element} */ (this.element.lastChild); -}; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/bubble_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/bubble_test.html.svn-base deleted file mode 100644 index c26c23a..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/bubble_test.html.svn-base +++ /dev/null @@ -1,264 +0,0 @@ -<!DOCTYPE html> -<!-- - All Rights Reserved. - - @author tildahl@google.com (Michael Tildahl) - @author robbyw@google.com (Robby Walker) ---> -<html> -<!-- -Copyright 2008 The Closure Library Authors. All Rights Reserved. - -Use of this source code is governed by the Apache License, Version 2.0. -See the COPYING file for details. ---> -<head> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<title>Closure Unit Tests - goog.ui.editor.Bubble</title> -<script src="../../base.js"></script> -<script> - goog.require('goog.dom'); - goog.require('goog.dom.TagName'); - goog.require('goog.events.BrowserEvent'); - goog.require('goog.events.EventType'); - goog.require('goog.events.KeyCodes'); - goog.require('goog.string'); - goog.require('goog.style'); - goog.require('goog.testing.editor.TestHelper'); - goog.require('goog.testing.editor.FieldMock'); - goog.require('goog.testing.events'); - goog.require('goog.testing.jsunit'); - goog.require('goog.testing.LooseMock'); - goog.require('goog.ui.editor.Bubble'); - goog.require('goog.userAgent'); -</script> -<link rel="stylesheet" type="text/css" href="../../css/editor/bubble.css"> -</head> -<body> - -<div id="field"></div> - -<script> - -var testHelper; -var fieldDiv = goog.dom.getElement('field'); -var bubble; -var link; -var link2; -var panelId; - -function setUpPage() { - var viewportSize = goog.dom.getViewportSize(); - // Some tests depends on enough size of viewport. - if (viewportSize.width < 600 || viewportSize.height < 440) { - window.moveTo(0, 0); - window.resizeTo(640, 480); - } -}; - -function setUp() { - testHelper = new goog.testing.editor.TestHelper(fieldDiv); - testHelper.setUpEditableElement(); - - bubble = new goog.ui.editor.Bubble(document.body, 999); - - fieldDiv.innerHTML = '<a href="http://www.google.com">Google</a>' + - '<a href="http://www.google.com">Google2</a>'; - link = fieldDiv.firstChild; - link2 = fieldDiv.lastChild; - - window.scrollTo(0, 0); - goog.style.setStyle(document.body, 'direction', 'ltr'); - goog.style.setStyle(document.getElementById('field'), 'position', 'static'); -} - -function tearDown() { - if (panelId) { - bubble.removePanel(panelId); - } - testHelper.tearDownEditableElement(); -} - -/** - * This is a helper function for setting up the target element with a - * given direction. - * - * @param {string} dir The direction of the target element, 'ltr' or 'rtl'. - * @param {boolean=} opt_preferTopPosition Whether to prefer placing the bubble - * above the element instead of below it. Defaults to preferring below. - */ -function prepareTargetWithGivenDirection(dir, opt_preferTopPosition) { - goog.style.setStyle(document.body, 'direction', dir); - - fieldDiv.style.direction = dir; - fieldDiv.innerHTML = '<a href="http://www.google.com">Google</a>'; - link = fieldDiv.firstChild; - - panelId = bubble.addPanel('A', 'Link', link, function(el) { - el.innerHTML = '<div style="border:1px solid blue;">B</div>'; - }, opt_preferTopPosition); -} - -/** - * This is a helper function for getting the expected position of the bubble. - * (align to the right or the left of the target element). Align left by - * default and align right if opt_alignRight is true. The expected Y is - * unaffected by alignment. - * - * @param {boolean=} opt_alignRight Sets the expected alignment to be right. - */ -function getExpectedBubblePositionWithGivenAlignment(opt_alignRight) { - var targetPosition = goog.style.getFramedPageOffset(link, window); - var targetWidth = link.offsetWidth; - var bubbleSize = goog.style.getSize(bubble.bubbleContainer_); - var expectedBubbleX = opt_alignRight ? - targetPosition.x + targetWidth - bubbleSize.width : targetPosition.x; - var expectedBubbleY = link.offsetHeight + targetPosition.y + - goog.ui.editor.Bubble.VERTICAL_CLEARANCE_; - - return { - x: expectedBubbleX, - y: expectedBubbleY - }; -} - -function testCreateBubbleWithLinkPanel() { - var id = goog.string.createUniqueString(); - panelId = bubble.addPanel("A", "Link", link, function(container) { - container.innerHTML = '<span id="' + id + '">Test</span>'; - }); - assertNotNull('Bubble should be created', bubble.bubbleContents_); - assertNotNull('Added element should be present', goog.dom.getElement(id)); - assertTrue('Bubble should be visible', bubble.isVisible()); -} - -function testCloseBubble() { - testCreateBubbleWithLinkPanel(); - - var count = 0; - goog.events.listen(bubble, goog.ui.Component.EventType.HIDE, function() { - count++; - }); - - bubble.removePanel(panelId); - panelId = null; - - assertFalse('Bubble should not be visible', bubble.isVisible()); - assertEquals('Hide event should be dispatched', 1, count); -} - -function testCloseBox() { - testCreateBubbleWithLinkPanel(); - - var count = 0; - goog.events.listen(bubble, goog.ui.Component.EventType.HIDE, function() { - count++; - }); - - var closeBox = goog.dom.getElementsByTagNameAndClass( - goog.dom.TagName.DIV, 'tr_bubble_closebox', bubble.bubbleContainer_)[0]; - goog.testing.events.fireClickSequence(closeBox); - panelId = null; - - assertFalse('Bubble should not be visible', bubble.isVisible()); - assertEquals('Hide event should be dispatched', 1, count); -} - -function testViewPortSizeMonitorEvent() { - testCreateBubbleWithLinkPanel(); - - var numCalled = 0; - bubble.reposition = function() { - numCalled++; - }; - - assertNotUndefined('viewPortSizeMonitor_ should not be undefined', - bubble.viewPortSizeMonitor_); - bubble.viewPortSizeMonitor_.dispatchEvent(goog.events.EventType.RESIZE); - - assertEquals('reposition not called', 1, numCalled); -} - -function testBubblePositionPreferTop() { - called = false; - bubble.positionAtAnchor_ = function(targetCorner, bubbleCorner, overflow) { - called = true; - - // Assert that the bubble is positioned below the target. - assertEquals(goog.positioning.Corner.TOP_START, targetCorner); - assertEquals(goog.positioning.Corner.BOTTOM_START, bubbleCorner); - - return goog.positioning.OverflowStatus.NONE; - }; - prepareTargetWithGivenDirection('ltr', true); - assertTrue(called); -} - -function testBubblePosition() { - panelId = bubble.addPanel('A', 'Link', link, goog.nullFunction); - var CLEARANCE = goog.ui.editor.Bubble.VERTICAL_CLEARANCE_; - var bubbleContainer = bubble.bubbleContainer_; - - // The field is at a normal place, alomost the top of the viewport, and - // there is enough space at the bottom of the field. - var targetPos = goog.style.getFramedPageOffset(link, window); - var targetSize = goog.style.getSize(link); - var pos = goog.style.getFramedPageOffset(bubbleContainer); - assertEquals(targetPos.y + targetSize.height + CLEARANCE, pos.y); - assertEquals(targetPos.x, pos.x); - - // Move the target to the bottom of the viewport. - var field = document.getElementById('field'); - var fieldPos = goog.style.getFramedPageOffset(field, window); - fieldPos.y += bubble.dom_.getViewportSize().height - - (targetPos.y + targetSize.height); - goog.style.setStyle(field, 'position', 'absolute'); - goog.style.setPosition(field, fieldPos); - bubble.reposition(); - var bubbleSize = goog.style.getSize(bubbleContainer); - targetPosition = goog.style.getFramedPageOffset(link, window); - pos = goog.style.getFramedPageOffset(bubbleContainer); - assertEquals(targetPosition.y - CLEARANCE - bubbleSize.height, pos.y); -} - -function testBubblePositionRightAligned() { - prepareTargetWithGivenDirection('rtl'); - - var expectedPos = getExpectedBubblePositionWithGivenAlignment(true); - var pos = goog.style.getFramedPageOffset(bubble.bubbleContainer_); - assertEquals(expectedPos.x, pos.x); - assertEquals(expectedPos.y, pos.y); -} - -/** - * Test for bug 1955511, the bubble should align to the right side - * of the target element when the bubble is RTL, regardless of the - * target element's directionality. - */ -function testBubblePositionLeftToRight() { - goog.style.setStyle(bubble.bubbleContainer_, 'direction', 'ltr'); - prepareTargetWithGivenDirection('rtl'); - - var expectedPos = getExpectedBubblePositionWithGivenAlignment(); - var pos = goog.style.getFramedPageOffset(bubble.bubbleContainer_); - assertEquals(expectedPos.x, pos.x); - assertEquals(expectedPos.y, pos.y); -} - -/** - * Test for bug 1955511, the bubble should align to the left side - * of the target element when the bubble is LTR, regardless of the - * target element's directionality. - */ -function testBubblePositionRightToLeft() { - goog.style.setStyle(bubble.bubbleContainer_, 'direction', 'rtl'); - prepareTargetWithGivenDirection('ltr'); - - var expectedPos = getExpectedBubblePositionWithGivenAlignment(true); - var pos = goog.style.getFramedPageOffset(bubble.bubbleContainer_); - assertEquals(expectedPos.x, pos.x); - assertEquals(expectedPos.y, pos.y); -} -</script> -</body> -</html> diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/defaulttoolbar.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/defaulttoolbar.js.svn-base deleted file mode 100644 index 63fd370..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/defaulttoolbar.js.svn-base +++ /dev/null @@ -1,1065 +0,0 @@ -// 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. - -/** - * @fileoverview Factory functions for creating a default editing toolbar. - * - * @author attila@google.com (Attila Bodis) - * @author jparent@google.com (Julie Parent) - * @see ../../demos/editor/editor.html - */ - -goog.provide('goog.ui.editor.DefaultToolbar'); - -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.dom.classes'); -goog.require('goog.editor.Command'); -goog.require('goog.string.StringBuffer'); -goog.require('goog.style'); -goog.require('goog.ui.ControlContent'); -goog.require('goog.ui.editor.ToolbarFactory'); -goog.require('goog.ui.editor.messages'); - -// Font menu creation. - - -/** @desc Font menu item caption for the default sans-serif font. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_NORMAL = goog.getMsg('Normal'); - - -/** @desc Font menu item caption for the default serif font. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_NORMAL_SERIF = - goog.getMsg('Normal / serif'); - - -/** - * Common font descriptors for all locales. Each descriptor has the following - * attributes: - * <ul> - * <li>{@code caption} - Caption to show in the font menu (e.g. 'Tahoma') - * <li>{@code value} - Value for the corresponding 'font-family' CSS style - * (e.g. 'Tahoma, Arial, sans-serif') - * </ul> - * @type {!Array.<{caption:string, value:string}>} - * @private - */ -goog.ui.editor.DefaultToolbar.FONTS_ = [ - { - caption: goog.ui.editor.DefaultToolbar.MSG_FONT_NORMAL, - value: 'arial,sans-serif' - }, - { - caption: goog.ui.editor.DefaultToolbar.MSG_FONT_NORMAL_SERIF, - value: 'times new roman,serif' - }, - {caption: 'Courier New', value: 'courier new,monospace'}, - {caption: 'Georgia', value: 'georgia,serif'}, - {caption: 'Trebuchet', value: 'trebuchet ms,sans-serif'}, - {caption: 'Verdana', value: 'verdana,sans-serif'} -]; - - -/** - * Locale-specific font descriptors. The object is a map of locale strings to - * arrays of font descriptors. - * @type {!Object.<!Array.<{caption:string, value:string}>>} - * @private - */ -goog.ui.editor.DefaultToolbar.I18N_FONTS_ = { - 'ja': [{ - caption: '\uff2d\uff33 \uff30\u30b4\u30b7\u30c3\u30af', - value: 'ms pgothic,sans-serif' - }, { - caption: '\uff2d\uff33 \uff30\u660e\u671d', - value: 'ms pmincho,serif' - }, { - caption: '\uff2d\uff33 \u30b4\u30b7\u30c3\u30af', - value: 'ms gothic,monospace' - }], - 'ko': [{ - caption: '\uad74\ub9bc', - value: 'gulim,sans-serif' - }, { - caption: '\ubc14\ud0d5', - value: 'batang,serif' - }, { - caption: '\uad74\ub9bc\uccb4', - value: 'gulimche,monospace' - }], - 'zh-tw': [{ - caption: '\u65b0\u7d30\u660e\u9ad4', - value: 'pmingliu,serif' - }, { - caption: '\u7d30\u660e\u9ad4', - value: 'mingliu,serif' - }], - 'zh-cn': [{ - caption: '\u5b8b\u4f53', - value: 'simsun,serif' - }, { - caption: '\u9ed1\u4f53', - value: 'simhei,sans-serif' - }, { - caption: 'MS Song', - value: 'ms song,monospace' - }] -}; - - -/** - * Default locale for font names. - * @type {string} - * @private - */ -goog.ui.editor.DefaultToolbar.locale_ = 'en-us'; - - -/** - * Sets the locale for the font names. If not set, defaults to 'en-us'. - * Used only for default creation of font names name. Must be set - * before font name menu is created. - * @param {string} locale Locale to use for the toolbar font names. - */ -goog.ui.editor.DefaultToolbar.setLocale = function(locale) { - goog.ui.editor.DefaultToolbar.locale_ = locale; -}; - - -/** - * Initializes the given font menu button by adding default fonts to the menu. - * If goog.ui.editor.DefaultToolbar.setLocale was called to specify a locale - * for which locale-specific default fonts exist, those are added before - * common fonts. - * @param {!goog.ui.Select} button Font menu button. - */ -goog.ui.editor.DefaultToolbar.addDefaultFonts = function(button) { - // Normalize locale to lowercase, with a hyphen (see bug 1036165). - var locale = - goog.ui.editor.DefaultToolbar.locale_.replace(/_/, '-').toLowerCase(); - // Add locale-specific default fonts, if any. - var fontlist = []; - - if (locale in goog.ui.editor.DefaultToolbar.I18N_FONTS_) { - fontlist = goog.ui.editor.DefaultToolbar.I18N_FONTS_[locale]; - } - if (fontlist.length) { - goog.ui.editor.ToolbarFactory.addFonts(button, fontlist); - } - // Add locale-independent default fonts. - goog.ui.editor.ToolbarFactory.addFonts(button, - goog.ui.editor.DefaultToolbar.FONTS_); -}; - - -// Font size menu creation. - - -/** @desc Font size menu item caption for the 'Small' size. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_SMALL = goog.getMsg('Small'); - - -/** @desc Font size menu item caption for the 'Normal' size. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_NORMAL = goog.getMsg('Normal'); - - -/** @desc Font size menu item caption for the 'Large' size. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_LARGE = goog.getMsg('Large'); - - -/** @desc Font size menu item caption for the 'Huge' size. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_HUGE = goog.getMsg('Huge'); - - -/** - * Font size descriptors, each with the following attributes: - * <ul> - * <li>{@code caption} - Caption to show in the font size menu (e.g. 'Huge') - * <li>{@code value} - Value for the corresponding HTML font size (e.g. 6) - * </ul> - * @type {!Array.<{caption:string, value:number}>} - * @private - */ -goog.ui.editor.DefaultToolbar.FONT_SIZES_ = [ - {caption: goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_SMALL, value: 1}, - {caption: goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_NORMAL, value: 2}, - {caption: goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_LARGE, value: 4}, - {caption: goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_HUGE, value: 6} -]; - - -/** - * Initializes the given font size menu button by adding default font sizes to - * it. - * @param {!goog.ui.Select} button Font size menu button. - */ -goog.ui.editor.DefaultToolbar.addDefaultFontSizes = function(button) { - goog.ui.editor.ToolbarFactory.addFontSizes(button, - goog.ui.editor.DefaultToolbar.FONT_SIZES_); -}; - - -// Header format menu creation. - - -/** @desc Caption for "Heading" block format option. */ -goog.ui.editor.DefaultToolbar.MSG_FORMAT_HEADING = goog.getMsg('Heading'); - - -/** @desc Caption for "Subheading" block format option. */ -goog.ui.editor.DefaultToolbar.MSG_FORMAT_SUBHEADING = goog.getMsg('Subheading'); - - -/** @desc Caption for "Minor heading" block format option. */ -goog.ui.editor.DefaultToolbar.MSG_FORMAT_MINOR_HEADING = - goog.getMsg('Minor heading'); - - -/** @desc Caption for "Normal" block format option. */ -goog.ui.editor.DefaultToolbar.MSG_FORMAT_NORMAL = goog.getMsg('Normal'); - - -/** - * Format option descriptors, each with the following attributes: - * <ul> - * <li>{@code caption} - Caption to show in the menu (e.g. 'Minor heading') - * <li>{@code command} - Corresponding {@link goog.dom.TagName} (e.g. - * 'H4') - * </ul> - * @type {!Array.<{caption:string, command:string}>} - * @private - */ -goog.ui.editor.DefaultToolbar.FORMAT_OPTIONS_ = [ - { - caption: goog.ui.editor.DefaultToolbar.MSG_FORMAT_HEADING, - command: goog.dom.TagName.H2 - }, - { - caption: goog.ui.editor.DefaultToolbar.MSG_FORMAT_SUBHEADING, - command: goog.dom.TagName.H3 - }, - { - caption: goog.ui.editor.DefaultToolbar.MSG_FORMAT_MINOR_HEADING, - command: goog.dom.TagName.H4 - }, - { - caption: goog.ui.editor.DefaultToolbar.MSG_FORMAT_NORMAL, - command: goog.dom.TagName.P - } -]; - - -/** - * Initializes the given "Format block" menu button by adding default format - * options to the menu. - * @param {!goog.ui.Select} button "Format block" menu button. - */ -goog.ui.editor.DefaultToolbar.addDefaultFormatOptions = function(button) { - goog.ui.editor.ToolbarFactory.addFormatOptions(button, - goog.ui.editor.DefaultToolbar.FORMAT_OPTIONS_); -}; - - -/** - * Creates a {@link goog.ui.Toolbar} containing a default set of editor - * toolbar buttons, and renders it into the given parent element. - * @param {!Element} elem Toolbar parent element. - * @param {boolean=} opt_isRightToLeft Whether the editor chrome is - * right-to-left; defaults to the directionality of the toolbar parent - * element. - * @return {!goog.ui.Toolbar} Default editor toolbar, rendered into the given - * parent element. - * @see goog.ui.editor.DefaultToolbar.DEFAULT_BUTTONS - */ -goog.ui.editor.DefaultToolbar.makeDefaultToolbar = function(elem, - opt_isRightToLeft) { - var isRightToLeft = opt_isRightToLeft || goog.style.isRightToLeft(elem); - var buttons = isRightToLeft ? - goog.ui.editor.DefaultToolbar.DEFAULT_BUTTONS_RTL : - goog.ui.editor.DefaultToolbar.DEFAULT_BUTTONS; - return goog.ui.editor.DefaultToolbar.makeToolbar(buttons, elem, - opt_isRightToLeft); -}; - - -/** - * Creates a {@link goog.ui.Toolbar} containing the specified set of - * toolbar buttons, and renders it into the given parent element. Each - * item in the {@code items} array must either be a - * {@link goog.editor.Command} (to create a built-in button) or a subclass - * of {@link goog.ui.Control} (to create a custom control). - * @param {!Array.<string|goog.ui.Control>} items Toolbar items; each must - * be a {@link goog.editor.Command} or a {@link goog.ui.Control}. - * @param {!Element} elem Toolbar parent element. - * @param {boolean=} opt_isRightToLeft Whether the editor chrome is - * right-to-left; defaults to the directionality of the toolbar parent - * element. - * @return {!goog.ui.Toolbar} Editor toolbar, rendered into the given parent - * element. - */ -goog.ui.editor.DefaultToolbar.makeToolbar = function(items, elem, - opt_isRightToLeft) { - var domHelper = goog.dom.getDomHelper(elem); - var controls = []; - - for (var i = 0, button; button = items[i]; i++) { - if (goog.isString(button)) { - button = goog.ui.editor.DefaultToolbar.makeBuiltInToolbarButton(button, - domHelper); - } - if (button) { - controls.push(button); - } - } - - return goog.ui.editor.ToolbarFactory.makeToolbar(controls, elem, - opt_isRightToLeft); -}; - - -/** - * Creates an instance of a subclass of {@link goog.ui.Button} for the given - * {@link goog.editor.Command}, or null if no built-in button exists for the - * command. Note that this function is only intended to create built-in - * buttons; please don't try to hack it! - * @param {string} command Editor command ID. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {goog.ui.Button} Toolbar button (null if no built-in button exists - * for the command). - */ -goog.ui.editor.DefaultToolbar.makeBuiltInToolbarButton = function(command, - opt_domHelper) { - var button; - var descriptor = goog.ui.editor.DefaultToolbar.buttons_[command]; - if (descriptor) { - // Default the factory method to makeToggleButton, since most built-in - // toolbar buttons are toggle buttons. See also - // goog.ui.editor.DefaultToolbar.BUTTONS_. - var factory = descriptor.factory || - goog.ui.editor.ToolbarFactory.makeToggleButton; - var id = descriptor.command; - var tooltip = descriptor.tooltip; - var caption = descriptor.caption; - var classNames = descriptor.classes; - // Default the DOM helper to the one for the current document. - var domHelper = opt_domHelper || goog.dom.getDomHelper(); - // Instantiate the button based on the descriptor. - button = factory(id, tooltip, caption, classNames, null, domHelper); - // If this button's state should be queried when updating the toolbar, - // set the button object's queryable property to true. - if (descriptor.queryable) { - button.queryable = true; - } - } - return button; -}; - - -/** - * A set of built-in buttons to display in the default editor toolbar. - * @type {!Array.<string>} - */ -goog.ui.editor.DefaultToolbar.DEFAULT_BUTTONS = [ - goog.editor.Command.IMAGE, - goog.editor.Command.LINK, - goog.editor.Command.BOLD, - goog.editor.Command.ITALIC, - goog.editor.Command.UNORDERED_LIST, - goog.editor.Command.FONT_COLOR, - goog.editor.Command.FONT_FACE, - goog.editor.Command.FONT_SIZE, - goog.editor.Command.JUSTIFY_LEFT, - goog.editor.Command.JUSTIFY_CENTER, - goog.editor.Command.JUSTIFY_RIGHT, - goog.editor.Command.EDIT_HTML -]; - - -/** - * A set of built-in buttons to display in the default editor toolbar when - * the editor chrome is right-to-left (BiDi mode only). - * @type {!Array.<string>} - */ -goog.ui.editor.DefaultToolbar.DEFAULT_BUTTONS_RTL = [ - goog.editor.Command.IMAGE, - goog.editor.Command.LINK, - goog.editor.Command.BOLD, - goog.editor.Command.ITALIC, - goog.editor.Command.UNORDERED_LIST, - goog.editor.Command.FONT_COLOR, - goog.editor.Command.FONT_FACE, - goog.editor.Command.FONT_SIZE, - goog.editor.Command.JUSTIFY_RIGHT, - goog.editor.Command.JUSTIFY_CENTER, - goog.editor.Command.JUSTIFY_LEFT, - goog.editor.Command.DIR_RTL, - goog.editor.Command.DIR_LTR, - goog.editor.Command.EDIT_HTML -]; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. This button - * is designed to be used as the RTL button. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ButtonRenderer=} opt_renderer Button renderer; defaults to - * {@link goog.ui.ToolbarButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.rtlButtonFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeToggleButton(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper); - button.updateFromValue = function(value) { - // Enable/disable right-to-left text editing mode in the toolbar. - var isRtl = !!value; - // Enable/disable a marker class on the toolbar's root element; the rest is - // done using CSS scoping in editortoolbar.css. This changes - // direction-senitive toolbar icons (like indent/outdent) - goog.dom.classes.enable( - button.getParent().getElement(), goog.getCssName('tr-rtl-mode'), isRtl); - button.setChecked(isRtl); - } - return button; -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. Designed to - * be used to create undo and redo buttons. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ButtonRenderer=} opt_renderer Button renderer; defaults to - * {@link goog.ui.ToolbarButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.undoRedoButtonFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeButton(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper); - button.updateFromValue = function(value) { - button.setEnabled(value); - } - return button; -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. Used to create - * a font face button, filled with default fonts. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.MenuButtonRenderer=} opt_renderer Button renderer; defaults - * to {@link goog.ui.ToolbarMenuButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.fontFaceFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeSelectButton(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper); - goog.ui.editor.DefaultToolbar.addDefaultFonts(button); - button.setDefaultCaption(goog.ui.editor.DefaultToolbar.MSG_FONT_NORMAL); - // Font options don't have keyboard accelerators. - goog.dom.classes.add(button.getMenu().getContentElement(), - goog.getCssName('goog-menu-noaccel')); - - // How to update this button's state. - button.updateFromValue = function(value) { - // Normalize value to null or a non-empty string (sometimes we get - // the empty string, sometimes we get false...), extract the substring - // up to the first comma to get the primary font name, and normalize - // to lowercase. This allows us to map a font spec like "Arial, - // Helvetica, sans-serif" to a font menu item. - // TODO (attila): Try to make this more robust. - var item = null; - if (value && value.length > 0) { - item = /** @type {goog.ui.MenuItem} */ (button.getMenu().getChild( - goog.ui.editor.ToolbarFactory.getPrimaryFont(value))); - } - var selectedItem = button.getSelectedItem(); - if (item != selectedItem) { - button.setSelectedItem(item); - } - } - return button; -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. Use to create a - * font size button, filled with default font sizes. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.MenuButtonRenderer=} opt_renderer Button renderer; defaults - * to {@link goog.ui.ToolbarMebuButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.fontSizeFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeSelectButton(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper); - goog.ui.editor.DefaultToolbar.addDefaultFontSizes(button); - button.setDefaultCaption(goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_NORMAL); - // Font size options don't have keyboard accelerators. - goog.dom.classes.add(button.getMenu().getContentElement(), - goog.getCssName('goog-menu-noaccel')); - // How to update this button's state. - button.updateFromValue = function(value) { - // Webkit pre-534.7 returns a string like '32px' instead of the equivalent - // integer, so normalize that first. - // NOTE(user): Gecko returns "6" so can't just normalize all - // strings, only ones ending in "px". - if (goog.isString(value) && - goog.style.getLengthUnits(value) == 'px') { - value = goog.ui.editor.ToolbarFactory.getLegacySizeFromPx( - parseInt(value, 10)); - } - // Normalize value to null or a positive integer (sometimes we get - // the empty string, sometimes we get false, or -1 if the above - // normalization didn't match to a particular 0-7 size) - value = value > 0 ? value : null; - if (value != button.getValue()) { - button.setValue(value); - } - } - return button; -}; - - -/** - * Function to update the state of a color menu button. - * @param {goog.ui.ToolbarColorMenuButton} button The button to which the - * color menu is attached. - * @param {number} color Color value to update to. - * @private - */ -goog.ui.editor.DefaultToolbar.colorUpdateFromValue_ = function(button, color) { - var value = color; - /** @preserveTry */ - try { - if (goog.userAgent.IE) { - // IE returns a number that, converted to hex, is a BGR color. - // Convert from decimal to BGR to RGB. - var hex = '000000' + value.toString(16); - var bgr = hex.substr(hex.length - 6, 6); - value = new goog.string.StringBuffer('#', bgr.substring(4, 6), - bgr.substring(2, 4), bgr.substring(0, 2)).toString(); - } - if (value != button.getValue()) { - button.setValue(/** @type {string} */ (value)); - } - } catch (ex) { - // TODO(attila): Find out when/why this happens. - } -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. Use to create - * a font color button. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ColorMenuButtonRenderer=} opt_renderer Button renderer; - * defaults to {@link goog.ui.ToolbarColorMenuButtonRenderer} if - * unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.fontColorFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeColorMenuButton(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper); - // Initialize default foreground color. - button.setSelectedColor('#000'); - button.updateFromValue = goog.partial( - goog.ui.editor.DefaultToolbar.colorUpdateFromValue_, button); - return button; -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. Use to create - * a font background color button. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ColorMenuButtonRenderer=} opt_renderer Button renderer; - * defaults to {@link goog.ui.ToolbarColorMenuButtonRenderer} if - * unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.backgroundColorFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeColorMenuButton(id, - tooltip, caption, opt_classNames, opt_renderer, opt_domHelper); - // Initialize default background color. - button.setSelectedColor('#FFF'); - button.updateFromValue = goog.partial( - goog.ui.editor.DefaultToolbar.colorUpdateFromValue_, button); - return button; -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. Use to create - * the format menu, prefilled with default formats. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.MenuButtonRenderer=} opt_renderer Button renderer; - * defaults to - * {@link goog.ui.ToolbarMenuButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - * @private - */ -goog.ui.editor.DefaultToolbar.formatBlockFactory_ = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeSelectButton(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper); - goog.ui.editor.DefaultToolbar.addDefaultFormatOptions(button); - button.setDefaultCaption(goog.ui.editor.DefaultToolbar.MSG_FORMAT_NORMAL); - // Format options don't have keyboard accelerators. - goog.dom.classes.add(button.getMenu().getContentElement(), - goog.getCssName('goog-menu-noaccel')); - // How to update this button. - button.updateFromValue = function(value) { - // Normalize value to null or a nonempty string (sometimes we get - // the empty string, sometimes we get false...) - value = value && value.length > 0 ? value : null; - if (value != button.getValue()) { - button.setValue(value); - } - } - return button; -}; - - -// Messages used for tooltips and captions. - - -/** @desc Format menu tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_FORMAT_BLOCK_TITLE = goog.getMsg('Format'); - - -/** @desc Format menu caption. */ -goog.ui.editor.DefaultToolbar.MSG_FORMAT_BLOCK_CAPTION = goog.getMsg('Format'); - - -/** @desc Undo button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_UNDO_TITLE = goog.getMsg('Undo'); - - -/** @desc Redo button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_REDO_TITLE = goog.getMsg('Redo'); - - -/** @desc Font menu tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_FACE_TITLE = goog.getMsg('Font'); - - -/** @desc Font size menu tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_TITLE = goog.getMsg('Font size'); - - -/** @desc Text foreground color menu tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_FONT_COLOR_TITLE = goog.getMsg('Text color'); - - -/** @desc Bold button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_BOLD_TITLE = goog.getMsg('Bold'); - - -/** @desc Italic button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_ITALIC_TITLE = goog.getMsg('Italic'); - - -/** @desc Underline button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_UNDERLINE_TITLE = goog.getMsg('Underline'); - - -/** @desc Text background color menu tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_BACKGROUND_COLOR_TITLE = - goog.getMsg('Text background color'); - - -/** @desc Link button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_LINK_TITLE = - goog.getMsg('Add or remove link'); - - -/** @desc Numbered list button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_ORDERED_LIST_TITLE = - goog.getMsg('Numbered list'); - - -/** @desc Bullet list button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_UNORDERED_LIST_TITLE = - goog.getMsg('Bullet list'); - - -/** @desc Outdent button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_OUTDENT_TITLE = - goog.getMsg('Decrease indent'); - - -/** @desc Indent button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_INDENT_TITLE = goog.getMsg('Increase indent'); - - -/** @desc Align left button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_ALIGN_LEFT_TITLE = goog.getMsg('Align left'); - - -/** @desc Align center button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_ALIGN_CENTER_TITLE = - goog.getMsg('Align center'); - - -/** @desc Align right button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_ALIGN_RIGHT_TITLE = - goog.getMsg('Align right'); - - -/** @desc Justify button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_JUSTIFY_TITLE = goog.getMsg('Justify'); - - -/** @desc Remove formatting button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_REMOVE_FORMAT_TITLE = - goog.getMsg('Remove formatting'); - - -/** @desc Insert image button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_IMAGE_TITLE = goog.getMsg('Insert image'); - - -/** @desc Strike through button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_STRIKE_THROUGH_TITLE = - goog.getMsg('Strikethrough'); - - -/** @desc Left-to-right button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_DIR_LTR_TITLE = goog.getMsg('Left-to-right'); - - -/** @desc Right-to-left button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_DIR_RTL_TITLE = goog.getMsg('Right-to-left'); - - -/** @desc Blockquote button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_BLOCKQUOTE_TITLE = goog.getMsg('Quote'); - - -/** @desc Edit HTML button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_EDIT_HTML_TITLE = - goog.getMsg('Edit HTML source'); - - -/** @desc Subscript button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_SUBSCRIPT = goog.getMsg('Subscript'); - - -/** @desc Superscript button tooltip. */ -goog.ui.editor.DefaultToolbar.MSG_SUPERSCRIPT = goog.getMsg('Superscript'); - - -/** @desc Edit HTML button caption. */ -goog.ui.editor.DefaultToolbar.MSG_EDIT_HTML_CAPTION = goog.getMsg('Edit HTML'); - - -/** - * Map of {@code goog.editor.Command}s to toolbar button descriptor objects, - * each of which has the following attributes: - * <ul> - * <li>{@code command} - The command corresponding to the - * button (mandatory) - * <li>{@code tooltip} - Tooltip text (optional); if unspecified, the button - * has no hover text - * <li>{@code caption} - Caption to display on the button (optional); if - * unspecified, the button has no text caption - * <li>{@code classes} - CSS class name(s) to be applied to the button's - * element when rendered (optional); if unspecified, defaults to - * 'tr-icon' - * plus 'tr-' followed by the command ID, but without any leading '+' - * character (e.g. if the command ID is '+undo', then {@code classes} - * defaults to 'tr-icon tr-undo') - * <li>{@code factory} - factory function used to create the button, which - * must accept {@code id}, {@code tooltip}, {@code caption}, and - * {@code classes} as arguments, and must return an instance of - * {@link goog.ui.Button} or an appropriate subclass (optional); if - * unspecified, defaults to - * {@link goog.ui.editor.DefaultToolbar.makeToggleButton}, - * since most built-in toolbar buttons are toggle buttons - * <li>(@code queryable} - Whether the button's state should be queried - * when updating the toolbar (optional). - * </ul> - * Note that this object is only used for creating toolbar buttons for - * built-in editor commands; custom buttons aren't listed here. Please don't - * try to hack this! - * @type {Object.<!goog.ui.editor.ButtonDescriptor>}. - * @private - */ -goog.ui.editor.DefaultToolbar.buttons_ = {}; - - -/** - * @typedef {{command: string, tooltip: ?string, - * caption: ?goog.ui.ControlContent, classes: ?string, - * factory: ?function(string, string, goog.ui.ControlContent, ?string, - * goog.ui.ButtonRenderer, goog.dom.DomHelper):goog.ui.Button, - * queryable:?boolean}} - */ -goog.ui.editor.ButtonDescriptor; - - -/** - * Built-in toolbar button descriptors. See - * {@link goog.ui.editor.DefaultToolbar.buttons_} for details on button - * descriptor objects. This array is processed at JS parse time; each item is - * inserted into {@link goog.ui.editor.DefaultToolbar.buttons_}, and the array - * itself is deleted and (hopefully) garbage-collected. - * @type {Array.<!goog.ui.editor.ButtonDescriptor>}. - * @private - */ -goog.ui.editor.DefaultToolbar.BUTTONS_ = [{ - command: goog.editor.Command.UNDO, - tooltip: goog.ui.editor.DefaultToolbar.MSG_UNDO_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-undo'), - factory: goog.ui.editor.DefaultToolbar.undoRedoButtonFactory_, - queryable: true -}, { - command: goog.editor.Command.REDO, - tooltip: goog.ui.editor.DefaultToolbar.MSG_REDO_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-redo'), - factory: goog.ui.editor.DefaultToolbar.undoRedoButtonFactory_, - queryable: true -}, { - command: goog.editor.Command.FONT_FACE, - tooltip: goog.ui.editor.DefaultToolbar.MSG_FONT_FACE_TITLE, - classes: goog.getCssName('tr-fontName'), - factory: goog.ui.editor.DefaultToolbar.fontFaceFactory_, - queryable: true -}, { - command: goog.editor.Command.FONT_SIZE, - tooltip: goog.ui.editor.DefaultToolbar.MSG_FONT_SIZE_TITLE, - classes: goog.getCssName('tr-fontSize'), - factory: goog.ui.editor.DefaultToolbar.fontSizeFactory_, - queryable: true -}, { - command: goog.editor.Command.BOLD, - tooltip: goog.ui.editor.DefaultToolbar.MSG_BOLD_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-bold'), - queryable: true -}, { - command: goog.editor.Command.ITALIC, - tooltip: goog.ui.editor.DefaultToolbar.MSG_ITALIC_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-italic'), - queryable: true -}, { - command: goog.editor.Command.UNDERLINE, - tooltip: goog.ui.editor.DefaultToolbar.MSG_UNDERLINE_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-underline'), - queryable: true -}, { - command: goog.editor.Command.FONT_COLOR, - tooltip: goog.ui.editor.DefaultToolbar.MSG_FONT_COLOR_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-foreColor'), - factory: goog.ui.editor.DefaultToolbar.fontColorFactory_, - queryable: true -}, { - command: goog.editor.Command.BACKGROUND_COLOR, - tooltip: goog.ui.editor.DefaultToolbar.MSG_BACKGROUND_COLOR_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-backColor'), - factory: goog.ui.editor.DefaultToolbar.backgroundColorFactory_, - queryable: true -}, { - command: goog.editor.Command.LINK, - tooltip: goog.ui.editor.DefaultToolbar.MSG_LINK_TITLE, - caption: goog.ui.editor.messages.MSG_LINK_CAPTION, - classes: goog.getCssName('tr-link'), - queryable: true -}, { - command: goog.editor.Command.ORDERED_LIST, - tooltip: goog.ui.editor.DefaultToolbar.MSG_ORDERED_LIST_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-insertOrderedList'), - queryable: true -}, { - command: goog.editor.Command.UNORDERED_LIST, - tooltip: goog.ui.editor.DefaultToolbar.MSG_UNORDERED_LIST_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-insertUnorderedList'), - queryable: true -}, { - command: goog.editor.Command.OUTDENT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_OUTDENT_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-outdent'), - factory: goog.ui.editor.ToolbarFactory.makeButton -}, { - command: goog.editor.Command.INDENT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_INDENT_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-indent'), - factory: goog.ui.editor.ToolbarFactory.makeButton -}, { - command: goog.editor.Command.JUSTIFY_LEFT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_ALIGN_LEFT_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-justifyLeft'), - queryable: true -}, { - command: goog.editor.Command.JUSTIFY_CENTER, - tooltip: goog.ui.editor.DefaultToolbar.MSG_ALIGN_CENTER_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-justifyCenter'), - queryable: true -}, { - command: goog.editor.Command.JUSTIFY_RIGHT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_ALIGN_RIGHT_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-justifyRight'), - queryable: true -}, { - command: goog.editor.Command.JUSTIFY_FULL, - tooltip: goog.ui.editor.DefaultToolbar.MSG_JUSTIFY_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-justifyFull'), - queryable: true -}, { - command: goog.editor.Command.REMOVE_FORMAT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_REMOVE_FORMAT_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-removeFormat'), - factory: goog.ui.editor.ToolbarFactory.makeButton -}, { - command: goog.editor.Command.IMAGE, - tooltip: goog.ui.editor.DefaultToolbar.MSG_IMAGE_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-image'), - factory: goog.ui.editor.ToolbarFactory.makeButton -}, { - command: goog.editor.Command.STRIKE_THROUGH, - tooltip: goog.ui.editor.DefaultToolbar.MSG_STRIKE_THROUGH_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-strikeThrough'), - queryable: true -}, { - command: goog.editor.Command.SUBSCRIPT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_SUBSCRIPT, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-subscript'), - queryable: true -} , { - command: goog.editor.Command.SUPERSCRIPT, - tooltip: goog.ui.editor.DefaultToolbar.MSG_SUPERSCRIPT, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-superscript'), - queryable: true -}, { - command: goog.editor.Command.DIR_LTR, - tooltip: goog.ui.editor.DefaultToolbar.MSG_DIR_LTR_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-ltr'), - queryable: true -}, { - command: goog.editor.Command.DIR_RTL, - tooltip: goog.ui.editor.DefaultToolbar.MSG_DIR_RTL_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + goog.getCssName('tr-rtl'), - factory: goog.ui.editor.DefaultToolbar.rtlButtonFactory_, - queryable: true -}, { - command: goog.editor.Command.BLOCKQUOTE, - tooltip: goog.ui.editor.DefaultToolbar.MSG_BLOCKQUOTE_TITLE, - classes: goog.getCssName('tr-icon') + ' ' + - goog.getCssName('tr-BLOCKQUOTE'), - queryable: true -}, { - command: goog.editor.Command.FORMAT_BLOCK, - tooltip: goog.ui.editor.DefaultToolbar.MSG_FORMAT_BLOCK_TITLE, - caption: goog.ui.editor.DefaultToolbar.MSG_FORMAT_BLOCK_CAPTION, - classes: goog.getCssName('tr-formatBlock'), - factory: goog.ui.editor.DefaultToolbar.formatBlockFactory_, - queryable: true -}, { - command: goog.editor.Command.EDIT_HTML, - tooltip: goog.ui.editor.DefaultToolbar.MSG_EDIT_HTML_TITLE, - caption: goog.ui.editor.DefaultToolbar.MSG_EDIT_HTML_CAPTION, - classes: goog.getCssName('tr-editHtml'), - factory: goog.ui.editor.ToolbarFactory.makeButton -}]; - - -(function() { -// Create the goog.ui.editor.DefaultToolbar.buttons_ map from -// goog.ui.editor.DefaultToolbar.BUTTONS_. -for (var i = 0, button; - button = goog.ui.editor.DefaultToolbar.BUTTONS_[i]; i++) { - goog.ui.editor.DefaultToolbar.buttons_[button.command] = button; -} - -// goog.ui.editor.DefaultToolbar.BUTTONS_ is no longer needed -// once the map is ready. -delete goog.ui.editor.DefaultToolbar.BUTTONS_; - -})(); diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/equationeditordialog.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/equationeditordialog.js.svn-base deleted file mode 100644 index 579234f..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/equationeditordialog.js.svn-base +++ /dev/null @@ -1,123 +0,0 @@ -// 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.editor.EquationEditorDialog'); - -goog.require('goog.editor.Command'); -goog.require('goog.ui.editor.AbstractDialog'); -goog.require('goog.ui.editor.EquationEditorOkEvent'); -goog.require('goog.ui.equation.ChangeEvent'); -goog.require('goog.ui.equation.TexEditor'); - - - -/** - * Equation editor dialog (based on goog.ui.editor.AbstractDialog). - * @param {Object} context The context that this dialog runs in. - * @param {goog.dom.DomHelper} domHelper DomHelper to be used to create the - * dialog's dom structure. - * @param {string} equation Initial equation. - * @param {string} helpUrl URL pointing to help documentation. - * @constructor - * @extends {goog.ui.editor.AbstractDialog} - */ -goog.ui.editor.EquationEditorDialog = function(context, domHelper, - equation, helpUrl) { - goog.ui.editor.AbstractDialog.call(this, domHelper); - this.equationEditor_ = - new goog.ui.equation.TexEditor(context, helpUrl); - this.equationEditor_.render(); - this.equationEditor_.setEquation(equation); - this.equationEditor_.addEventListener(goog.editor.Command.EQUATION, - this.onChange_, false, this); -}; -goog.inherits(goog.ui.editor.EquationEditorDialog, - goog.ui.editor.AbstractDialog); - - -/** - * The equation editor actual UI. - * @type {goog.ui.equation.TexEditor} - * @private - */ -goog.ui.editor.EquationEditorDialog.prototype.equationEditor_; - - -/** - * The dialog's OK button element. - * @type {Element?} - * @private - */ -goog.ui.editor.EquationEditorDialog.prototype.okButton_; - - -/** @override */ -goog.ui.editor.EquationEditorDialog.prototype.createDialogControl = - function() { - var builder = new goog.ui.editor.AbstractDialog.Builder(this); - - /** - * @desc The title of the equation editor dialog. - */ - var MSG_EE_DIALOG_TITLE = goog.getMsg('Equation Editor'); - - /** - * @desc Button label for the equation editor dialog for adding - * a new equation. - */ - var MSG_EE_BUTTON_SAVE_NEW = goog.getMsg('Insert equation'); - - /** - * @desc Button label for the equation editor dialog for saving - * a modified equation. - */ - var MSG_EE_BUTTON_SAVE_MODIFY = goog.getMsg('Save changes'); - - var okButtonText = this.equationEditor_.getEquation() ? - MSG_EE_BUTTON_SAVE_MODIFY : MSG_EE_BUTTON_SAVE_NEW; - - builder.setTitle(MSG_EE_DIALOG_TITLE) - .setContent(this.equationEditor_.getElement()) - .addOkButton(okButtonText) - .addCancelButton(); - - return builder.build(); -}; - - -/** - * @override - */ -goog.ui.editor.EquationEditorDialog.prototype.createOkEvent = function(e) { - if (this.equationEditor_.isValid()) { - // Equation is not valid, don't close the dialog. - return null; - } - var equationHtml = this.equationEditor_.getHtml(); - return new goog.ui.editor.EquationEditorOkEvent(equationHtml); -}; - - -/** - * Handles CHANGE event fired when user changes equation. - * @param {goog.ui.equation.ChangeEvent} e The event object. - * @private - */ -goog.ui.editor.EquationEditorDialog.prototype.onChange_ = function(e) { - if (!this.okButton_) { - this.okButton_ = this.getButtonElement( - goog.ui.Dialog.DefaultButtonKeys.OK); - } - this.okButton_.disabled = !e.isValid; -}; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/equationeditorokevent.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/equationeditorokevent.js.svn-base deleted file mode 100644 index 06d0e0f..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/equationeditorokevent.js.svn-base +++ /dev/null @@ -1,49 +0,0 @@ -// 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.editor.EquationEditorOkEvent'); - -goog.require('goog.events.Event'); -goog.require('goog.ui.editor.AbstractDialog'); - - - -/** - * OK event object for the equation editor dialog. - * @param {string} equationHtml html containing the equation to put in the - * editable field. - * @constructor - * @extends {goog.events.Event} - */ -goog.ui.editor.EquationEditorOkEvent = function(equationHtml) { - this.equationHtml = equationHtml; -}; -goog.inherits(goog.ui.editor.EquationEditorOkEvent, - goog.events.Event); - - -/** - * Event type. - * @type {goog.ui.editor.AbstractDialog.EventType} - * @override - */ -goog.ui.editor.EquationEditorOkEvent.prototype.type = - goog.ui.editor.AbstractDialog.EventType.OK; - - -/** - * HTML containing the equation to put in the editable field. - * @type {string} - */ -goog.ui.editor.EquationEditorOkEvent.prototype.equationHtml; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/linkdialog.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/linkdialog.js.svn-base deleted file mode 100644 index 965a598..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/linkdialog.js.svn-base +++ /dev/null @@ -1,937 +0,0 @@ -// 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. - -/** - * @fileoverview A dialog for editing/creating a link. - * - */ - -goog.provide('goog.ui.editor.LinkDialog'); -goog.provide('goog.ui.editor.LinkDialog.BeforeTestLinkEvent'); -goog.provide('goog.ui.editor.LinkDialog.EventType'); -goog.provide('goog.ui.editor.LinkDialog.OkEvent'); - -goog.require('goog.dom'); -goog.require('goog.dom.DomHelper'); -goog.require('goog.dom.TagName'); -goog.require('goog.dom.classes'); -goog.require('goog.dom.selection'); -goog.require('goog.editor.BrowserFeature'); -goog.require('goog.editor.Link'); -goog.require('goog.editor.focus'); -goog.require('goog.events'); -goog.require('goog.events.EventHandler'); -goog.require('goog.events.EventType'); -goog.require('goog.events.InputHandler'); -goog.require('goog.events.InputHandler.EventType'); -goog.require('goog.string'); -goog.require('goog.style'); -goog.require('goog.ui.Button'); -goog.require('goog.ui.LinkButtonRenderer'); -goog.require('goog.ui.editor.AbstractDialog'); -goog.require('goog.ui.editor.AbstractDialog.Builder'); -goog.require('goog.ui.editor.AbstractDialog.EventType'); -goog.require('goog.ui.editor.TabPane'); -goog.require('goog.ui.editor.messages'); -goog.require('goog.userAgent'); -goog.require('goog.window'); - - - -/** - * A type of goog.ui.editor.AbstractDialog for editing/creating a link. - * @param {goog.dom.DomHelper} domHelper DomHelper to be used to create the - * dialog's dom structure. - * @param {goog.editor.Link} link The target link. - * @constructor - * @extends {goog.ui.editor.AbstractDialog} - */ -goog.ui.editor.LinkDialog = function(domHelper, link) { - goog.base(this, domHelper); - this.targetLink_ = link; - - /** - * The event handler for this dialog. - * @type {goog.events.EventHandler} - * @private - */ - this.eventHandler_ = new goog.events.EventHandler(this); -}; -goog.inherits(goog.ui.editor.LinkDialog, goog.ui.editor.AbstractDialog); - - -/** - * Events specific to the link dialog. - * @enum {string} - */ -goog.ui.editor.LinkDialog.EventType = { - BEFORE_TEST_LINK: 'beforetestlink' -}; - - - -/** - * OK event object for the link dialog. - * @param {string} linkText Text the user chose to display for the link. - * @param {string} linkUrl Url the user chose for the link to point to. - * @param {boolean} openInNewWindow Whether the link should open in a new window - * when clicked. - * @constructor - * @extends {goog.events.Event} - */ -goog.ui.editor.LinkDialog.OkEvent = function( - linkText, linkUrl, openInNewWindow) { - goog.base(this, goog.ui.editor.AbstractDialog.EventType.OK); - - /** - * The text of the link edited in the dialog. - * @type {string} - */ - this.linkText = linkText; - - /** - * The url of the link edited in the dialog. - * @type {string} - */ - this.linkUrl = linkUrl; - - /** - * Whether the link should open in a new window when clicked. - * @type {boolean} - */ - this.openInNewWindow = openInNewWindow; -}; -goog.inherits(goog.ui.editor.LinkDialog.OkEvent, goog.events.Event); - - - -/** - * Event fired before testing a link by opening it in another window. - * Calling preventDefault will stop the link from being opened. - * @param {string} url Url of the link being tested. - * @constructor - * @extends {goog.events.Event} - */ -goog.ui.editor.LinkDialog.BeforeTestLinkEvent = function(url) { - goog.base(this, goog.ui.editor.LinkDialog.EventType.BEFORE_TEST_LINK); - - /** - * The url of the link being tested. - * @type {string} - */ - this.url = url; -}; -goog.inherits(goog.ui.editor.LinkDialog.BeforeTestLinkEvent, goog.events.Event); - - -/** - * Optional warning to show about email addresses. - * @type {string|undefined} - * @private - */ -goog.ui.editor.LinkDialog.prototype.emailWarning_; - - -/** - * Whether to show a checkbox where the user can choose to have the link open in - * a new window. - * @type {boolean} - * @private - */ -goog.ui.editor.LinkDialog.prototype.showOpenLinkInNewWindow_ = false; - - -/** - * Whether the "open link in new window" checkbox should be checked when the - * dialog is shown, and also whether it was checked last time the dialog was - * closed. - * @type {boolean} - * @private - */ -goog.ui.editor.LinkDialog.prototype.isOpenLinkInNewWindowChecked_ = false; - - -/** - * Sets the warning message to show to users about including email addresses on - * public web pages. - * @param {string} emailWarning Warning message to show users about including - * email addresses on the web. - */ -goog.ui.editor.LinkDialog.prototype.setEmailWarning = function( - emailWarning) { - this.emailWarning_ = emailWarning; -}; - - -/** - * Tells the dialog to show a checkbox where the user can choose to have the - * link open in a new window. - * @param {boolean} startChecked Whether to check the checkbox the first - * time the dialog is shown. Subesquent times the checkbox will remember its - * previous state. - */ -goog.ui.editor.LinkDialog.prototype.showOpenLinkInNewWindow = function( - startChecked) { - this.showOpenLinkInNewWindow_ = true; - this.isOpenLinkInNewWindowChecked_ = startChecked; -}; - - -/** @override */ -goog.ui.editor.LinkDialog.prototype.show = function() { - goog.base(this, 'show'); - - - this.selectAppropriateTab_(this.textToDisplayInput_.value, - this.getTargetUrl_()); - this.syncOkButton_(); - - if (this.showOpenLinkInNewWindow_) { - if (!this.targetLink_.isNew()) { - // If link is not new, checkbox should reflect current target. - this.isOpenLinkInNewWindowChecked_ = - this.targetLink_.getAnchor().target == '_blank'; - } - this.openInNewWindowCheckbox_.checked = this.isOpenLinkInNewWindowChecked_; - } -}; - - -/** @override */ -goog.ui.editor.LinkDialog.prototype.hide = function() { - this.disableAutogenFlag_(false); - goog.base(this, 'hide'); -}; - - -/** - * Tells the dialog whether to show the 'text to display' div. - * When the target element of the dialog is an image, there is no link text - * to modify. This function can be used for this kind of situations. - * @param {boolean} visible Whether to make 'text to display' div visible. - */ -goog.ui.editor.LinkDialog.prototype.setTextToDisplayVisible = function( - visible) { - if (this.textToDisplayDiv_) { - goog.style.setStyle(this.textToDisplayDiv_, 'display', - visible ? 'block' : 'none'); - } -}; - - -/** - * Tells the plugin whether to stop leaking the page's url via the referrer - * header when the "test this link" link is clicked. - * @param {boolean} stop Whether to stop leaking the referrer. - */ -goog.ui.editor.LinkDialog.prototype.setStopReferrerLeaks = function(stop) { - this.stopReferrerLeaks_ = stop; -}; - - -/** - * Tells the dialog whether the autogeneration of text to display is to be - * enabled. - * @param {boolean} enable Whether to enable the feature. - */ -goog.ui.editor.LinkDialog.prototype.setAutogenFeatureEnabled = function( - enable) { - this.autogenFeatureEnabled_ = enable; -}; - - -// *** Protected interface ************************************************** // - - -/** @override */ -goog.ui.editor.LinkDialog.prototype.createDialogControl = function() { - this.textToDisplayDiv_ = /** @type {HTMLDivElement} */( - this.buildTextToDisplayDiv_()); - var content = this.dom.createDom(goog.dom.TagName.DIV, null, - this.textToDisplayDiv_); - - var builder = new goog.ui.editor.AbstractDialog.Builder(this); - builder.setTitle(goog.ui.editor.messages.MSG_EDIT_LINK) - .setContent(content); - - this.tabPane_ = new goog.ui.editor.TabPane(this.dom, - goog.ui.editor.messages.MSG_LINK_TO); - this.tabPane_.addTab(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB, - goog.ui.editor.messages.MSG_ON_THE_WEB, - goog.ui.editor.messages.MSG_ON_THE_WEB_TIP, - this.buildTabOnTheWeb_()); - this.tabPane_.addTab(goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB, - goog.ui.editor.messages.MSG_EMAIL_ADDRESS, - goog.ui.editor.messages.MSG_EMAIL_ADDRESS_TIP, - this.buildTabEmailAddress_()); - this.tabPane_.render(content); - - this.eventHandler_.listen(this.tabPane_, goog.ui.Component.EventType.SELECT, - this.onChangeTab_); - - if (this.showOpenLinkInNewWindow_) { - content.appendChild(this.buildOpenInNewWindowDiv_()); - } - - return builder.build(); -}; - - -/** - * Creates and returns the event object to be used when dispatching the OK - * event to listeners based on which tab is currently selected and the contents - * of the input fields of that tab. - * @return {goog.ui.editor.LinkDialog.OkEvent} The event object to be used when - * dispatching the OK event to listeners. - * @protected - * @override - */ -goog.ui.editor.LinkDialog.prototype.createOkEvent = function() { - if (this.tabPane_.getCurrentTabId() == - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB) { - return this.createOkEventFromEmailTab_(); - } else { - return this.createOkEventFromWebTab_(); - } -}; - - -/** @override */ -goog.ui.editor.LinkDialog.prototype.disposeInternal = function() { - this.eventHandler_.dispose(); - this.eventHandler_ = null; - - this.urlInputHandler_.dispose(); - this.urlInputHandler_ = null; - this.emailInputHandler_.dispose(); - this.emailInputHandler_ = null; - - goog.base(this, 'disposeInternal'); -}; - - -// *** Private implementation *********************************************** // - - -/** - * The link being modified by this dialog. - * @type {goog.editor.Link} - * @private - */ -goog.ui.editor.LinkDialog.prototype.targetLink_; - - -/** - * EventHandler object that keeps track of all handlers set by this dialog. - * @type {goog.events.EventHandler} - * @private - */ -goog.ui.editor.LinkDialog.prototype.eventHandler_; - - -/** - * InputHandler object to listen for changes in the url input field. - * @type {goog.events.InputHandler} - * @private - */ -goog.ui.editor.LinkDialog.prototype.urlInputHandler_; - - -/** - * InputHandler object to listen for changes in the email input field. - * @type {goog.events.InputHandler} - * @private - */ -goog.ui.editor.LinkDialog.prototype.emailInputHandler_; - - -/** - * The tab bar where the url and email tabs are. - * @type {goog.ui.editor.TabPane} - * @private - */ -goog.ui.editor.LinkDialog.prototype.tabPane_; - - -/** - * The div element holding the link's display text input. - * @type {HTMLDivElement} - * @private - */ -goog.ui.editor.LinkDialog.prototype.textToDisplayDiv_; - - -/** - * The input element holding the link's display text. - * @type {HTMLInputElement} - * @private - */ -goog.ui.editor.LinkDialog.prototype.textToDisplayInput_; - - -/** - * Whether or not the feature of automatically generating the display text is - * enabled. - * @type {boolean} - * @private - */ -goog.ui.editor.LinkDialog.prototype.autogenFeatureEnabled_ = true; - - -/** - * Whether or not we should automatically generate the display text. - * @type {boolean} - * @private - */ -goog.ui.editor.LinkDialog.prototype.autogenerateTextToDisplay_; - - -/** - * Whether or not automatic generation of the display text is disabled. - * @type {boolean} - * @private - */ -goog.ui.editor.LinkDialog.prototype.disableAutogen_; - - -/** - * The input element (checkbox) to indicate that the link should open in a new - * window. - * @type {HTMLInputElement} - * @private - */ -goog.ui.editor.LinkDialog.prototype.openInNewWindowCheckbox_; - - -/** - * Whether to stop leaking the page's url via the referrer header when the - * "test this link" link is clicked. - * @type {boolean} - * @private - */ -goog.ui.editor.LinkDialog.prototype.stopReferrerLeaks_ = false; - - -/** - * Builds and returns the text to display section of the edit link dialog. - * @return {Element} A div element to be appended into the dialog div. - * @private - */ -goog.ui.editor.LinkDialog.prototype.buildTextToDisplayDiv_ = function() { - var table = this.dom.createTable(1, 2); - table.cellSpacing = '0'; - table.cellPadding = '0'; - table.style.fontSize = '10pt'; - // Build the text to display input. - var textToDisplayDiv = this.dom.createDom(goog.dom.TagName.DIV); - table.rows[0].cells[0].innerHTML = '<span style="position: relative;' + - ' bottom: 2px; padding-right: 1px; white-space: nowrap;">' + - goog.ui.editor.messages.MSG_TEXT_TO_DISPLAY + ' </span>'; - this.textToDisplayInput_ = /** @type {HTMLInputElement} */( - this.dom.createDom(goog.dom.TagName.INPUT, - {id: goog.ui.editor.LinkDialog.Id_.TEXT_TO_DISPLAY})); - var textInput = this.textToDisplayInput_; - // 98% prevents scroll bars in standards mode. - // TODO(robbyw): Is this necessary for quirks mode? - goog.style.setStyle(textInput, 'width', '98%'); - goog.style.setStyle(table.rows[0].cells[1], 'width', '100%'); - goog.dom.appendChild(table.rows[0].cells[1], textInput); - - textInput.value = this.targetLink_.getCurrentText(); - this.eventHandler_.listen(textInput, - goog.events.EventType.KEYUP, - goog.bind(this.onTextToDisplayEdit_, this)); - - goog.dom.appendChild(textToDisplayDiv, table); - return textToDisplayDiv; -}; - - -/** - * Builds and returns the "checkbox to open the link in a new window" section of - * the edit link dialog. - * @return {Element} A div element to be appended into the dialog div. - * @private - */ -goog.ui.editor.LinkDialog.prototype.buildOpenInNewWindowDiv_ = function() { - this.openInNewWindowCheckbox_ = /** @type {HTMLInputElement} */( - this.dom.createDom(goog.dom.TagName.INPUT, {'type': 'checkbox'})); - return this.dom.createDom(goog.dom.TagName.DIV, null, - this.dom.createDom(goog.dom.TagName.LABEL, null, - this.openInNewWindowCheckbox_, - goog.ui.editor.messages.MSG_OPEN_IN_NEW_WINDOW)); -}; - - -/** -* Builds and returns the div containing the tab "On the web". -* @return {Element} The div element containing the tab. -* @private -*/ -goog.ui.editor.LinkDialog.prototype.buildTabOnTheWeb_ = function() { - var onTheWebDiv = this.dom.createElement(goog.dom.TagName.DIV); - - var headingDiv = this.dom.createDom(goog.dom.TagName.DIV, - {innerHTML: '<b>' + goog.ui.editor.messages.MSG_WHAT_URL + '</b>'}); - var urlInput = this.dom.createDom(goog.dom.TagName.INPUT, - {id: goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT, - className: goog.ui.editor.LinkDialog.TARGET_INPUT_CLASSNAME_}); - // IE throws on unknown values for type. - if (!goog.userAgent.IE) { - // On browsers that support Web Forms 2.0, allow autocompletion of URLs. - // (As of now, this is only supported by Opera 9) - urlInput.type = 'url'; - } - - if (goog.editor.BrowserFeature.NEEDS_99_WIDTH_IN_STANDARDS_MODE && - goog.editor.node.isStandardsMode(urlInput)) { - urlInput.style.width = '99%'; - } - - var inputDiv = this.dom.createDom(goog.dom.TagName.DIV, null, urlInput); - - this.urlInputHandler_ = new goog.events.InputHandler(urlInput); - this.eventHandler_.listen(this.urlInputHandler_, - goog.events.InputHandler.EventType.INPUT, - this.onUrlOrEmailInputChange_); - - var testLink = new goog.ui.Button(goog.ui.editor.messages.MSG_TEST_THIS_LINK, - goog.ui.LinkButtonRenderer.getInstance(), - this.dom); - testLink.render(inputDiv); - testLink.getElement().style.marginTop = '1em'; - this.eventHandler_.listen(testLink, - goog.ui.Component.EventType.ACTION, - this.onWebTestLink_); - - // Build the "On the web" explanation text div. - var explanationDiv = this.dom.createDom(goog.dom.TagName.DIV, - {className: goog.ui.editor.LinkDialog.EXPLANATION_TEXT_CLASSNAME_, - innerHTML: goog.ui.editor.messages.MSG_TR_LINK_EXPLANATION}); - onTheWebDiv.appendChild(headingDiv); - onTheWebDiv.appendChild(inputDiv); - onTheWebDiv.appendChild(explanationDiv); - - return onTheWebDiv; -}; - - -/** - * Builds and returns the div containing the tab "Email address". - * @return {Element} the div element containing the tab. - * @private - */ -goog.ui.editor.LinkDialog.prototype.buildTabEmailAddress_ = function() { - var emailTab = this.dom.createDom(goog.dom.TagName.DIV); - - var headingDiv = this.dom.createDom(goog.dom.TagName.DIV, - {innerHTML: '<b>' + goog.ui.editor.messages.MSG_WHAT_EMAIL + '</b>'}); - goog.dom.appendChild(emailTab, headingDiv); - var emailInput = this.dom.createDom(goog.dom.TagName.INPUT, - {id: goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_INPUT, - className: goog.ui.editor.LinkDialog.TARGET_INPUT_CLASSNAME_}); - - if (goog.editor.BrowserFeature.NEEDS_99_WIDTH_IN_STANDARDS_MODE && - goog.editor.node.isStandardsMode(emailInput)) { - // Standards mode sizes this too large. - emailInput.style.width = '99%'; - } - - goog.dom.appendChild(emailTab, emailInput); - - this.emailInputHandler_ = new goog.events.InputHandler(emailInput); - this.eventHandler_.listen(this.emailInputHandler_, - goog.events.InputHandler.EventType.INPUT, - this.onUrlOrEmailInputChange_); - - goog.dom.appendChild(emailTab, - this.dom.createDom(goog.dom.TagName.DIV, - {id: goog.ui.editor.LinkDialog.Id_.EMAIL_WARNING, - className: goog.ui.editor.LinkDialog.EMAIL_WARNING_CLASSNAME_, - style: 'visibility:hidden'}, - goog.ui.editor.messages.MSG_INVALID_EMAIL)); - - if (this.emailWarning_) { - var explanationDiv = this.dom.createDom(goog.dom.TagName.DIV, - {className: goog.ui.editor.LinkDialog.EXPLANATION_TEXT_CLASSNAME_, - innerHTML: this.emailWarning_}); - goog.dom.appendChild(emailTab, explanationDiv); - } - return emailTab; -}; - - -/** - * Returns the url that the target points to. - * @return {string} The url that the target points to. - * @private - */ -goog.ui.editor.LinkDialog.prototype.getTargetUrl_ = function() { - // Get the href-attribute through getAttribute() rather than the href property - // because Google-Toolbar on Firefox with "Send with Gmail" turned on - // modifies the href-property of 'mailto:' links but leaves the attribute - // untouched. - return this.targetLink_.getAnchor().getAttribute('href') || ''; -}; - - -/** - * Selects the correct tab based on the URL, and fills in its inputs. - * For new links, it suggests a url based on the link text. - * @param {string} text The inner text of the link. - * @param {string} url The href for the link. - * @private - */ -goog.ui.editor.LinkDialog.prototype.selectAppropriateTab_ = function( - text, url) { - if (this.isNewLink_()) { - // Newly created non-empty link: try to infer URL from the link text. - this.guessUrlAndSelectTab_(text); - } else if (goog.editor.Link.isMailto(url)) { - // The link is for an email. - this.tabPane_.setSelectedTabId( - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB); - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_INPUT) - .value = url.substring(url.indexOf(':') + 1); - this.setAutogenFlagFromCurInput_(); - } else { - // No specific tab was appropriate, default to on the web tab. - this.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT) - .value = this.isNewLink_() ? 'http://' : url; - this.setAutogenFlagFromCurInput_(); - } -}; - - -/** - * Select a url/tab based on the link's text. This function is simply - * the isNewLink_() == true case of selectAppropriateTab_(). - * @param {string} text The inner text of the link. - * @private - */ -goog.ui.editor.LinkDialog.prototype.guessUrlAndSelectTab_ = function(text) { - if (goog.editor.Link.isLikelyEmailAddress(text)) { - // The text is for an email address. - this.tabPane_.setSelectedTabId( - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB); - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_INPUT) - .value = text; - this.setAutogenFlag_(true); - // TODO(user): Why disable right after enabling? What bug are we - // working around? - this.disableAutogenFlag_(true); - } else if (goog.editor.Link.isLikelyUrl(text)) { - // The text is for a web URL. - this.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT) - .value = text; - this.setAutogenFlag_(true); - this.disableAutogenFlag_(true); - } else { - // No meaning could be deduced from text, choose a default tab. - if (!this.targetLink_.getCurrentText()) { - this.setAutogenFlag_(true); - } - this.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - } -}; - - -/** - * Called on a change to the url or email input. If either one of those tabs - * is active, sets the OK button to enabled/disabled accordingly. - * @private - */ -goog.ui.editor.LinkDialog.prototype.syncOkButton_ = function() { - var inputValue; - if (this.tabPane_.getCurrentTabId() == - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB) { - inputValue = this.dom.getElement( - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_INPUT).value; - this.toggleInvalidEmailWarning_(inputValue != '' && - !goog.editor.Link.isLikelyEmailAddress(inputValue)); - } else if (this.tabPane_.getCurrentTabId() == - goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB) { - inputValue = this.dom.getElement( - goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT).value; - } else { - return; - } - this.getOkButtonElement().disabled = goog.string.isEmpty(inputValue); -}; - - -/** - * Show/hide the Invalid Email Address warning. - * @param {boolean} on Whether to show the warning. - * @private - */ -goog.ui.editor.LinkDialog.prototype.toggleInvalidEmailWarning_ = function(on) { - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.EMAIL_WARNING) - .style.visibility = (on ? 'visible' : 'hidden'); -}; - - -/** - * Changes the autogenerateTextToDisplay flag so that text to - * display stops autogenerating. - * @private - */ -goog.ui.editor.LinkDialog.prototype.onTextToDisplayEdit_ = function() { - var inputEmpty = this.textToDisplayInput_.value == ''; - if (inputEmpty) { - this.setAutogenFlag_(true); - } else { - this.setAutogenFlagFromCurInput_(); - } -}; - - -/** - * The function called when hitting OK with the "On the web" tab current. - * @return {goog.ui.editor.LinkDialog.OkEvent} The event object to be used when - * dispatching the OK event to listeners. - * @private - */ -goog.ui.editor.LinkDialog.prototype.createOkEventFromWebTab_ = function() { - var input = /** @type {HTMLInputElement} */( - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT)); - var linkURL = input.value; - if (goog.editor.Link.isLikelyEmailAddress(linkURL)) { - // Make sure that if user types in an e-mail address, it becomes "mailto:". - return this.createOkEventFromEmailTab_( - goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT); - } else { - if (linkURL.search(/:/) < 0) { - linkURL = 'http://' + goog.string.trimLeft(linkURL); - } - return this.createOkEventFromUrl_(linkURL); - } -}; - - -/** - * The function called when hitting OK with the "email address" tab current. - * @param {string=} opt_inputId Id of an alternate input to check. - * @return {goog.ui.editor.LinkDialog.OkEvent} The event object to be used when - * dispatching the OK event to listeners. - * @private - */ -goog.ui.editor.LinkDialog.prototype.createOkEventFromEmailTab_ = function( - opt_inputId) { - var linkURL = this.dom.getElement( - opt_inputId || goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_INPUT).value; - linkURL = 'mailto:' + linkURL; - return this.createOkEventFromUrl_(linkURL); -}; - - -/** - * Function to test a link from the on the web tab. - * @private - */ -goog.ui.editor.LinkDialog.prototype.onWebTestLink_ = function() { - var input = /** @type {HTMLInputElement} */( - this.dom.getElement(goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT)); - var url = input.value; - if (url.search(/:/) < 0) { - url = 'http://' + goog.string.trimLeft(url); - } - if (this.dispatchEvent( - new goog.ui.editor.LinkDialog.BeforeTestLinkEvent(url))) { - var win = this.dom.getWindow(); - var size = goog.dom.getViewportSize(win); - var openOptions = { - target: '_blank', - width: Math.max(size.width - 50, 50), - height: Math.max(size.height - 50, 50), - toolbar: true, - scrollbars: true, - location: true, - statusbar: false, - menubar: true, - 'resizable': true, - 'noreferrer': this.stopReferrerLeaks_ - }; - goog.window.open(url, openOptions, win); - } -}; - - -/** - * Called whenever the url or email input is edited. If the text to display - * matches the text to display, turn on auto. Otherwise if auto is on, update - * the text to display based on the url. - * @private - */ -goog.ui.editor.LinkDialog.prototype.onUrlOrEmailInputChange_ = function() { - if (this.autogenerateTextToDisplay_) { - this.setTextToDisplayFromAuto_(); - } else if (this.textToDisplayInput_.value == '') { - this.setAutogenFlagFromCurInput_(); - } - this.syncOkButton_(); -}; - - -/** - * Called when the currently selected tab changes. - * @param {goog.events.Event} e The tab change event. - * @private - */ -goog.ui.editor.LinkDialog.prototype.onChangeTab_ = function(e) { - var tab = /** @type {goog.ui.Tab} */ (e.target); - - // Focus on the input field in the selected tab. - var input = this.dom.getElement(tab.getId() + - goog.ui.editor.LinkDialog.Id_.TAB_INPUT_SUFFIX); - goog.editor.focus.focusInputField(input); - - // For some reason, IE does not fire onpropertychange events when the width - // is specified as a percentage, which breaks the InputHandlers. - input.style.width = ''; - input.style.width = input.offsetWidth + 'px'; - - this.syncOkButton_(); - this.setTextToDisplayFromAuto_(); -}; - - -/** - * If autogen is turned on, set the value of text to display based on the - * current selection or url. - * @private - */ -goog.ui.editor.LinkDialog.prototype.setTextToDisplayFromAuto_ = function() { - if (this.autogenFeatureEnabled_ && this.autogenerateTextToDisplay_) { - var inputId = this.tabPane_.getCurrentTabId() + - goog.ui.editor.LinkDialog.Id_.TAB_INPUT_SUFFIX; - this.textToDisplayInput_.value = - /** @type {HTMLInputElement} */(this.dom.getElement(inputId)).value; - } -}; - - -/** - * Turn on the autogenerate text to display flag, and set some sort of indicator - * that autogen is on. - * @param {boolean} val Boolean value to set autogenerate to. - * @private - */ -goog.ui.editor.LinkDialog.prototype.setAutogenFlag_ = function(val) { - // TODO(user): This whole autogen thing is very confusing. It needs - // to be refactored and/or explained. - this.autogenerateTextToDisplay_ = val; -}; - - -/** - * Disables autogen so that onUrlOrEmailInputChange_ doesn't act in cases - * that are undesirable. - * @param {boolean} autogen Boolean value to set disableAutogen to. - * @private - */ -goog.ui.editor.LinkDialog.prototype.disableAutogenFlag_ = function(autogen) { - this.setAutogenFlag_(!autogen); - this.disableAutogen_ = autogen; -}; - - -/** - * Creates an OK event from the text to display input and the specified link. - * If text to display input is empty, then generate the auto value for it. - * @return {goog.ui.editor.LinkDialog.OkEvent} The event object to be used when - * dispatching the OK event to listeners. - * @param {string} url Url the target element should point to. - * @private - */ -goog.ui.editor.LinkDialog.prototype.createOkEventFromUrl_ = function(url) { - // Fill in the text to display input in case it is empty. - this.setTextToDisplayFromAuto_(); - if (this.showOpenLinkInNewWindow_) { - // Save checkbox state for next time. - this.isOpenLinkInNewWindowChecked_ = this.openInNewWindowCheckbox_.checked; - } - return new goog.ui.editor.LinkDialog.OkEvent(this.textToDisplayInput_.value, - url, this.showOpenLinkInNewWindow_ && this.isOpenLinkInNewWindowChecked_); -}; - - -/** - * If an email or url is being edited, set autogenerate to on if the text to - * display matches the url. - * @private - */ -goog.ui.editor.LinkDialog.prototype.setAutogenFlagFromCurInput_ = function() { - var autogen = false; - if (!this.disableAutogen_) { - var tabInput = this.dom.getElement(this.tabPane_.getCurrentTabId() + - goog.ui.editor.LinkDialog.Id_.TAB_INPUT_SUFFIX); - autogen = (tabInput.value == this.textToDisplayInput_.value); - } - this.setAutogenFlag_(autogen); -}; - - -/** - * @return {boolean} Whether the link is new. - * @private - */ -goog.ui.editor.LinkDialog.prototype.isNewLink_ = function() { - return this.targetLink_.isNew(); -}; - - -/** - * IDs for relevant DOM elements. - * @enum {string} - * @private - */ -goog.ui.editor.LinkDialog.Id_ = { - TEXT_TO_DISPLAY: 'linkdialog-text', - ON_WEB_TAB: 'linkdialog-onweb', - ON_WEB_INPUT: 'linkdialog-onweb-tab-input', - EMAIL_ADDRESS_TAB: 'linkdialog-email', - EMAIL_ADDRESS_INPUT: 'linkdialog-email-tab-input', - EMAIL_WARNING: 'linkdialog-email-warning', - TAB_INPUT_SUFFIX: '-tab-input' -}; - - -/** - * Class name for the url and email input elements. - * @type {string} - * @private - */ -goog.ui.editor.LinkDialog.TARGET_INPUT_CLASSNAME_ = - goog.getCssName('tr-link-dialog-target-input'); - - -/** - * Class name for the email address warning element. - * @type {string} - * @private - */ -goog.ui.editor.LinkDialog.EMAIL_WARNING_CLASSNAME_ = - goog.getCssName('tr-link-dialog-email-warning'); - - -/** - * Class name for the explanation text elements. - * @type {string} - * @private - */ -goog.ui.editor.LinkDialog.EXPLANATION_TEXT_CLASSNAME_ = - goog.getCssName('tr-link-dialog-explanation-text'); diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/linkdialog_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/linkdialog_test.html.svn-base deleted file mode 100644 index bee15b9..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/linkdialog_test.html.svn-base +++ /dev/null @@ -1,556 +0,0 @@ -<!DOCTYPE html> -<html> -<!-- -Copyright 2010 The Closure Library Authors. All Rights Reserved. - -Use of this source code is governed by the Apache License, Version 2.0. -See the COPYING file for details. ---> -<!-- ---> -<head> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<title>goog.ui.editor.LinkDialog Tests</title> -<script src="../../base.js"></script> -<script> - goog.require('goog.dom'); - goog.require('goog.dom.DomHelper'); - goog.require('goog.editor.BrowserFeature'); - goog.require('goog.editor.Link'); - goog.require('goog.events.Event'); - goog.require('goog.events.EventHandler'); - goog.require('goog.math.Size'); - goog.require('goog.testing.MockControl'); - goog.require('goog.testing.PropertyReplacer'); - goog.require('goog.testing.dom'); - goog.require('goog.testing.events'); - goog.require('goog.testing.jsunit'); - goog.require('goog.testing.mockmatchers'); - goog.require('goog.testing.mockmatchers.ArgumentMatcher'); - goog.require('goog.ui.editor.AbstractDialog.EventType'); - goog.require('goog.ui.editor.LinkDialog'); - goog.require('goog.ui.editor.LinkDialog.OkEvent'); - goog.require('goog.ui.editor.messages'); -</script> -<link rel="stylesheet" href="../../css/dialog.css"/> -<link rel="stylesheet" href="../../css/linkbutton.css"/> -<link rel="stylesheet" href="../../css/editor/dialog.css"/> -<link rel="stylesheet" href="../../css/editor/linkdialog.css"/> -</head> -<body> - <iframe id="appWindowIframe" src="javascript:''"></iframe> -<script> - - var dialog; - var mockCtrl; - var mockLink; - var mockOkHandler; - var mockGetViewportSize; - var mockWindowOpen; - var isNew; - var anchorElem; - var stubs = new goog.testing.PropertyReplacer(); - - var ANCHOR_TEXT = 'anchor text'; - var ANCHOR_URL = 'http://www.google.com/'; - var ANCHOR_EMAIL = 'm@r.cos'; - var ANCHOR_MAILTO = 'mailto:' + ANCHOR_EMAIL; - - function setUp() { - anchorElem = goog.dom.createElement(goog.dom.TagName.A); - goog.dom.appendChild(goog.dom.getDocument().body, anchorElem); - - mockCtrl = new goog.testing.MockControl(); - mockLink = mockCtrl.createLooseMock(goog.editor.Link); - mockOkHandler = mockCtrl.createLooseMock(goog.events.EventHandler); - - isNew = false; - mockLink.isNew(); - mockLink.$anyTimes(); - mockLink.$does(function() { - return isNew; - }); - mockLink.getCurrentText(); - mockLink.$anyTimes(); - mockLink.$does(function() { - return anchorElem.innerHTML; - }); - mockLink.setTextAndUrl(goog.testing.mockmatchers.isString, - goog.testing.mockmatchers.isString); - mockLink.$anyTimes(); - mockLink.$does(function(text, url) { - anchorElem.innerHTML = text; - anchorElem.href = url; - }); - mockLink.$registerArgumentListVerifier('placeCursorRightOf', function() { - return true; - }); - mockLink.placeCursorRightOf(goog.testing.mockmatchers.iBoolean); - mockLink.$anyTimes(); - mockLink.getAnchor(); - mockLink.$anyTimes(); - mockLink.$returns(anchorElem); - - mockWindowOpen = mockCtrl.createFunctionMock('open'); - stubs.set(window, 'open', mockWindowOpen); - } - - function tearDown() { - dialog.dispose(); - goog.dom.removeNode(anchorElem); - stubs.reset(); - } - - function setUpAnchor(href, text, opt_isNew, opt_target) { - anchorElem.href = href; - anchorElem.innerHTML = text; - isNew = !!opt_isNew; - if (opt_target) { - anchorElem.target = opt_target; - } - } - - /** - * Creates and shows the dialog to be tested. - * @param {Document=} opt_document Document to render the dialog into. - * Defaults to the main window's document. - * @param {boolean=} opt_openInNewWindow Whether the open in new window - * checkbox should be shown. - */ - function createAndShow(opt_document, opt_openInNewWindow) { - dialog = new goog.ui.editor.LinkDialog(new goog.dom.DomHelper(opt_document), - mockLink); - if (opt_openInNewWindow) { - dialog.showOpenLinkInNewWindow(false); - } - dialog.addEventListener(goog.ui.editor.AbstractDialog.EventType.OK, - mockOkHandler); - dialog.show(); - } - - /** - * Sets up the mock event handler to expect an OK event with the given text - * and url. - */ - function expectOk(linkText, linkUrl, opt_openInNewWindow) { - mockOkHandler.handleEvent(new goog.testing.mockmatchers.ArgumentMatcher( - function(arg) { - return arg.type == goog.ui.editor.AbstractDialog.EventType.OK && - arg.linkText == linkText && - arg.linkUrl == linkUrl && - arg.openInNewWindow == !!opt_openInNewWindow; - }, - '{linkText: ' + linkText + ', linkUrl: ' + linkUrl + - ', openInNewWindow: ' + opt_openInNewWindow + '}')); - } - - /** - * Tests that when you show the dialog for a new link, the input fields are - * empty, the web tab is selected and focus is in the url input field. - * @param {Document=} opt_document Document to render the dialog into. - * Defaults to the main window's document. - */ - function testShowForNewLink(opt_document) { - mockCtrl.$replayAll(); - setUpAnchor('', '', true); // Must be done before creating the dialog. - createAndShow(opt_document); - - assertEquals('Display text input field should be empty', - '', - getDisplayInputText()); - assertEquals('Url input field should be empty', - '', - getUrlInputText()); - assertEquals('On the web tab should be selected', - goog.ui.editor.LinkDialog.Id_.ON_WEB, - dialog.curTabId_); - if (goog.editor.BrowserFeature.HAS_ACTIVE_ELEMENT) { - assertEquals('Focus should be on url input', - getUrlInput(), - dialog.dom.getDocument().activeElement); - } - - mockCtrl.$verifyAll(); - } - - /** - * Fakes that the mock field is using an iframe and does the same test as - * testShowForNewLink(). - */ - function testShowForNewLinkWithDiffAppWindow() { - testShowForNewLink(goog.dom.getElement('appWindowIframe').contentDocument); - } - - /** - * Tests that when you show the dialog for a url link, the input fields are - * filled in, the web tab is selected and focus is in the url input field. - */ - function testShowForUrlLink() { - mockCtrl.$replayAll(); - setUpAnchor(ANCHOR_URL, ANCHOR_TEXT); - createAndShow(); - - assertEquals('Display text input field should be filled in', - ANCHOR_TEXT, - getDisplayInputText()); - assertEquals('Url input field should be filled in', - ANCHOR_URL, - getUrlInputText()); - assertEquals('On the web tab should be selected', - goog.ui.editor.LinkDialog.Id_.ON_WEB, - dialog.curTabId_); - if (goog.editor.BrowserFeature.HAS_ACTIVE_ELEMENT) { - assertEquals('Focus should be on url input', - getUrlInput(), - dialog.dom.getDocument().activeElement); - } - - mockCtrl.$verifyAll(); - } - - /** - * Tests that when you show the dialog for a mailto link, the input fields are - * filled in, the email tab is selected and focus is in the email input field. - */ - function testShowForMailtoLink() { - mockCtrl.$replayAll(); - setUpAnchor(ANCHOR_MAILTO, ANCHOR_TEXT); - createAndShow(); - - assertEquals('Display text input field should be filled in', - ANCHOR_TEXT, - getDisplayInputText()); - assertEquals('Email input field should be filled in', - ANCHOR_EMAIL, // The 'mailto:' is not in the input! - getEmailInputText()); - assertEquals('Email tab should be selected', - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS, - dialog.curTabId_); - if (goog.editor.BrowserFeature.HAS_ACTIVE_ELEMENT) { - assertEquals('Focus should be on email input', - getEmailInput(), - dialog.dom.getDocument().activeElement); - } - - mockCtrl.$verifyAll(); - } - - /** - * Tests that the display text is autogenerated from the url input in the - * right situations (and not generated when appropriate too). - */ - function testAutogeneration() { - mockCtrl.$replayAll(); - setUpAnchor('', '', true); - createAndShow(); - - // Simulate typing a url when everything is empty, should autogen. - setUrlInputText(ANCHOR_URL); - assertEquals('Display text should have been autogenerated', - ANCHOR_URL, - getDisplayInputText()); - - // Simulate typing text when url is set, afterwards should not autogen. - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_MAILTO); - assertNotEquals('Display text should not have been autogenerated', - ANCHOR_MAILTO, - getDisplayInputText()); - assertEquals('Display text should have remained the same', - ANCHOR_TEXT, - getDisplayInputText()); - - // Simulate typing text equal to existing url, afterwards should autogen. - setDisplayInputText(ANCHOR_MAILTO); - setUrlInputText(ANCHOR_URL); - assertEquals('Display text should have been autogenerated', - ANCHOR_URL, - getDisplayInputText()); - - mockCtrl.$verifyAll(); - } - - /** - * Tests that the display text is not autogenerated from the url input in all - * situations when the autogeneration feature is turned off. - */ - function testAutogenerationOff() { - mockCtrl.$replayAll(); - - setUpAnchor('', '', true); - createAndShow(); - - // Disable the autogen feature - dialog.setAutogenFeatureEnabled(false); - - // Simulate typing a url when everything is empty, should not autogen. - setUrlInputText(ANCHOR_URL); - assertEquals('Display text should not have been autogenerated', - '', - getDisplayInputText()); - - // Simulate typing text when url is set, afterwards should not autogen. - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_MAILTO); - assertNotEquals('Display text should not have been autogenerated', - ANCHOR_MAILTO, - getDisplayInputText()); - assertEquals('Display text should have remained the same', - ANCHOR_TEXT, - getDisplayInputText()); - - // Simulate typing text equal to existing url, afterwards should not - // autogen. - setDisplayInputText(ANCHOR_MAILTO); - setUrlInputText(ANCHOR_URL); - assertEquals('Display text should not have been autogenerated', - ANCHOR_MAILTO, - getDisplayInputText()); - - mockCtrl.$verifyAll(); - } - - /** - * Tests that clicking OK with the url tab selected dispatches an event with - * the proper link data. - */ - function testOkForUrl() { - expectOk(ANCHOR_TEXT, ANCHOR_URL); - mockCtrl.$replayAll(); - setUpAnchor('', '', true); - createAndShow(); - - dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_URL); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - - mockCtrl.$verifyAll(); - } - - /** - * Tests that clicking OK with the url tab selected but with an email address - * in the url field dispatches an event with the proper link data. - */ - function testOkForUrlWithEmail() { - expectOk(ANCHOR_TEXT, ANCHOR_MAILTO); - mockCtrl.$replayAll(); - setUpAnchor('', '', true); - createAndShow(); - - dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_EMAIL); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - - mockCtrl.$verifyAll(); - } - - /** - * Tests that clicking OK with the email tab selected dispatches an event with - * the proper link data. - */ - function testOkForEmail() { - expectOk(ANCHOR_TEXT, ANCHOR_MAILTO); - mockCtrl.$replayAll(); - setUpAnchor('', '', true); - createAndShow(); - - dialog.tabPane_.setSelectedTabId( - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB); - - setDisplayInputText(ANCHOR_TEXT); - setEmailInputText(ANCHOR_EMAIL); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - - mockCtrl.$verifyAll(); - } - - function testOpenLinkInNewWindowNewLink() { - expectOk(ANCHOR_TEXT, ANCHOR_URL, true); - expectOk(ANCHOR_TEXT, ANCHOR_URL, false); - mockCtrl.$replayAll(); - - setUpAnchor('', '', true); - createAndShow(undefined, true); - dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_URL); - - assertFalse('"Open in new window" should start unchecked', - getOpenInNewWindowCheckboxChecked()); - setOpenInNewWindowCheckboxChecked(true); - assertTrue('"Open in new window" should have gotten checked', - getOpenInNewWindowCheckboxChecked()); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - - // Reopen same dialog - dialog.show(); - dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_URL); - - assertTrue('"Open in new window" should remember it was checked', - getOpenInNewWindowCheckboxChecked()); - setOpenInNewWindowCheckboxChecked(false); - assertFalse('"Open in new window" should have gotten unchecked', - getOpenInNewWindowCheckboxChecked()); - goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); - } - - function testOpenLinkInNewWindowExistingLink() { - mockCtrl.$replayAll(); - - // Edit an existing link that already opens in a new window. - setUpAnchor('', '', false, '_blank'); - createAndShow(undefined, true); - dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); - setDisplayInputText(ANCHOR_TEXT); - setUrlInputText(ANCHOR_URL); - - assertTrue('"Open in new window" should start checked for existing link', - getOpenInNewWindowCheckboxChecked()); - - mockCtrl.$verifyAll(); - } - - /** - * Test that clicking on the test button opens a new window with the correct - * options. - */ - function testWebTestButton() { - if (goog.userAgent.GECKO) { - // TODO(robbyw): Figure out why this is flaky and fix it. - return; - } - - var width, height; - mockWindowOpen(ANCHOR_URL, '_blank', - new goog.testing.mockmatchers.ArgumentMatcher(function(str) { - return str == 'width=' + width + ',height=' + height + - ',toolbar=1,scrollbars=1,location=1,statusbar=0,' + - 'menubar=1,resizable=1' - }, "3rd arg: (string) window.open() options")); - - mockCtrl.$replayAll(); - setUpAnchor(ANCHOR_URL, ANCHOR_TEXT); - createAndShow(); - - // Measure viewport after opening dialog because that might cause scrollbars - // to appear and reduce the viewport size. - var size = goog.dom.getViewportSize(window); - width = Math.max(size.width - 50, 50); - height = Math.max(size.height - 50, 50); - - var testLink = goog.testing.dom.findTextNode( - goog.ui.editor.messages.MSG_TEST_THIS_LINK, - dialog.dialogInternal_.getElement()); - goog.testing.events.fireClickSequence(testLink.parentNode); - - mockCtrl.$verifyAll(); - } - - /** - * Test that clicking on the test button does not open a new window when - * the event is canceled. - */ - function testWebTestButtonPreventDefault() { - mockCtrl.$replayAll(); - setUpAnchor(ANCHOR_URL, ANCHOR_TEXT); - createAndShow(); - - goog.events.listen(dialog, - goog.ui.editor.LinkDialog.EventType.BEFORE_TEST_LINK, - function(e) { - assertEquals(e.url, ANCHOR_URL); - e.preventDefault(); - }); - var testLink = goog.testing.dom.findTextNode( - goog.ui.editor.messages.MSG_TEST_THIS_LINK, - dialog.dialogInternal_.getElement()); - goog.testing.events.fireClickSequence(testLink.parentNode); - - mockCtrl.$verifyAll(); - } - - /** - * Test that the setTextToDisplayVisible() correctly works. - * options. - */ - function testSetTextToDisplayVisible() { - mockCtrl.$replayAll(); - setUpAnchor('', '', true); - createAndShow(); - - assertNotEquals('none', - goog.style.getStyle(dialog.textToDisplayDiv_, 'display')); - dialog.setTextToDisplayVisible(false); - assertEquals('none', - goog.style.getStyle(dialog.textToDisplayDiv_, 'display')); - dialog.setTextToDisplayVisible(true); - assertNotEquals('none', - goog.style.getStyle(dialog.textToDisplayDiv_, 'display')); - - mockCtrl.$verifyAll(); - } - - function getDisplayInput() { - return dialog.dom.getElement(goog.ui.editor.LinkDialog.Id_.TEXT_TO_DISPLAY); - } - - function getDisplayInputText() { - return getDisplayInput().value; - } - - function setDisplayInputText(text) { - var textInput = getDisplayInput(); - textInput.value = text; - // Fire event so that dialog behaves like when user types. - goog.testing.events.fireBrowserEvent(new goog.events.Event('keyup', - textInput)); - } - - function getUrlInput() { - return dialog.dom.getElement(goog.ui.editor.LinkDialog.Id_.ON_WEB_INPUT); - } - - function getUrlInputText() { - return getUrlInput().value; - } - - function setUrlInputText(text) { - var urlInput = getUrlInput(); - urlInput.value = text; - // Fire event so that dialog behaves like when user types. - dialog.urlInputHandler_.dispatchEvent( - goog.events.InputHandler.EventType.INPUT); - } - - function getEmailInput() { - return dialog.dom.getElement( - goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_INPUT); - } - - function getEmailInputText() { - return getEmailInput().value; - } - - function setEmailInputText(text) { - var emailInput = getEmailInput(); - emailInput.value = text; - // Fire event so that dialog behaves like when user types. - dialog.emailInputHandler_.dispatchEvent( - goog.events.InputHandler.EventType.INPUT); - } - - function getOpenInNewWindowCheckboxChecked() { - return dialog.openInNewWindowCheckbox_.checked; - } - - function setOpenInNewWindowCheckboxChecked(checked) { - dialog.openInNewWindowCheckbox_.checked = checked; - } - -</script> -</body> -</html> diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/messages.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/messages.js.svn-base deleted file mode 100644 index ca09f61..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/messages.js.svn-base +++ /dev/null @@ -1,123 +0,0 @@ -// 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. - -/** - * @fileoverview Messages common to Editor UI components. - * - * @author robbyw@google.com (Robby Walker) - */ - -goog.provide('goog.ui.editor.messages'); - - -/** @desc Link button / bubble caption. */ -goog.ui.editor.messages.MSG_LINK_CAPTION = goog.getMsg('Link'); - - -/** @desc Title for the dialog that edits a link. */ -goog.ui.editor.messages.MSG_EDIT_LINK = goog.getMsg('Edit Link'); - - -/** @desc Prompt the user for the text of the link they've written. */ -goog.ui.editor.messages.MSG_TEXT_TO_DISPLAY = goog.getMsg('Text to display:'); - - -/** @desc Prompt the user for the URL of the link they've created. */ -goog.ui.editor.messages.MSG_LINK_TO = goog.getMsg('Link to:'); - - -/** @desc Prompt the user to type a web address for their link. */ -goog.ui.editor.messages.MSG_ON_THE_WEB = goog.getMsg('Web address'); - - -/** @desc More details on what linking to a web address involves.. */ -goog.ui.editor.messages.MSG_ON_THE_WEB_TIP = goog.getMsg( - 'Link to a page or file somewhere else on the web'); - - -/** - * @desc Text for a button that allows the user to test the link that - * they created. - */ -goog.ui.editor.messages.MSG_TEST_THIS_LINK = goog.getMsg('Test this link'); - - -/** - * @desc Explanation for how to create a link with the link-editing dialog. - */ -goog.ui.editor.messages.MSG_TR_LINK_EXPLANATION = goog.getMsg( - '{$startBold}Not sure what to put in the box?{$endBold} ' + - 'First, find the page on the web that you want to ' + - 'link to. (A {$searchEngineLink}search engine{$endLink} ' + - 'might be useful.) Then, copy the web address from ' + - "the box in your browser's address bar, and paste it into " + - 'the box above.', - {'startBold': '<b>', - 'endBold': '</b>', - 'searchEngineLink': "<a href='http://www.google.com/' target='_new'>", - 'endLink': '</a>'}); - - -/** @desc Prompt for the URL of a link that the user is creating. */ -goog.ui.editor.messages.MSG_WHAT_URL = goog.getMsg( - 'To what URL should this link go?'); - - -/** - * @desc Prompt for an email address, so that the user can create a link - * that sends an email. - */ -goog.ui.editor.messages.MSG_EMAIL_ADDRESS = goog.getMsg('Email address'); - - -/** - * @desc Explanation of the prompt for an email address in a link. - */ -goog.ui.editor.messages.MSG_EMAIL_ADDRESS_TIP = goog.getMsg( - 'Link to an email address'); - - -/** @desc Error message when the user enters an invalid email address. */ -goog.ui.editor.messages.MSG_INVALID_EMAIL = goog.getMsg( - 'Invalid email address'); - - -/** - * @desc When the user creates a mailto link, asks them what email - * address clicking on this link will send mail to. - */ -goog.ui.editor.messages.MSG_WHAT_EMAIL = goog.getMsg( - 'To what email address should this link?'); - - -/** - * @desc Warning about the dangers of creating links with email - * addresses in them. - */ -goog.ui.editor.messages.MSG_EMAIL_EXPLANATION = goog.getMsg( - '{$preb}Be careful.{$postb} ' + - 'Remember that any time you include an email address on a web page, ' + - 'nasty spammers can find it too.', {'preb': '<b>', 'postb': '</b>'}); - - -/** - * @desc Label for the checkbox that allows the user to specify what when this - * link is clicked, it should be opened in a new window. - */ -goog.ui.editor.messages.MSG_OPEN_IN_NEW_WINDOW = goog.getMsg( - 'Open this link in a new window'); - - -/** @desc Image bubble caption. */ -goog.ui.editor.messages.MSG_IMAGE_CAPTION = goog.getMsg('Image'); diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/tabpane.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/tabpane.js.svn-base deleted file mode 100644 index 92a5981..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/tabpane.js.svn-base +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2010 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 Tabbed pane with style and functionality specific to - * Editor dialogs. - * - * @author robbyw@google.com (Robby Walker) - */ - -goog.provide('goog.ui.editor.TabPane'); - -goog.require('goog.dom.TagName'); -goog.require('goog.events.EventHandler'); -goog.require('goog.ui.Component'); -goog.require('goog.ui.Control'); -goog.require('goog.ui.Tab'); -goog.require('goog.ui.TabBar'); - - - -/** - * Creates a new Editor-style tab pane. - * @param {goog.dom.DomHelper} dom The dom helper for the window to create this - * tab pane in. - * @param {string=} opt_caption Optional caption of the tab pane. - * @constructor - * @extends {goog.ui.Component} - */ -goog.ui.editor.TabPane = function(dom, opt_caption) { - goog.base(this, dom); - - /** - * The event handler used to register events. - * @type {goog.events.EventHandler} - * @private - */ - this.eventHandler_ = new goog.events.EventHandler(this); - - /** - * The tab bar used to render the tabs. - * @type {goog.ui.TabBar} - * @private - */ - this.tabBar_ = new goog.ui.TabBar(goog.ui.TabBar.Location.START, - undefined, this.dom_); - this.tabBar_.setFocusable(false); - - /** - * The content element. - * @private - */ - this.tabContent_ = this.dom_.createDom(goog.dom.TagName.DIV, - {className: goog.getCssName('goog-tab-content')}); - - /** - * The currently selected radio button. - * @type {Element} - * @private - */ - this.selectedRadio_ = null; - - /** - * The currently visible tab content. - * @type {Element} - * @private - */ - this.visibleContent_ = null; - - - // Add the caption as the first element in the tab bar. - if (opt_caption) { - var captionControl = new goog.ui.Control(opt_caption, undefined, - this.dom_); - captionControl.addClassName(goog.getCssName('tr-tabpane-caption')); - captionControl.setEnabled(false); - this.tabBar_.addChild(captionControl, true); - } -}; -goog.inherits(goog.ui.editor.TabPane, goog.ui.Component); - - -/** - * @return {string} The ID of the content element for the current tab. - */ -goog.ui.editor.TabPane.prototype.getCurrentTabId = function() { - return this.tabBar_.getSelectedTab().getId(); -}; - - -/** - * Selects the tab with the given id. - * @param {string} id Id of the tab to select. - */ -goog.ui.editor.TabPane.prototype.setSelectedTabId = function(id) { - this.tabBar_.setSelectedTab(this.tabBar_.getChild(id)); -}; - - -/** - * Adds a tab to the tab pane. - * @param {string} id The id of the tab to add. - * @param {string} caption The caption of the tab. - * @param {string} tooltip The tooltip for the tab. - * @param {Element} content The content element to show when this tab is - * selected. - */ -goog.ui.editor.TabPane.prototype.addTab = function(id, caption, tooltip, - content) { - var radio = this.dom_.createDom(goog.dom.TagName.INPUT, {type: 'radio'}); - - var tab = new goog.ui.Tab([radio, this.dom_.createTextNode(caption)], - undefined, this.dom_); - tab.setId(id); - tab.setTooltip(tooltip); - this.tabBar_.addChild(tab, true); - - this.eventHandler_.listen(radio, goog.events.EventType.SELECT, - goog.bind(this.tabBar_.setSelectedTab, this.tabBar_, tab)); - - content.id = id + '-tab'; - this.tabContent_.appendChild(content); - goog.style.showElement(content, false); -}; - - -/** @override */ -goog.ui.editor.TabPane.prototype.enterDocument = function() { - goog.base(this, 'enterDocument'); - - // Get the root element and add a class name to it. - var root = this.getElement(); - goog.dom.classes.add(root, goog.getCssName('tr-tabpane')); - - // Add the tabs. - this.addChild(this.tabBar_, true); - this.eventHandler_.listen(this.tabBar_, goog.ui.Component.EventType.SELECT, - this.handleTabSelect_); - - // Add the tab content. - root.appendChild(this.tabContent_); - - // Add an element to clear the tab float. - root.appendChild( - this.dom_.createDom(goog.dom.TagName.DIV, - {className: goog.getCssName('goog-tab-bar-clear')})); -}; - - -/** - * Handles a tab change. - * @param {goog.events.Event} e The browser change event. - * @private - */ -goog.ui.editor.TabPane.prototype.handleTabSelect_ = function(e) { - var tab = /** @type {goog.ui.Tab} */ (e.target); - - // Show the tab content. - if (this.visibleContent_) { - goog.style.showElement(this.visibleContent_, false); - } - this.visibleContent_ = this.dom_.getElement(tab.getId() + '-tab'); - goog.style.showElement(this.visibleContent_, true); - - // Select the appropriate radio button (and deselect the current one). - if (this.selectedRadio_) { - this.selectedRadio_.checked = false; - } - this.selectedRadio_ = tab.getElement().getElementsByTagName( - goog.dom.TagName.INPUT)[0]; - this.selectedRadio_.checked = true; -}; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarcontroller.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarcontroller.js.svn-base deleted file mode 100644 index eed44a4..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarcontroller.js.svn-base +++ /dev/null @@ -1,295 +0,0 @@ -// 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. - -/** - * @fileoverview A class for managing the editor toolbar. - * - * @author attila@google.com (Attila Bodis) - * @author jparent@google.com (Julie Parent) - * @see ../../demos/editor/editor.html - */ - -goog.provide('goog.ui.editor.ToolbarController'); - -goog.require('goog.editor.Field.EventType'); -goog.require('goog.events.EventHandler'); -goog.require('goog.events.EventTarget'); -goog.require('goog.ui.Component.EventType'); - - - -/** - * A class for managing the editor toolbar. Acts as a bridge between - * a {@link goog.editor.Field} and a {@link goog.ui.Toolbar}. - * - * The {@code toolbar} argument must be an instance of {@link goog.ui.Toolbar} - * or a subclass. This class doesn't care how the toolbar was created. As - * long as one or more controls hosted in the toolbar have IDs that match - * built-in {@link goog.editor.Command}s, they will function as expected. It is - * the caller's responsibility to ensure that the toolbar is already rendered - * or that it decorates an existing element. - * - * - * @param {!goog.editor.Field} field Editable field to be controlled by the - * toolbar. - * @param {!goog.ui.Toolbar} toolbar Toolbar to control the editable field. - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.ui.editor.ToolbarController = function(field, toolbar) { - goog.events.EventTarget.call(this); - - /** - * Event handler to listen for field events and user actions. - * @type {!goog.events.EventHandler} - * @private - */ - this.handler_ = new goog.events.EventHandler(this); - - /** - * The field instance controlled by the toolbar. - * @type {!goog.editor.Field} - * @private - */ - this.field_ = field; - - /** - * The toolbar that controls the field. - * @type {!goog.ui.Toolbar} - * @private - */ - this.toolbar_ = toolbar; - - /** - * Editing commands whose state is to be queried when updating the toolbar. - * @type {!Array.<string>} - * @private - */ - this.queryCommands_ = []; - - // Iterate over all buttons, and find those which correspond to - // queryable commands. Add them to the list of commands to query on - // each COMMAND_VALUE_CHANGE event. - this.toolbar_.forEachChild(function(button) { - if (button.queryable) { - this.queryCommands_.push(this.getComponentId(button.getId())); - } - }, this); - - // Make sure the toolbar doesn't steal keyboard focus. - this.toolbar_.setFocusable(false); - - // Hook up handlers that update the toolbar in response to field events, - // and to execute editor commands in response to toolbar events. - this.handler_. - listen(this.field_, goog.editor.Field.EventType.COMMAND_VALUE_CHANGE, - this.updateToolbar). - listen(this.toolbar_, goog.ui.Component.EventType.ACTION, - this.handleAction); -}; -goog.inherits(goog.ui.editor.ToolbarController, goog.events.EventTarget); - - -/** - * Returns the Closure component ID of the control that corresponds to the - * given {@link goog.editor.Command} constant. - * Subclasses may override this method if they want to use a custom mapping - * scheme from commands to controls. - * @param {string} command Editor command. - * @return {string} Closure component ID of the corresponding toolbar - * control, if any. - * @protected - */ -goog.ui.editor.ToolbarController.prototype.getComponentId = function(command) { - // The default implementation assumes that the component ID is the same as - // the command constant. - return command; -}; - - -/** - * Returns the {@link goog.editor.Command} constant - * that corresponds to the given Closure component ID. Subclasses may override - * this method if they want to use a custom mapping scheme from controls to - * commands. - * @param {string} id Closure component ID of a toolbar control. - * @return {string} Editor command or dialog constant corresponding to the - * toolbar control, if any. - * @protected - */ -goog.ui.editor.ToolbarController.prototype.getCommand = function(id) { - // The default implementation assumes that the component ID is the same as - // the command constant. - return id; -}; - - -/** - * Returns the event handler object for the editor toolbar. Useful for classes - * that extend {@code goog.ui.editor.ToolbarController}. - * @return {!goog.events.EventHandler} The event handler object. - * @protected - */ -goog.ui.editor.ToolbarController.prototype.getHandler = function() { - return this.handler_; -}; - - -/** - * Returns the field instance managed by the toolbar. Useful for - * classes that extend {@code goog.ui.editor.ToolbarController}. - * @return {!goog.editor.Field} The field managed by the toolbar. - * @protected - */ -goog.ui.editor.ToolbarController.prototype.getField = function() { - return this.field_; -}; - - -/** - * Returns the toolbar UI component that manages the editor. Useful for - * classes that extend {@code goog.ui.editor.ToolbarController}. - * @return {!goog.ui.Toolbar} The toolbar UI component. - */ -goog.ui.editor.ToolbarController.prototype.getToolbar = function() { - return this.toolbar_; -}; - - -/** - * @return {boolean} Whether the toolbar is visible. - */ -goog.ui.editor.ToolbarController.prototype.isVisible = function() { - return this.toolbar_.isVisible(); -}; - - -/** - * Shows or hides the toolbar. - * @param {boolean} visible Whether to show or hide the toolbar. - */ -goog.ui.editor.ToolbarController.prototype.setVisible = function(visible) { - this.toolbar_.setVisible(visible); -}; - - -/** - * @return {boolean} Whether the toolbar is enabled. - */ -goog.ui.editor.ToolbarController.prototype.isEnabled = function() { - return this.toolbar_.isEnabled(); -}; - - -/** - * Enables or disables the toolbar. - * @param {boolean} enabled Whether to enable or disable the toolbar. - */ -goog.ui.editor.ToolbarController.prototype.setEnabled = function(enabled) { - this.toolbar_.setEnabled(enabled); -}; - - -/** - * Programmatically blurs the editor toolbar, un-highlighting the currently - * highlighted item, and closing the currently open menu (if any). - */ -goog.ui.editor.ToolbarController.prototype.blur = function() { - // We can't just call this.toolbar_.getElement().blur(), because the toolbar - // element itself isn't focusable, so goog.ui.Container#handleBlur isn't - // registered to handle blur events. - this.toolbar_.handleBlur(null); -}; - - -/** @override */ -goog.ui.editor.ToolbarController.prototype.disposeInternal = function() { - goog.ui.editor.ToolbarController.superClass_.disposeInternal.call(this); - if (this.handler_) { - this.handler_.dispose(); - delete this.handler_; - } - if (this.toolbar_) { - this.toolbar_.dispose(); - delete this.toolbar_; - } - delete this.field_; - delete this.queryCommands_; -}; - - -/** - * Updates the toolbar in response to editor events. Specifically, updates - * button states based on {@code COMMAND_VALUE_CHANGE} events, reflecting the - * effective formatting of the selection. - * @param {goog.events.Event} e Editor event to handle. - * @protected - */ -goog.ui.editor.ToolbarController.prototype.updateToolbar = function(e) { - if (!this.toolbar_.isEnabled() || - !this.dispatchEvent(goog.ui.Component.EventType.CHANGE)) { - return; - } - - var state; - - /** @preserveTry */ - try { - /** @type {Array.<string>} */ - e.commands; // Added by dispatchEvent. - - // If the COMMAND_VALUE_CHANGE event specifies which commands changed - // state, then we only need to update those ones, otherwise update all - // commands. - state = /** @type {Object} */ ( - this.field_.queryCommandValue(e.commands || this.queryCommands_)); - } catch (ex) { - // TODO(attila): Find out when/why this happens. - state = {}; - } - - this.updateToolbarFromState(state); -}; - - -/** - * Updates the toolbar to reflect a given state. - * @param {Object} state Object mapping editor commands to values. - */ -goog.ui.editor.ToolbarController.prototype.updateToolbarFromState = - function(state) { - for (var command in state) { - var button = this.toolbar_.getChild(this.getComponentId(command)); - if (button) { - var value = state[command]; - if (button.updateFromValue) { - button.updateFromValue(value); - } else { - button.setChecked(!!value); - } - } - } -}; - - -/** - * Handles {@code ACTION} events dispatched by toolbar buttons in response to - * user actions by executing the corresponding field command. - * @param {goog.events.Event} e Action event to handle. - * @protected - */ -goog.ui.editor.ToolbarController.prototype.handleAction = function(e) { - var command = this.getCommand(e.target.getId()); - this.field_.execCommand(command, e.target.getValue()); -}; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarfactory.js.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarfactory.js.svn-base deleted file mode 100644 index 6597f6b..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarfactory.js.svn-base +++ /dev/null @@ -1,440 +0,0 @@ -// 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. - -/** - * @fileoverview Generic factory functions for creating the building blocks for - * an editor toolbar. - * - * @author attila@google.com (Attila Bodis) - * @author jparent@google.com (Julie Parent) - */ - -goog.provide('goog.ui.editor.ToolbarFactory'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.string'); -goog.require('goog.string.Unicode'); -goog.require('goog.style'); -goog.require('goog.ui.Component.State'); -goog.require('goog.ui.Container.Orientation'); -goog.require('goog.ui.ControlContent'); -goog.require('goog.ui.Option'); -goog.require('goog.ui.Toolbar'); -goog.require('goog.ui.ToolbarButton'); -goog.require('goog.ui.ToolbarColorMenuButton'); -goog.require('goog.ui.ToolbarMenuButton'); -goog.require('goog.ui.ToolbarRenderer'); -goog.require('goog.ui.ToolbarSelect'); -goog.require('goog.userAgent'); - - -/** - * Takes a font spec (e.g. "Arial, Helvetica, sans-serif") and returns the - * primary font name, normalized to lowercase (e.g. "arial"). - * @param {string} fontSpec Font specification. - * @return {string} The primary font name, in lowercase. - */ -goog.ui.editor.ToolbarFactory.getPrimaryFont = function(fontSpec) { - var i = fontSpec.indexOf(','); - var fontName = (i != -1 ? fontSpec.substring(0, i) : fontSpec).toLowerCase(); - // Strip leading/trailing quotes from the font name (bug 1050118). - return goog.string.stripQuotes(fontName, '"\''); -}; - - -/** - * Bulk-adds fonts to the given font menu button. The argument must be an - * array of font descriptor objects, each of which must have the following - * attributes: - * <ul> - * <li>{@code caption} - Caption to show in the font menu (e.g. 'Tahoma') - * <li>{@code value} - Value for the corresponding 'font-family' CSS style - * (e.g. 'Tahoma, Arial, sans-serif') - * </ul> - * @param {!goog.ui.Select} button Font menu button. - * @param {!Array.<{caption: string, value: string}>} fonts Array of - * font descriptors. - */ -goog.ui.editor.ToolbarFactory.addFonts = function(button, fonts) { - goog.array.forEach(fonts, function(font) { - goog.ui.editor.ToolbarFactory.addFont(button, font.caption, font.value); - }); -}; - - -/** - * Adds a menu item to the given font menu button. The first font listed in - * the {@code value} argument is considered the font ID, so adding two items - * whose CSS style starts with the same font may lead to unpredictable results. - * @param {!goog.ui.Select} button Font menu button. - * @param {string} caption Caption to show for the font menu. - * @param {string} value Value for the corresponding 'font-family' CSS style. - */ -goog.ui.editor.ToolbarFactory.addFont = function(button, caption, value) { - // The font ID is the first font listed in the CSS style, normalized to - // lowercase. - var id = goog.ui.editor.ToolbarFactory.getPrimaryFont(value); - - // Construct the option, and add it to the button. - var option = new goog.ui.Option(caption, value, button.getDomHelper()); - option.setId(id); - button.addItem(option); - - // Captions are shown in their own font. - option.getContentElement().style.fontFamily = value; -}; - - -/** - * Bulk-adds font sizes to the given font size menu button. The argument must - * be an array of font size descriptor objects, each of which must have the - * following attributes: - * <ul> - * <li>{@code caption} - Caption to show in the font size menu (e.g. 'Huge') - * <li>{@code value} - Value for the corresponding HTML font size (e.g. 6) - * </ul> - * @param {!goog.ui.Select} button Font size menu button. - * @param {!Array.<{caption: string, value:number}>} sizes Array of font - * size descriptors. - */ -goog.ui.editor.ToolbarFactory.addFontSizes = function(button, sizes) { - goog.array.forEach(sizes, function(size) { - goog.ui.editor.ToolbarFactory.addFontSize(button, size.caption, size.value); - }); -}; - - -/** - * Adds a menu item to the given font size menu button. The {@code value} - * argument must be a legacy HTML font size in the 0-7 range. - * @param {!goog.ui.Select} button Font size menu button. - * @param {string} caption Caption to show in the font size menu. - * @param {number} value Value for the corresponding HTML font size. - */ -goog.ui.editor.ToolbarFactory.addFontSize = function(button, caption, value) { - // Construct the option, and add it to the button. - var option = new goog.ui.Option(caption, value, button.getDomHelper()); - button.addItem(option); - - // Adjust the font size of the menu item and the height of the checkbox - // element after they've been rendered by addItem(). Captions are shown in - // the corresponding font size, and lining up the checkbox is tricky. - var content = option.getContentElement(); - content.style.fontSize = - goog.ui.editor.ToolbarFactory.getPxFromLegacySize(value) + 'px'; - content.firstChild.style.height = '1.1em'; -}; - - -/** - * Converts a legacy font size specification into an equivalent pixel size. - * For example, {@code <font size="6">} is {@code font-size: 32px;}, etc. - * @param {number} fontSize Legacy font size spec in the 0-7 range. - * @return {number} Equivalent pixel size. - */ -goog.ui.editor.ToolbarFactory.getPxFromLegacySize = function(fontSize) { - return goog.ui.editor.ToolbarFactory.LEGACY_SIZE_TO_PX_MAP_[fontSize] || 10; -}; - - -/** - * Converts a pixel font size specification into an equivalent legacy size. - * For example, {@code font-size: 32px;} is {@code <font size="6">}, etc. - * If the given pixel size doesn't exactly match one of the legacy sizes, -1 is - * returned. - * @param {number} px Pixel font size. - * @return {number} Equivalent legacy size spec in the 0-7 range, or -1 if none - * exists. - */ -goog.ui.editor.ToolbarFactory.getLegacySizeFromPx = function(px) { - // Use lastIndexOf to get the largest legacy size matching the pixel size - // (most notably returning 1 instead of 0 for 10px). - return goog.array.lastIndexOf( - goog.ui.editor.ToolbarFactory.LEGACY_SIZE_TO_PX_MAP_, px); -}; - - -/** - * Map of legacy font sizes (0-7) to equivalent pixel sizes. - * @type {Array.<number>} - * @private - */ -goog.ui.editor.ToolbarFactory.LEGACY_SIZE_TO_PX_MAP_ = - [10, 10, 13, 16, 18, 24, 32, 48]; - - -/** - * Bulk-adds format options to the given "Format block" menu button. The - * argument must be an array of format option descriptor objects, each of - * which must have the following attributes: - * <ul> - * <li>{@code caption} - Caption to show in the menu (e.g. 'Minor heading') - * <li>{@code command} - Corresponding {@link goog.dom.TagName} (e.g. - * 'H4') - * </ul> - * @param {!goog.ui.Select} button "Format block" menu button. - * @param {!Array.<{caption: string, command: string}>} formats Array of format - * option descriptors. - */ -goog.ui.editor.ToolbarFactory.addFormatOptions = function(button, formats) { - goog.array.forEach(formats, function(format) { - goog.ui.editor.ToolbarFactory.addFormatOption(button, format.caption, - format.command); - }); -}; - - -/** - * Adds a menu item to the given "Format block" menu button. - * @param {!goog.ui.Select} button "Format block" menu button. - * @param {string} caption Caption to show in the menu. - * @param {goog.dom.TagName} tag Corresponding block format tag. - */ -goog.ui.editor.ToolbarFactory.addFormatOption = function(button, caption, tag) { - // Construct the option, and add it to the button. - // TODO(attila): Create boring but functional menu item for now... - var buttonDom = button.getDomHelper(); - var option = new goog.ui.Option(buttonDom.createDom(goog.dom.TagName.DIV, - null, caption), tag, buttonDom); - option.setId(tag); - button.addItem(option); -}; - - -/** - * Creates a {@link goog.ui.Toolbar} containing the specified set of - * toolbar buttons, and renders it into the given parent element. Each - * item in the {@code items} array must a {@link goog.ui.Control}. - * @param {!Array.<goog.ui.Control>} items Toolbar items; each must - * be a {@link goog.ui.Control}. - * @param {!Element} elem Toolbar parent element. - * @param {boolean=} opt_isRightToLeft Whether the editor chrome is - * right-to-left; defaults to the directionality of the toolbar parent - * element. - * @return {!goog.ui.Toolbar} Editor toolbar, rendered into the given parent - * element. - */ -goog.ui.editor.ToolbarFactory.makeToolbar = function(items, elem, - opt_isRightToLeft) { - var domHelper = goog.dom.getDomHelper(elem); - - // Create an empty horizontal toolbar using the default renderer. - var toolbar = new goog.ui.Toolbar(goog.ui.ToolbarRenderer.getInstance(), - goog.ui.Container.Orientation.HORIZONTAL, domHelper); - - // Optimization: Explicitly test for the directionality of the parent - // element here, so we can set it for both the toolbar and its children, - // saving a lot of expensive calls to goog.style.isRightToLeft() during - // rendering. - var isRightToLeft = opt_isRightToLeft || goog.style.isRightToLeft(elem); - toolbar.setRightToLeft(isRightToLeft); - - // Optimization: Set the toolbar to non-focusable before it is rendered, - // to avoid creating unnecessary keyboard event handler objects. - toolbar.setFocusable(false); - - for (var i = 0, button; button = items[i]; i++) { - // Optimization: Set the button to non-focusable before it is rendered, - // to avoid creating unnecessary keyboard event handler objects. Also set - // the directionality of the button explicitly, to avoid expensive calls - // to goog.style.isRightToLeft() during rendering. - button.setSupportedState(goog.ui.Component.State.FOCUSED, false); - button.setRightToLeft(isRightToLeft); - toolbar.addChild(button, true); - } - - toolbar.render(elem); - return toolbar; -}; - - -/** - * Creates a toolbar button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ButtonRenderer=} opt_renderer Button renderer; defaults to - * {@link goog.ui.ToolbarButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toolbar button. - */ -goog.ui.editor.ToolbarFactory.makeButton = function(id, tooltip, caption, - opt_classNames, opt_renderer, opt_domHelper) { - var button = new goog.ui.ToolbarButton( - goog.ui.editor.ToolbarFactory.createContent_(caption, opt_classNames, - opt_domHelper), - opt_renderer, - opt_domHelper); - button.setId(id); - button.setTooltip(tooltip); - return button; -}; - - -/** - * Creates a toggle button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. The button - * returned has checkbox-like toggle semantics. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ButtonRenderer=} opt_renderer Button renderer; defaults to - * {@link goog.ui.ToolbarButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Button} A toggle button. - */ -goog.ui.editor.ToolbarFactory.makeToggleButton = function(id, tooltip, caption, - opt_classNames, opt_renderer, opt_domHelper) { - var button = goog.ui.editor.ToolbarFactory.makeButton(id, tooltip, caption, - opt_classNames, opt_renderer, opt_domHelper); - button.setSupportedState(goog.ui.Component.State.CHECKED, true); - return button; -}; - - -/** - * Creates a menu button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's caption element. The button - * returned doesn't have an actual menu attached; use {@link - * goog.ui.MenuButton#setMenu} to attach a {@link goog.ui.Menu} to the - * button. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ButtonRenderer=} opt_renderer Button renderer; defaults to - * {@link goog.ui.ToolbarMenuButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.MenuButton} A menu button. - */ -goog.ui.editor.ToolbarFactory.makeMenuButton = function(id, tooltip, caption, - opt_classNames, opt_renderer, opt_domHelper) { - var button = new goog.ui.ToolbarMenuButton( - goog.ui.editor.ToolbarFactory.createContent_(caption, opt_classNames, - opt_domHelper), - null, - opt_renderer, - opt_domHelper); - button.setId(id); - button.setTooltip(tooltip); - return button; -}; - - -/** - * Creates a select button with the given ID, tooltip, and caption. Applies - * any custom CSS class names to the button's root element. The button - * returned doesn't have an actual menu attached; use {@link - * goog.ui.Select#setMenu} to attach a {@link goog.ui.Menu} containing - * {@link goog.ui.Option}s to the select button. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in buttons, anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption; used as the - * default caption when nothing is selected. - * @param {string=} opt_classNames CSS class name(s) to apply to the button's - * root element. - * @param {goog.ui.MenuButtonRenderer=} opt_renderer Button renderer; - * defaults to {@link goog.ui.ToolbarMenuButtonRenderer} if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.Select} A select button. - */ -goog.ui.editor.ToolbarFactory.makeSelectButton = function(id, tooltip, caption, - opt_classNames, opt_renderer, opt_domHelper) { - var button = new goog.ui.ToolbarSelect(null, null, - opt_renderer, - opt_domHelper); - if (opt_classNames) { - // Unlike the other button types, for goog.ui.Select buttons we apply the - // extra class names to the root element, because for select buttons the - // caption isn't stable (as it changes each time the selection changes). - goog.array.forEach(opt_classNames.split(/\s+/), button.addClassName, - button); - } - button.addClassName(goog.getCssName('goog-toolbar-select')); - button.setDefaultCaption(caption); - button.setId(id); - button.setTooltip(tooltip); - return button; -}; - - -/** - * Creates a color menu button with the given ID, tooltip, and caption. - * Applies any custom CSS class names to the button's caption element. The - * button is created with a default color menu containing standard color - * palettes. - * @param {string} id Button ID; must equal a {@link goog.editor.Command} for - * built-in toolbar buttons, but can be anything else for custom buttons. - * @param {string} tooltip Tooltip to be shown on hover. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the caption - * element. - * @param {goog.ui.ColorMenuButtonRenderer=} opt_renderer Button renderer; - * defaults to {@link goog.ui.ToolbarColorMenuButtonRenderer} - * if unspecified. - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!goog.ui.ColorMenuButton} A color menu button. - */ -goog.ui.editor.ToolbarFactory.makeColorMenuButton = function(id, tooltip, - caption, opt_classNames, opt_renderer, opt_domHelper) { - var button = new goog.ui.ToolbarColorMenuButton( - goog.ui.editor.ToolbarFactory.createContent_(caption, opt_classNames, - opt_domHelper), - null, - opt_renderer, - opt_domHelper); - button.setId(id); - button.setTooltip(tooltip); - return button; -}; - - -/** - * Creates a new DIV that wraps a button caption, optionally applying CSS - * class names to it. Used as a helper function in button factory methods. - * @param {goog.ui.ControlContent} caption Button caption. - * @param {string=} opt_classNames CSS class name(s) to apply to the DIV that - * wraps the caption (if any). - * @param {goog.dom.DomHelper=} opt_domHelper DOM helper, used for DOM - * creation; defaults to the current document if unspecified. - * @return {!Element} DIV that wraps the caption. - * @private - */ -goog.ui.editor.ToolbarFactory.createContent_ = function(caption, opt_classNames, - opt_domHelper) { - // FF2 doesn't like empty DIVs, especially when rendered right-to-left. - if ((!caption || caption == '') && goog.userAgent.GECKO && - !goog.userAgent.isVersion('1.9a')) { - caption = goog.string.Unicode.NBSP; - } - return (opt_domHelper || goog.dom.getDomHelper()).createDom( - goog.dom.TagName.DIV, - opt_classNames ? {'class' : opt_classNames} : null, caption); -}; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarfactory_test.html.svn-base b/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarfactory_test.html.svn-base deleted file mode 100644 index 6141fc4..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/.svn/text-base/toolbarfactory_test.html.svn-base +++ /dev/null @@ -1,73 +0,0 @@ -<!DOCTYPE html> -<!-- - All Rights Reserved. - - @author jparent@google.com (Julie Parent) ---><html> -<!-- -Copyright 2010 The Closure Library Authors. All Rights Reserved. - -Use of this source code is governed by the Apache License, Version 2.0. -See the COPYING file for details. ---> -<head> -<meta http-equiv="X-UA-Compatible" content="IE=edge"> -<title>Closure Unit Tests - goog.ui.editor.ToolbarFactory</title> -<script src="../../base.js"></script> -<script> - goog.require('goog.testing.ExpectedFailures'); - goog.require('goog.testing.editor.TestHelper'); - goog.require('goog.testing.jsunit'); - goog.require('goog.ui.editor.ToolbarFactory'); -</script> -</head> -<body> -<div id="myField">foo</div> -<script> -var helper = new goog.testing.editor.TestHelper(goog.dom.getElement('myField')); -var expectedFailures = new goog.testing.ExpectedFailures(); - -function setUp() { - helper.setUpEditableElement(); -} - -function tearDown() { - helper.tearDownEditableElement(); - expectedFailures.handleTearDown(); -} - -/** - * Makes sure we have the correct conversion table in - * goog.ui.editor.ToolbarFactory.LEGACY_SIZE_TO_PX_MAP_. Can only be tested in - * a browser that takes legacy size values as input to execCommand but returns - * pixel size values from queryCommandValue. That's OK because that's the only - * situation where this conversion table's precision is critical. (When it's - * used to size the labels of the font size menu options it's ok if it's a few - * pixels off.) - */ -function testGetLegacySizeFromPx() { - // We will be warned if other browsers start behaving like webkit pre-534.7. - expectedFailures.expectFailureFor( - !goog.userAgent.WEBKIT || - (goog.userAgent.WEBKIT && goog.userAgent.isVersion('534.7'))); - try { - var fieldElem = goog.dom.getElement('myField'); - // Start from 1 because size 0 is bogus (becomes 16px, legacy size 3). - for (var i = 1; i < - goog.ui.editor.ToolbarFactory.LEGACY_SIZE_TO_PX_MAP_.length; i++) { - helper.select(fieldElem, 0, fieldElem, 1); - document.execCommand('fontSize', false, i); - helper.select('foo', 1); - var value = document.queryCommandValue('fontSize'); - assertEquals('Px size ' + value + ' should convert to legacy size ' + i, - i, goog.ui.editor.ToolbarFactory.getLegacySizeFromPx( - parseInt(value, 10))); - } - } catch (e) { - expectedFailures.handleException(e); - } -} -</script> -</body> -</html> - diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/bubble.js b/contexts/data/lib/closure-library/closure/goog/ui/editor/bubble.js index 0928948..6e93888 100644 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/bubble.js +++ b/contexts/data/lib/closure-library/closure/goog/ui/editor/bubble.js @@ -32,6 +32,7 @@ goog.require('goog.editor.style'); goog.require('goog.events'); goog.require('goog.events.EventHandler'); goog.require('goog.events.EventType'); +goog.require('goog.math.Box'); goog.require('goog.positioning'); goog.require('goog.string'); goog.require('goog.style'); diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/defaulttoolbar.js b/contexts/data/lib/closure-library/closure/goog/ui/editor/defaulttoolbar.js index 63fd370..5746bba 100644 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/defaulttoolbar.js +++ b/contexts/data/lib/closure-library/closure/goog/ui/editor/defaulttoolbar.js @@ -26,7 +26,6 @@ goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('goog.dom.classes'); goog.require('goog.editor.Command'); -goog.require('goog.string.StringBuffer'); goog.require('goog.style'); goog.require('goog.ui.ControlContent'); goog.require('goog.ui.editor.ToolbarFactory'); @@ -587,8 +586,8 @@ goog.ui.editor.DefaultToolbar.colorUpdateFromValue_ = function(button, color) { // Convert from decimal to BGR to RGB. var hex = '000000' + value.toString(16); var bgr = hex.substr(hex.length - 6, 6); - value = new goog.string.StringBuffer('#', bgr.substring(4, 6), - bgr.substring(2, 4), bgr.substring(0, 2)).toString(); + value = '#' + bgr.substring(4, 6) + bgr.substring(2, 4) + + bgr.substring(0, 2); } if (value != button.getValue()) { button.setValue(/** @type {string} */ (value)); diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog.js b/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog.js index 965a598..fb18d06 100644 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog.js +++ b/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog.js @@ -87,11 +87,13 @@ goog.ui.editor.LinkDialog.EventType = { * @param {string} linkUrl Url the user chose for the link to point to. * @param {boolean} openInNewWindow Whether the link should open in a new window * when clicked. + * @param {boolean} noFollow Whether the link should have 'rel=nofollow' + * attribute. * @constructor * @extends {goog.events.Event} */ goog.ui.editor.LinkDialog.OkEvent = function( - linkText, linkUrl, openInNewWindow) { + linkText, linkUrl, openInNewWindow, noFollow) { goog.base(this, goog.ui.editor.AbstractDialog.EventType.OK); /** @@ -111,6 +113,12 @@ goog.ui.editor.LinkDialog.OkEvent = function( * @type {boolean} */ this.openInNewWindow = openInNewWindow; + + /** + * Whether the link should have 'rel=nofollow' attribute. + * @type {boolean} + */ + this.noFollow = noFollow; }; goog.inherits(goog.ui.editor.LinkDialog.OkEvent, goog.events.Event); @@ -163,6 +171,15 @@ goog.ui.editor.LinkDialog.prototype.isOpenLinkInNewWindowChecked_ = false; /** + * Whether to show a checkbox where the user can choose to have 'rel=nofollow' + * attribute added to the link. + * @type {boolean} + * @private + */ +goog.ui.editor.LinkDialog.prototype.showRelNoFollow_ = false; + + +/** * Sets the warning message to show to users about including email addresses on * public web pages. * @param {string} emailWarning Warning message to show users about including @@ -188,6 +205,15 @@ goog.ui.editor.LinkDialog.prototype.showOpenLinkInNewWindow = function( }; +/** + * Tells the dialog to show a checkbox where the user can choose to add + * 'rel=nofollow' attribute to the link. + */ +goog.ui.editor.LinkDialog.prototype.showRelNoFollow = function() { + this.showRelNoFollow_ = true; +}; + + /** @override */ goog.ui.editor.LinkDialog.prototype.show = function() { goog.base(this, 'show'); @@ -205,6 +231,11 @@ goog.ui.editor.LinkDialog.prototype.show = function() { } this.openInNewWindowCheckbox_.checked = this.isOpenLinkInNewWindowChecked_; } + + if (this.showRelNoFollow_) { + this.relNoFollowCheckbox_.checked = + goog.ui.editor.LinkDialog.hasNoFollow(this.targetLink_.getAnchor().rel); + } }; @@ -251,39 +282,37 @@ goog.ui.editor.LinkDialog.prototype.setAutogenFeatureEnabled = function( }; +/** + * Checks if {@code str} contains {@code "nofollow"} as a separate word. + * @param {string} str String to be tested. This is usually {@code rel} + * attribute of an {@code HTMLAnchorElement} object. + * @return {boolean} {@code true} if {@code str} contains {@code nofollow}. + */ +goog.ui.editor.LinkDialog.hasNoFollow = function(str) { + return goog.ui.editor.LinkDialog.NO_FOLLOW_REGEX_.test(str); +}; + + +/** + * Removes {@code "nofollow"} from {@code rel} if it's present as a separate + * word. + * @param {string} rel Input string. This is usually {@code rel} attribute of + * an {@code HTMLAnchorElement} object. + * @return {string} {@code rel} with any {@code "nofollow"} removed. + */ +goog.ui.editor.LinkDialog.removeNoFollow = function(rel) { + return rel.replace(goog.ui.editor.LinkDialog.NO_FOLLOW_REGEX_, ''); +}; + + // *** Protected interface ************************************************** // /** @override */ goog.ui.editor.LinkDialog.prototype.createDialogControl = function() { - this.textToDisplayDiv_ = /** @type {HTMLDivElement} */( - this.buildTextToDisplayDiv_()); - var content = this.dom.createDom(goog.dom.TagName.DIV, null, - this.textToDisplayDiv_); - var builder = new goog.ui.editor.AbstractDialog.Builder(this); builder.setTitle(goog.ui.editor.messages.MSG_EDIT_LINK) - .setContent(content); - - this.tabPane_ = new goog.ui.editor.TabPane(this.dom, - goog.ui.editor.messages.MSG_LINK_TO); - this.tabPane_.addTab(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB, - goog.ui.editor.messages.MSG_ON_THE_WEB, - goog.ui.editor.messages.MSG_ON_THE_WEB_TIP, - this.buildTabOnTheWeb_()); - this.tabPane_.addTab(goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB, - goog.ui.editor.messages.MSG_EMAIL_ADDRESS, - goog.ui.editor.messages.MSG_EMAIL_ADDRESS_TIP, - this.buildTabEmailAddress_()); - this.tabPane_.render(content); - - this.eventHandler_.listen(this.tabPane_, goog.ui.Component.EventType.SELECT, - this.onChangeTab_); - - if (this.showOpenLinkInNewWindow_) { - content.appendChild(this.buildOpenInNewWindowDiv_()); - } - + .setContent(this.createDialogContent_()); return builder.build(); }; @@ -312,6 +341,9 @@ goog.ui.editor.LinkDialog.prototype.disposeInternal = function() { this.eventHandler_.dispose(); this.eventHandler_ = null; + this.tabPane_.dispose(); + this.tabPane_ = null; + this.urlInputHandler_.dispose(); this.urlInputHandler_ = null; this.emailInputHandler_.dispose(); @@ -325,6 +357,15 @@ goog.ui.editor.LinkDialog.prototype.disposeInternal = function() { /** + * Regular expression that matches {@code nofollow} value in an + * {@code * HTMLAnchorElement}'s {@code rel} element. + * @type {RegExp} + * @private + */ +goog.ui.editor.LinkDialog.NO_FOLLOW_REGEX_ = /\bnofollow\b/i; + + +/** * The link being modified by this dialog. * @type {goog.editor.Link} * @private @@ -415,6 +456,15 @@ goog.ui.editor.LinkDialog.prototype.openInNewWindowCheckbox_; /** + * The input element (checkbox) to indicate that the link should have + * 'rel=nofollow' attribute. + * @type {HTMLInputElement} + * @private + */ +goog.ui.editor.LinkDialog.prototype.relNoFollowCheckbox_; + + +/** * Whether to stop leaking the page's url via the referrer header when the * "test this link" link is clicked. * @type {boolean} @@ -424,6 +474,43 @@ goog.ui.editor.LinkDialog.prototype.stopReferrerLeaks_ = false; /** + * Creates contents of this dialog. + * @return {Element} Contents of the dialog as a DOM element. + * @private + */ +goog.ui.editor.LinkDialog.prototype.createDialogContent_ = function() { + this.textToDisplayDiv_ = /** @type {HTMLDivElement} */( + this.buildTextToDisplayDiv_()); + var content = this.dom.createDom(goog.dom.TagName.DIV, null, + this.textToDisplayDiv_); + + this.tabPane_ = new goog.ui.editor.TabPane(this.dom, + goog.ui.editor.messages.MSG_LINK_TO); + this.tabPane_.addTab(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB, + goog.ui.editor.messages.MSG_ON_THE_WEB, + goog.ui.editor.messages.MSG_ON_THE_WEB_TIP, + this.buildTabOnTheWeb_()); + this.tabPane_.addTab(goog.ui.editor.LinkDialog.Id_.EMAIL_ADDRESS_TAB, + goog.ui.editor.messages.MSG_EMAIL_ADDRESS, + goog.ui.editor.messages.MSG_EMAIL_ADDRESS_TIP, + this.buildTabEmailAddress_()); + this.tabPane_.render(content); + + this.eventHandler_.listen(this.tabPane_, goog.ui.Component.EventType.SELECT, + this.onChangeTab_); + + if (this.showOpenLinkInNewWindow_) { + content.appendChild(this.buildOpenInNewWindowDiv_()); + } + if (this.showRelNoFollow_) { + content.appendChild(this.buildRelNoFollowDiv_()); + } + + return content; +}; + + +/** * Builds and returns the text to display section of the edit link dialog. * @return {Element} A div element to be appended into the dialog div. * @private @@ -475,6 +562,30 @@ goog.ui.editor.LinkDialog.prototype.buildOpenInNewWindowDiv_ = function() { /** + * Creates a DIV with a checkbox for {@code rel=nofollow} option. + * @return {Element} Newly created DIV element. + * @private + */ +goog.ui.editor.LinkDialog.prototype.buildRelNoFollowDiv_ = function() { + /** @desc Checkbox text for adding 'rel=nofollow' attribute to a link. */ + var MSG_ADD_REL_NOFOLLOW_ATTR = goog.getMsg( + "Add '{$relNoFollow}' attribute ({$linkStart}Learn more{$linkEnd})", { + 'relNoFollow': 'rel=nofollow', + 'linkStart': '<a href="http://support.google.com/webmasters/bin/' + + 'answer.py?hl=en&answer=96569" target="_blank">', + 'linkEnd': '</a>' + }); + + this.relNoFollowCheckbox_ = /** @type {HTMLInputElement} */( + this.dom.createDom(goog.dom.TagName.INPUT, {'type': 'checkbox'})); + return this.dom.createDom(goog.dom.TagName.DIV, null, + this.dom.createDom(goog.dom.TagName.LABEL, null, + this.relNoFollowCheckbox_, + goog.dom.htmlToDocumentFragment(MSG_ADD_REL_NOFOLLOW_ATTR))); +}; + + +/** * Builds and returns the div containing the tab "On the web". * @return {Element} The div element containing the tab. * @private @@ -865,7 +976,8 @@ goog.ui.editor.LinkDialog.prototype.createOkEventFromUrl_ = function(url) { this.isOpenLinkInNewWindowChecked_ = this.openInNewWindowCheckbox_.checked; } return new goog.ui.editor.LinkDialog.OkEvent(this.textToDisplayInput_.value, - url, this.showOpenLinkInNewWindow_ && this.isOpenLinkInNewWindowChecked_); + url, this.showOpenLinkInNewWindow_ && this.isOpenLinkInNewWindowChecked_, + this.showRelNoFollow_ && this.relNoFollowCheckbox_.checked); }; diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog_test.html b/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog_test.html index bee15b9..80e6571 100644 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog_test.html +++ b/contexts/data/lib/closure-library/closure/goog/ui/editor/linkdialog_test.html @@ -101,13 +101,16 @@ See the COPYING file for details. stubs.reset(); } - function setUpAnchor(href, text, opt_isNew, opt_target) { + function setUpAnchor(href, text, opt_isNew, opt_target, opt_rel) { anchorElem.href = href; anchorElem.innerHTML = text; isNew = !!opt_isNew; if (opt_target) { anchorElem.target = opt_target; } + if (opt_rel) { + anchorElem.rel = opt_rel; + } } /** @@ -116,13 +119,18 @@ See the COPYING file for details. * Defaults to the main window's document. * @param {boolean=} opt_openInNewWindow Whether the open in new window * checkbox should be shown. + * @param {boolean=} opt_noFollow Whether rel=nofollow checkbox should be + * shown. */ - function createAndShow(opt_document, opt_openInNewWindow) { + function createAndShow(opt_document, opt_openInNewWindow, opt_noFollow) { dialog = new goog.ui.editor.LinkDialog(new goog.dom.DomHelper(opt_document), mockLink); if (opt_openInNewWindow) { dialog.showOpenLinkInNewWindow(false); } + if (opt_noFollow) { + dialog.showRelNoFollow(); + } dialog.addEventListener(goog.ui.editor.AbstractDialog.EventType.OK, mockOkHandler); dialog.show(); @@ -132,16 +140,18 @@ See the COPYING file for details. * Sets up the mock event handler to expect an OK event with the given text * and url. */ - function expectOk(linkText, linkUrl, opt_openInNewWindow) { + function expectOk(linkText, linkUrl, opt_openInNewWindow, opt_noFollow) { mockOkHandler.handleEvent(new goog.testing.mockmatchers.ArgumentMatcher( function(arg) { return arg.type == goog.ui.editor.AbstractDialog.EventType.OK && arg.linkText == linkText && arg.linkUrl == linkUrl && - arg.openInNewWindow == !!opt_openInNewWindow; + arg.openInNewWindow == !!opt_openInNewWindow && + arg.noFollow == !!opt_noFollow; }, '{linkText: ' + linkText + ', linkUrl: ' + linkUrl + - ', openInNewWindow: ' + opt_openInNewWindow + '}')); + ', openInNewWindow: ' + opt_openInNewWindow + + ', noFollow: ' + opt_noFollow + '}')); } /** @@ -414,6 +424,44 @@ See the COPYING file for details. mockCtrl.$verifyAll(); } + function testRelNoFollowNewLink() { + expectOk(ANCHOR_TEXT, ANCHOR_URL, null, true); + expectOk(ANCHOR_TEXT, ANCHOR_URL, null, false); + mockCtrl.$replayAll(); + + setUpAnchor('', '', true, true); + createAndShow(null, null, true); + dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); + setDisplayInputText(ANCHOR_TEXT); + setUrlInputText(ANCHOR_URL); + assertFalse('rel=nofollow should start unchecked', + dialog.relNoFollowCheckbox_.checked); + + // Check rel=nofollow and close the dialog. + dialog.relNoFollowCheckbox_.checked = true; + goog.testing.events.fireClickSequence(dialog.getOkButtonElement()); + + // Reopen the same dialog. + anchorElem.rel = 'foo nofollow bar'; + dialog.show(); + dialog.tabPane_.setSelectedTabId(goog.ui.editor.LinkDialog.Id_.ON_WEB_TAB); + setDisplayInputText(ANCHOR_TEXT); + setUrlInputText(ANCHOR_URL); + assertTrue('rel=nofollow should start checked when reopening the dialog', + dialog.relNoFollowCheckbox_.checked); + } + + function testRelNoFollowExistingLink() { + mockCtrl.$replayAll(); + + setUpAnchor('', '', null, null, 'foo nofollow bar'); + createAndShow(null, null, true); + assertTrue('rel=nofollow should start checked for existing link', + dialog.relNoFollowCheckbox_.checked); + + mockCtrl.$verifyAll(); + } + /** * Test that clicking on the test button opens a new window with the correct * options. diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/tabpane.js b/contexts/data/lib/closure-library/closure/goog/ui/editor/tabpane.js index 92a5981..df10825 100644 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/tabpane.js +++ b/contexts/data/lib/closure-library/closure/goog/ui/editor/tabpane.js @@ -47,6 +47,7 @@ goog.ui.editor.TabPane = function(dom, opt_caption) { * @private */ this.eventHandler_ = new goog.events.EventHandler(this); + this.registerDisposable(this.eventHandler_); /** * The tab bar used to render the tabs. diff --git a/contexts/data/lib/closure-library/closure/goog/ui/editor/toolbarfactory.js b/contexts/data/lib/closure-library/closure/goog/ui/editor/toolbarfactory.js index 6597f6b..cae68cc 100644 --- a/contexts/data/lib/closure-library/closure/goog/ui/editor/toolbarfactory.js +++ b/contexts/data/lib/closure-library/closure/goog/ui/editor/toolbarfactory.js @@ -185,8 +185,8 @@ goog.ui.editor.ToolbarFactory.LEGACY_SIZE_TO_PX_MAP_ = * 'H4') * </ul> * @param {!goog.ui.Select} button "Format block" menu button. - * @param {!Array.<{caption: string, command: string}>} formats Array of format - * option descriptors. + * @param {!Array.<{caption: string, command: goog.dom.TagName}>} formats Array + * of format option descriptors. */ goog.ui.editor.ToolbarFactory.addFormatOptions = function(button, formats) { goog.array.forEach(formats, function(format) { |