From 6493f7abe3bd59f55b7b572af03fae8abde1d4a3 Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Sun, 12 May 2013 20:21:44 +0200 Subject: [PATCH 01/14] #20 proposed architecture for bootstrap --- yii/assets.php | 17 ++ yii/bootstrap/enum/AlertEnum.php | 26 +++ yii/bootstrap/enum/BootstrapEnum.php | 26 +++ yii/bootstrap/enum/ButtonEnum.php | 33 +++ yii/bootstrap/enum/IconEnum.php | 158 +++++++++++++ yii/bootstrap/enum/ProgressEnum.php | 19 ++ yii/bootstrap/helpers/Alert.php | 19 ++ yii/bootstrap/helpers/Assets.php | 19 ++ yii/bootstrap/helpers/Button.php | 19 ++ yii/bootstrap/helpers/Icon.php | 43 ++++ yii/bootstrap/helpers/Progress.php | 19 ++ yii/bootstrap/helpers/base/Alert.php | 46 ++++ yii/bootstrap/helpers/base/Assets.php | 25 ++ yii/bootstrap/helpers/base/Button.php | 69 ++++++ yii/bootstrap/helpers/base/Icon.php | 21 ++ yii/bootstrap/helpers/base/Progress.php | 21 ++ yii/bootstrap/widgets/Modal.php | 303 +++++++++++++++++++++++++ yii/bootstrap/widgets/base/BootstrapWidget.php | 139 ++++++++++++ 18 files changed, 1022 insertions(+) create mode 100644 yii/bootstrap/enum/AlertEnum.php create mode 100644 yii/bootstrap/enum/BootstrapEnum.php create mode 100644 yii/bootstrap/enum/ButtonEnum.php create mode 100644 yii/bootstrap/enum/IconEnum.php create mode 100644 yii/bootstrap/enum/ProgressEnum.php create mode 100644 yii/bootstrap/helpers/Alert.php create mode 100644 yii/bootstrap/helpers/Assets.php create mode 100644 yii/bootstrap/helpers/Button.php create mode 100644 yii/bootstrap/helpers/Icon.php create mode 100644 yii/bootstrap/helpers/Progress.php create mode 100644 yii/bootstrap/helpers/base/Alert.php create mode 100644 yii/bootstrap/helpers/base/Assets.php create mode 100644 yii/bootstrap/helpers/base/Button.php create mode 100644 yii/bootstrap/helpers/base/Icon.php create mode 100644 yii/bootstrap/helpers/base/Progress.php create mode 100644 yii/bootstrap/widgets/Modal.php create mode 100644 yii/bootstrap/widgets/base/BootstrapWidget.php diff --git a/yii/assets.php b/yii/assets.php index 7ee177d..6c32b83 100644 --- a/yii/assets.php +++ b/yii/assets.php @@ -42,4 +42,21 @@ return array( ), 'depends' => array('yii'), ), + 'yii/bootstrap' => array( + 'sourcePath' => __DIR__ . '/assets/bootstrap', + 'js' => array( + '/js/bootstrap.min.js', + ), + 'css' => array( + 'css/bootstrap.css' + ), + 'depends' => array('yii'), + ), + 'yii/bootstrap-responsive' => array( + 'sourcePath' => __DIR__ . '/assets/bootstrap', + 'css' => array( + 'css/bootstrap-responsive.css' + ), + 'depends' => array('yii/bootstrap'), + ) ); diff --git a/yii/bootstrap/enum/AlertEnum.php b/yii/bootstrap/enum/AlertEnum.php new file mode 100644 index 0000000..d0096fb --- /dev/null +++ b/yii/bootstrap/enum/AlertEnum.php @@ -0,0 +1,26 @@ + + * @since 2.0 + */ +class AlertEnum +{ + const CLASS_NAME = 'alert'; + + const TYPE_DEFAULT = ''; + const TYPE_SUCCESS = 'alert-success'; + const TYPE_INFORMATION = 'alert-info'; + const TYPE_ERROR = 'alert-error'; + + const SIZE_BLOCK = 'alert-block'; +} \ No newline at end of file diff --git a/yii/bootstrap/enum/BootstrapEnum.php b/yii/bootstrap/enum/BootstrapEnum.php new file mode 100644 index 0000000..ad1d0a8 --- /dev/null +++ b/yii/bootstrap/enum/BootstrapEnum.php @@ -0,0 +1,26 @@ + + * @since 2.0 + */ +class BootstrapEnum +{ + const FADE = 'fade'; + const IN = 'in'; + const CLOSE = 'close'; + const DISABLED = 'disabled'; + const ACTIVE = 'active'; + const MODAL = 'modal'; + const HIDE = 'hide'; + const DIALOG = 'dialog'; + const ALERT = 'alert'; +} \ No newline at end of file diff --git a/yii/bootstrap/enum/ButtonEnum.php b/yii/bootstrap/enum/ButtonEnum.php new file mode 100644 index 0000000..68454e4 --- /dev/null +++ b/yii/bootstrap/enum/ButtonEnum.php @@ -0,0 +1,33 @@ + + * @since 2.0 + */ +class ButtonEnum +{ + const TYPE_DEFAULT = 'btn'; + const TYPE_PRIMARY = 'btn-primary'; + const TYPE_INFO = 'btn-info'; + const TYPE_SUCCESS = 'btn-success'; + const TYPE_WARNING = 'btn-warning'; + const TYPE_DANGER = 'btn-danger'; + const TYPE_INVERSE = 'btn-inverse'; + const TYPE_LINK = 'btn-link'; + + const SIZE_DEFAULT = ''; + const SIZE_LARGE = 'btn-large'; + const SIZE_SMALL = 'btn-small'; + const SIZE_MINI = 'btn-mini'; + const SIZE_BLOCK = 'btn-block'; + +} \ No newline at end of file diff --git a/yii/bootstrap/enum/IconEnum.php b/yii/bootstrap/enum/IconEnum.php new file mode 100644 index 0000000..bebd8a3 --- /dev/null +++ b/yii/bootstrap/enum/IconEnum.php @@ -0,0 +1,158 @@ + + * @since 2.0 + */ +class IconEnum +{ + const ICON_GLASS = 'icon-glass'; + const ICON_MUSIC = 'icon-music'; + const ICON_SEARCH = 'icon-search'; + const ICON_ENVELOPE = 'icon-envelope'; + const ICON_HEART = 'icon-heart'; + const ICON_STAR = 'icon-star'; + const ICON_STAR_EMPTY = 'icon-star-empty'; + const ICON_USER = 'icon-user'; + const ICON_FILM = 'icon-film'; + const ICON_TH_LARGE = 'icon-th-large'; + const ICON_TH = 'icon-th'; + const ICON_TH_LIST = 'icon-th-list'; + const ICON_OK = 'icon-ok'; + const ICON_REMOVE = 'icon-remove'; + const ICON_ZOOM_IN = 'icon-zoom-in'; + const ICON_ZOOM_OUT = 'icon-zoom-out'; + const ICON_OFF = 'icon-off'; + const ICON_SIGNAL = 'icon-signal'; + const ICON_COG = 'icon-cog'; + const ICON_TRASH = 'icon-trash'; + const ICON_HOME = 'icon-home'; + const ICON_FILE = 'icon-file'; + const ICON_TIME = 'icon-time'; + const ICON_ROAD = 'icon-road'; + const ICON_DOWNLOAD_ALT = 'icon-download-alt'; + const ICON_DOWNLOAD = 'icon-download'; + const ICON_UPLOAD = 'icon-upload'; + const ICON_INBOX = 'icon-inbox'; + const ICON_PLAY_CIRCLE = 'icon-play-circle'; + const ICON_REPEAT = 'icon-repeat'; + const ICON_REFRESH = 'icon-refresh'; + const ICON_LIST_ALT = 'icon-list-alt'; + const ICON_LOCK = 'icon-lock'; + const ICON_FLAG = 'icon-flag'; + const ICON_HEADPHONES = 'icon-headphones'; + const ICON_VOLUME_OFF = 'icon-volume-off'; + const ICON_VOLUME_DOWN = 'icon-volume-down'; + const ICON_VOLUME_UP = 'icon-volume-up'; + const ICON_QRCODE = 'icon-qrcode'; + const ICON_BARCODE = 'icon-barcode'; + const ICON_TAG = 'icon-tag'; + const ICON_TAGS = 'icon-tags'; + const ICON_BOOK = 'icon-book'; + const ICON_BOOKMARK = 'icon-bookmark'; + const ICON_PRINT = 'icon-print'; + const ICON_CAMERA = 'icon-camera'; + const ICON_FONT = 'icon-font'; + const ICON_BOLD = 'icon-bold'; + const ICON_ITALIC = 'icon-italic'; + const ICON_TEXT_HEIGHT = 'icon-text-height'; + const ICON_TEXT_WIDTH = 'icon-text-width'; + const ICON_ALIGN_LEFT = 'icon-align-left'; + const ICON_ALIGN_CENTER = 'icon-align-center'; + const ICON_ALIGN_RIGHT = 'icon-align-right'; + const ICON_ALIGN_JUSTIFY = 'icon-align-justify'; + const ICON_LIST = 'icon-list'; + const ICON_INDENT_LEFT = 'icon-indent-left'; + const ICON_INDENT_RIGHT = 'icon-indent-right'; + const ICON_FACETIME_VIDEO = 'icon-facetime-video'; + const ICON_PICTURE = 'icon-picture'; + const ICON_PENCIL = 'icon-pencil'; + const ICON_MAP_MARKER = 'icon-map-marker'; + const ICON_ADJUST = 'icon-adjust'; + const ICON_TINT = 'icon-tint'; + const ICON_EDIT = 'icon-edit'; + const ICON_SHARE = 'icon-share'; + const ICON_CHECK = 'icon-check'; + const ICON_MOVE = 'icon-move'; + const ICON_STEP_BACKWARD = 'icon-step-backward'; + const ICON_FAST_BACKWARD = 'icon-fast-backward'; + const ICON_BACKWARD = 'icon-backward'; + const ICON_PLAY = 'icon-play'; + const ICON_PAUSE = 'icon-pause'; + const ICON_STOP = 'icon-pause'; + const ICON_FORWARD = 'icon-forward'; + const ICON_FAST_FORWARD = 'icon-fast-forward'; + const ICON_STEP_FORWARD = 'icon-step-forward'; + const ICON_EJECT = 'icon-eject'; + const ICON_CHEVRON_LEFT = 'icon-chevron-left'; + const ICON_CHEVRON_RIGHT = 'icon-chevron-right'; + const ICON_PLUS_SIGN = 'icon-plus-sign'; + const ICON_MINUS_SIGN = 'icon-minus-sign'; + const ICON_REMOVE_SIGN = 'icon-remove-sign'; + const ICON_OK_SIGN = 'icon-ok-sign'; + const ICON_QUESTION_SIGN = 'icon-question-sign'; + const ICON_INFO_SIGN = 'icon-info-sign'; + const ICON_SCREENSHOT = 'icon-screenshot'; + const ICON_REMOVE_CIRCLE = 'icon-remove-circle'; + const ICON_OK_CIRCLE = 'icon-ok-circle'; + const ICON_BAN_CIRCLE = 'icon-ban-circle'; + const ICON_ARROW_LEFT = 'icon-arrow-left'; + const ICON_ARROW_RIGHT = 'icon-arrow-right'; + const ICON_ARROW_UP = 'icon-arrow-up'; + const ICON_ARROW_DOWN = 'icon-arrow-down'; + const ICON_SHARE_ALT = 'icon-share-alt'; + const ICON_RESIZE_FULL = 'icon-resize-full'; + const ICON_RESIZE_SMALL = 'icon-resize-small'; + const ICON_PLUS = 'icon-plus'; + const ICON_MINUS = 'icon-minus'; + const ICON_ASTERISK = 'icon-asterisk'; + const ICON_EXCLAMATION_SIGN = 'icon-exclamation-sign'; + const ICON_GIFT = 'icon-gift'; + const ICON_LEAF = 'icon-leaf'; + const ICON_FIRE = 'icon-fire'; + const ICON_EYE_OPEN = 'icon-eye-open'; + const ICON_EYE_CLOSE = 'icon-eye-close'; + const ICON_WARNING_SIGN = 'icon-warning-sign'; + const ICON_PLANE = 'icon-plane'; + const ICON_CALENDAR = 'icon-calendar'; + const ICON_RANDOM = 'icon-random'; + const ICON_COMMENT = 'icon-comment'; + const ICON_MAGNET = 'icon-magnet'; + const ICON_CHEVRON_UP = 'icon-chevron-up'; + const ICON_CHEVRON_DOWN = 'icon-chevron-down'; + const ICON_RETWEET = 'icon-retweet'; + const ICON_SHOPPING_CART = 'icon-shopping-cart'; + const ICON_FOLDER_CLOSE = 'icon-folder-close'; + const ICON_FOLDER_OPEN = 'icon-folder-open'; + const ICON_RESIZE_VERTICAL = 'icon-resize-vertical'; + const ICON_RESIZE_HORIZONTAL = 'icon-resize-horizontal'; + const ICON_HDD = 'icon-hdd'; + const ICON_BULLHORN = 'icon-bullhorn'; + const ICON_BELL = 'icon-bell'; + const ICON_CERTFICATE = 'icon-certificate'; + const ICON_THUMBS_UP = 'icon-thumbs-up'; + const ICON_THUMBS_DOWN = 'icon-thumbs-down'; + const ICON_HAND_RIGHT = 'icon-hand-right'; + const ICON_HAND_LEFT = 'icon-hand-left'; + const ICON_HAND_UP = 'icon-hand-up'; + const ICON_HAND_DOWN = 'icon-hand-down'; + const ICON_CIRCLE_ARROW_RIGHT = 'icon-circle-arrow-right'; + const ICON_CIRCLE_ARROW_LEFT = 'icon-circle-arrow-left'; + const ICON_CIRCLE_ARROW_UP = 'icon-circle-arrow-up'; + const ICON_CIRCLE_ARROW_DOWN = 'icon-circle-arrow-down'; + const ICON_GLOBE = 'icon-globe'; + const ICON_WRENCH = 'icon-wrench'; + const ICON_TASKS = 'icon-tasks'; + const ICON_FILTER = 'icon-filter'; + const ICON_BRIEFCASE = 'icon-briefcase'; + const ICON_FULLSCREEN = 'icon-fullscreen'; +} \ No newline at end of file diff --git a/yii/bootstrap/enum/ProgressEnum.php b/yii/bootstrap/enum/ProgressEnum.php new file mode 100644 index 0000000..44a8b51 --- /dev/null +++ b/yii/bootstrap/enum/ProgressEnum.php @@ -0,0 +1,19 @@ + + * @since 2.0 + */ +class ProgressEnum +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Alert.php b/yii/bootstrap/helpers/Alert.php new file mode 100644 index 0000000..58139bd --- /dev/null +++ b/yii/bootstrap/helpers/Alert.php @@ -0,0 +1,19 @@ + + * @since 2.0 + */ +class Alert extends base\Alert +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Assets.php b/yii/bootstrap/helpers/Assets.php new file mode 100644 index 0000000..e03b04f --- /dev/null +++ b/yii/bootstrap/helpers/Assets.php @@ -0,0 +1,19 @@ + + * @since 2.0 + */ +class Assets extends base\Assets +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Button.php b/yii/bootstrap/helpers/Button.php new file mode 100644 index 0000000..1448838 --- /dev/null +++ b/yii/bootstrap/helpers/Button.php @@ -0,0 +1,19 @@ + + * @since 2.0 + */ +class Button extends base\Button +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Icon.php b/yii/bootstrap/helpers/Icon.php new file mode 100644 index 0000000..41eb0b9 --- /dev/null +++ b/yii/bootstrap/helpers/Icon.php @@ -0,0 +1,43 @@ + + * @since 2.0 + */ +class Icon extends base\Icon +{ + /** + * Generates an icon. + * @param string $icon the icon type. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated icon. + */ + public static function i($icon, $htmlOptions = array()) + { + if (is_string($icon)) + { + if (strpos($icon, 'icon-') === false) + $icon = 'icon-' . implode(' icon-', explode(' ', $icon)); + + // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? + if (isset($htmlOptions['class'])) + $htmlOptions['class'] .= ' ' . $icon; + else + $htmlOptions['class'] = $icon; + + return Html::tag('i', '', $htmlOptions); + } + return ''; + } +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Progress.php b/yii/bootstrap/helpers/Progress.php new file mode 100644 index 0000000..4e5bc7f --- /dev/null +++ b/yii/bootstrap/helpers/Progress.php @@ -0,0 +1,19 @@ + + * @since 2.0 + */ +class Progress extends base\Progress +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Alert.php b/yii/bootstrap/helpers/base/Alert.php new file mode 100644 index 0000000..bc6f899 --- /dev/null +++ b/yii/bootstrap/helpers/base/Alert.php @@ -0,0 +1,46 @@ + + * @since 2.0 + */ +class Alert +{ + + /** + * Generates an alert box + * @param $message + * @param array $htmlOptions + * @param bool $dismiss whether to display dismissal link or not + * @return string + */ + public static function create($message, $htmlOptions = array(), $dismiss = true) + { + // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? + if (isset($htmlOptions['class'])) + $htmlOptions['class'] .= ' ' . AlertEnum::CLASS_NAME; + else + $htmlOptions['class'] = AlertEnum::CLASS_NAME; + + ob_start(); + echo Html::beginTag('div', $htmlOptions); + if ($dismiss) + echo Button::closeLink('×', BootstrapEnum::ALERT); + echo $message; + echo Html::endTag('div'); + return ob_get_clean(); + } +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Assets.php b/yii/bootstrap/helpers/base/Assets.php new file mode 100644 index 0000000..30cd8ae --- /dev/null +++ b/yii/bootstrap/helpers/base/Assets.php @@ -0,0 +1,25 @@ + + * @since 2.0 + */ +class Assets +{ + public static function registerBundle($responsive = false) + { + $bundle = $responsive ? 'yii/bootstrap' : 'yii/bootstrap-responsive'; + + Yii::$app->getView()->registerAssetBundle($bundle); + } +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Button.php b/yii/bootstrap/helpers/base/Button.php new file mode 100644 index 0000000..2ae9da5 --- /dev/null +++ b/yii/bootstrap/helpers/base/Button.php @@ -0,0 +1,69 @@ + + * @since 2.0 + */ +class Button +{ + /** + * Returns a dismissal alert link + * @param string $text + * @param string $dismiss what to dismiss (alert or modal) + * @return string the dismissal alert link + */ + public static function closeLink($text = '×', $dismiss = null) + { + $options = array('class' => BootstrapEnum::CLOSE); + if(null !== $dismiss) + $options['data-dismiss'] = $dismiss; + return Html::a($text, '#', $options); + } + + /** + * Returns a dismissal button + * @param string $text the text to use for the close button + * @param string $dismiss what to dismiss (alert or modal) + * @return string the dismissal button + */ + public static function closeButton($text = '×', $dismiss = null) + { + $options = array('type' => 'button', 'class' => BootstrapEnum::CLOSE); + if(null !== $dismiss) + $options['data-dismiss'] = $dismiss; + + return Html::button($text, null, null, $options); + } + + + /** + * Returns a link button + * @param string $label the button label + * @param array $htmlOptions the HTML attributes of the button + * @return string the generated button + */ + public static function link($label, $htmlOptions = array()) + { + // TODO: consider method add or append to ArrayHelper class + if (isset($htmlOptions['class'])) + $htmlOptions['class'] .= ' ' . ButtonEnum::TYPE_LINK; + else + $htmlOptions['class'] = ButtonEnum::TYPE_LINK; + + return Html::a($label, '#', $htmlOptions); + } +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Icon.php b/yii/bootstrap/helpers/base/Icon.php new file mode 100644 index 0000000..47b0b05 --- /dev/null +++ b/yii/bootstrap/helpers/base/Icon.php @@ -0,0 +1,21 @@ + + * @since 2.0 + */ +class Icon +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Progress.php b/yii/bootstrap/helpers/base/Progress.php new file mode 100644 index 0000000..a13a44f --- /dev/null +++ b/yii/bootstrap/helpers/base/Progress.php @@ -0,0 +1,21 @@ + + * @since 2.0 + */ +class Progress +{ + +} \ No newline at end of file diff --git a/yii/bootstrap/widgets/Modal.php b/yii/bootstrap/widgets/Modal.php new file mode 100644 index 0000000..c591944 --- /dev/null +++ b/yii/bootstrap/widgets/Modal.php @@ -0,0 +1,303 @@ +widget(Modal::className(), array( + * 'id' => 'myModal', + * 'header' => 'Modal Heading', + * 'content' => '

One fine body...

', + * 'footer' => '//modal/_footer', // we can also use view paths + * 'buttonOptions' => array( + * 'label' => 'Show Modal', + * 'class' => \yii\bootstrap\enum\ButtonEnum::TYPE_DEFAULT + * ) + * )); + * ``` + * @see http://twitter.github.io/bootstrap/javascript.html#modals + * @author Antonio Ramirez + * @since 2.0 + */ +class Modal extends base\BootstrapWidget +{ + /** + * @var array The additional HTML attributes of the button that will show the modal. If empty array, only + * the markup of the modal will be rendered on the page, so users can easily call the modal manually with their own + * scripts. The following special attributes are available: + * + * + * For available options of the button trigger, see http://twitter.github.com/bootstrap/javascript.html#modals. + */ + public $buttonOptions = array(); + + /** + * @var boolean indicates whether the modal should use transitions. Defaults to 'true'. + */ + public $fade = true; + + /** + * @var bool $keyboard, closes the modal when escape key is pressed. + */ + public $keyboard = true; + + /** + * @var bool $show, shows the modal when initialized. + */ + public $show = false; + + /** + * @var mixed includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn't close + * the modal on click. + */ + public $backdrop = true; + + /** + * @var mixed the remote url. If a remote url is provided, content will be loaded via jQuery's load method and + * injected into the .modal-body of the modal. + */ + public $remote; + + /** + * @var string a javascript function that will be invoked immediately when the `show` instance method is called. + */ + public $onShow; + + /** + * @var string a javascript function that will be invoked when the modal has been made visible to the user + * (will wait for css transitions to complete). + */ + public $onShown; + + /** + * @var string a javascript function that will be invoked immediately when the hide instance method has been called. + */ + public $onHide; + + /** + * @var string a javascript function that will be invoked when the modal has finished being hidden from the user + * (will wait for css transitions to complete). + */ + public $onHidden; + + /** + * @var string[] the Javascript event handlers. + */ + protected $events = array(); + + /** + * @var array $pluginOptions the plugin options. + */ + protected $pluginOptions = array(); + + /** + * @var string + */ + public $closeText = '×'; + + /** + * @var string header content. Header can also be a path to a view file. + */ + public $header; + + /** + * @var string body of modal. Body can also be a path to a view file. + */ + public $content; + + /** + * @var string footer content. Content can also be a path to a view file. + */ + public $footer; + + /** + * Widget's init method + */ + public function init() + { + parent::init(); + + $this->name = 'modal'; + + $this->defaultOption('id', $this->getId()); + $this->selector = '#' . ArrayHelper::getValue($this->options, 'id'); + + $this->defaultOption('role', BootstrapEnum::DIALOG); + $this->defaultOption('tabindex', '-1'); + + $this->addOption('class', BootstrapEnum::MODAL); + $this->addOption('class', BootstrapEnum::HIDE); + + if ($this->fade) + $this->addOption('class', BootstrapEnum::FADE); + + $this->initPluginOptions(); + $this->initPluginEvents(); + } + + /** + * Initialize plugin events if any + */ + public function initPluginEvents() + { + foreach (array('onShow', 'onShown', 'onHide', 'onHidden') as $event) { + if ($this->{$event} !== null) { + $modalEvent = strtolower(substr($event, 2)); + if ($this->{$event} instanceof JsExpression) + $this->events[$modalEvent] = $this->$event; + else + $this->events[$modalEvent] = new JsExpression($this->{$event}); + } + } + } + + /** + * Initialize plugin options. + * ***Important***: The display of the button overrides the initialization of the modal bootstrap widget. + */ + public function initPluginOptions() + { + if (null !== $this->remote) + $this->pluginOptions['remote'] = Html::url($this->remote); + + foreach (array('backdrop', 'keyboard', 'show') as $option) { + $this->pluginOptions[$option] = isset($this->pluginOptions[$option]) + ? $this->pluginOptions[$option] + : $this->{$option}; + } + } + + /** + * Widget's run method + */ + public function run() + { + $this->renderModal(); + $this->renderButton(); + $this->registerScript(); + } + + /** + * Renders the button that will open the modal if its options have been configured + */ + public function renderButton() + { + if (!empty($this->buttonOptions)) { + + $this->buttonOptions['data-toggle'] = isset($this->buttonOptions['data-toggle']) + ? $this->buttonOptions['data-toggle'] + : BootstrapEnum::MODAL; + + if ($this->remote !== null && !isset($this->buttonOptions['data-remote'])) + $this->buttonOptions['data-remote'] = Html::url($this->remote); + + $label = ArrayHelper::remove($this->buttonOptions, 'label', 'Button'); + $name = ArrayHelper::remove($this->buttonOptions, 'name'); + $value = ArrayHelper::remove($this->buttonOptions, 'value'); + + $attr = isset($this->buttonOptions['data-remote']) + ? 'data-target' + : 'href'; + + $this->buttonOptions[$attr] = isset($this->buttonOptions[$attr]) + ? $this->buttonOptions[$attr] + : $this->selector; + + echo Html::button($label, $name, $value, $this->buttonOptions); + } + } + + /** + * Renders the modal markup + */ + public function renderModal() + { + echo Html::beginTag('div', $this->options) . PHP_EOL; + + $this->renderModalHeader(); + $this->renderModalBody(); + $this->renderModalFooter(); + + echo Html::endTag('div') . PHP_EOL; + } + + /** + * Renders the header HTML markup of the modal + */ + public function renderModalHeader() + { + echo '' . PHP_EOL; + } + + /** + * Renders the HTML markup for the body of the modal + */ + public function renderModalBody() + { + echo '' . PHP_EOL; + } + + /** + * Renders the HTML markup for the footer of the modal + */ + public function renderModalFooter() + { + + echo '' . PHP_EOL; + } + + /** + * Renders a section. If the section is a view file, the returned string will be the contents of the view file, + * otherwise, it will return the string in the $section variable. + * @param string $section + * @return string + */ + public function renderSection($section) + { + $viewFile = Yii::getAlias($section); + if (is_file($viewFile)) + return $this->view->renderFile($viewFile, array(), $this); + return $section; + } + + /** + * Registers client scripts + */ + public function registerScript() + { + // do we render a button? If so, bootstrap will handle its behavior through its + // mark-up, otherwise, register the plugin. + if(empty($this->buttonOptions)) + $this->registerPlugin($this->selector, $this->pluginOptions); + + // register events + $this->registerEvents($this->selector, $this->events); + } + +} \ No newline at end of file diff --git a/yii/bootstrap/widgets/base/BootstrapWidget.php b/yii/bootstrap/widgets/base/BootstrapWidget.php new file mode 100644 index 0000000..042f6f9 --- /dev/null +++ b/yii/bootstrap/widgets/base/BootstrapWidget.php @@ -0,0 +1,139 @@ + + * @since 2.0 + */ +class BootstrapWidget extends Widget +{ + + /** + * @var bool whether to register the asset + */ + public $responsive = true; + + /** + * @var array the HTML attributes for the widget container tag. + */ + public $options = array(); + + /** + * @var string the widget name + */ + protected $name; + + /** + * @var string the jQuery selector of the widget + */ + protected $selector; + + /** + * Initializes the widget. + */ + public function init() + { + $this->view->registerAssetBundle(($this->responsive ? 'yii/bootstrap' : 'yii/bootstrap-responsive')); + } + + /** + * Registers plugin events with the API. + * @param string $selector the CSS selector. + * @param string[] $events the JavaScript event configuration (name=>handler). + * @param int $position the position of the JavaScript code. + * @return boolean whether the events were registered. + */ + protected function registerEvents($selector, $events = array(), $position = View::POS_END) + { + if (empty($events)) + return; + + $script = ''; + foreach ($events as $name => $handler) { + $handler = ($handler instanceof JsExpression) + ? $handler + : new JsExpression($handler); + + $script .= ";jQuery(document).ready(function (){jQuery('{$selector}').on('{$name}', {$handler});});"; + } + if (!empty($script)) + $this->view->registerJs($script, array('position' => $position), $this->getUniqueScriptId()); + } + + /** + * Registers a specific Bootstrap plugin using the given selector and options. + * @param string $selector the CSS selector. + * @param array $options the JavaScript options for the plugin. + * @param int $position the position of the JavaScript code. + * @throws \yii\base\InvalidCallException + */ + public function registerPlugin($selector, $options = array(), $position = View::POS_END) + { + if(null === $this->name) + throw new InvalidCallException(); + + $options = !empty($options) ? Json::encode($options) : ''; + $script = ";jQuery(document).ready(function (){jQuery('{$selector}').{$this->name}({$options});});"; + $this->view->registerJs($script, array('position'=>$position)); + } + + /** + * Generates a "somewhat" random id string. + * @return string the id. + * @todo not sure it should be here or + */ + protected function getUniqueScriptId() + { + return uniqid(time() . '#', true); + } + + /** + * Adds a new option. If the key does not exists, it will create one, if it exists it will append the value + * and also makes sure the uniqueness of them. + * + * @param string $key + * @param mixed $value + * @param string $glue + * @return array + */ + protected function addOption($key, $value, $glue = ' ') + { + if (isset($this->options[$key])) { + if (!is_array($this->options[$key])) + $this->options[$key] = explode($glue, $this->options[$key]); + $this->options[$key][] = $value; + $this->options[$key] = array_unique($this->options[$key]); + $this->options[$key] = implode($glue, $this->options[$key]); + } else + $this->options[$key] = $value; + return $this->options; + } + + /** + * Sets the default value for an item if not set. + * @param string $key the name of the item. + * @param mixed $value the default value. + * @return array + */ + protected function defaultOption($key, $value) + { + if (!isset($this->options[$key])) + $this->options[$key] = $value; + return $this->options; + } +} \ No newline at end of file From 6cea89d8d4e88a995da0883325ce2d759e602157 Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Mon, 13 May 2013 19:33:48 +0200 Subject: [PATCH 02/14] made some changes, fix some pitfalls, remove PHP_EOL --- yii/bootstrap/enum/AlertEnum.php | 26 ---- yii/bootstrap/enum/BootstrapEnum.php | 26 ---- yii/bootstrap/enum/ButtonEnum.php | 33 ----- yii/bootstrap/enum/Enum.php | 26 ++++ yii/bootstrap/enum/IconEnum.php | 158 ----------------------- yii/bootstrap/enum/ProgressEnum.php | 19 --- yii/bootstrap/helpers/Icon.php | 22 ---- yii/bootstrap/helpers/base/Alert.php | 19 ++- yii/bootstrap/helpers/base/Assets.php | 53 ++++++++ yii/bootstrap/helpers/base/Button.php | 30 +++-- yii/bootstrap/helpers/base/Icon.php | 168 ++++++++++++++++++++++++- yii/bootstrap/helpers/base/Progress.php | 2 - yii/bootstrap/widgets/Modal.php | 35 +++--- yii/bootstrap/widgets/base/BootstrapWidget.php | 139 -------------------- yii/bootstrap/widgets/base/Widget.php | 126 +++++++++++++++++++ 15 files changed, 425 insertions(+), 457 deletions(-) delete mode 100644 yii/bootstrap/enum/AlertEnum.php delete mode 100644 yii/bootstrap/enum/BootstrapEnum.php delete mode 100644 yii/bootstrap/enum/ButtonEnum.php create mode 100644 yii/bootstrap/enum/Enum.php delete mode 100644 yii/bootstrap/enum/IconEnum.php delete mode 100644 yii/bootstrap/enum/ProgressEnum.php delete mode 100644 yii/bootstrap/widgets/base/BootstrapWidget.php create mode 100644 yii/bootstrap/widgets/base/Widget.php diff --git a/yii/bootstrap/enum/AlertEnum.php b/yii/bootstrap/enum/AlertEnum.php deleted file mode 100644 index d0096fb..0000000 --- a/yii/bootstrap/enum/AlertEnum.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class AlertEnum -{ - const CLASS_NAME = 'alert'; - - const TYPE_DEFAULT = ''; - const TYPE_SUCCESS = 'alert-success'; - const TYPE_INFORMATION = 'alert-info'; - const TYPE_ERROR = 'alert-error'; - - const SIZE_BLOCK = 'alert-block'; -} \ No newline at end of file diff --git a/yii/bootstrap/enum/BootstrapEnum.php b/yii/bootstrap/enum/BootstrapEnum.php deleted file mode 100644 index ad1d0a8..0000000 --- a/yii/bootstrap/enum/BootstrapEnum.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class BootstrapEnum -{ - const FADE = 'fade'; - const IN = 'in'; - const CLOSE = 'close'; - const DISABLED = 'disabled'; - const ACTIVE = 'active'; - const MODAL = 'modal'; - const HIDE = 'hide'; - const DIALOG = 'dialog'; - const ALERT = 'alert'; -} \ No newline at end of file diff --git a/yii/bootstrap/enum/ButtonEnum.php b/yii/bootstrap/enum/ButtonEnum.php deleted file mode 100644 index 68454e4..0000000 --- a/yii/bootstrap/enum/ButtonEnum.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @since 2.0 - */ -class ButtonEnum -{ - const TYPE_DEFAULT = 'btn'; - const TYPE_PRIMARY = 'btn-primary'; - const TYPE_INFO = 'btn-info'; - const TYPE_SUCCESS = 'btn-success'; - const TYPE_WARNING = 'btn-warning'; - const TYPE_DANGER = 'btn-danger'; - const TYPE_INVERSE = 'btn-inverse'; - const TYPE_LINK = 'btn-link'; - - const SIZE_DEFAULT = ''; - const SIZE_LARGE = 'btn-large'; - const SIZE_SMALL = 'btn-small'; - const SIZE_MINI = 'btn-mini'; - const SIZE_BLOCK = 'btn-block'; - -} \ No newline at end of file diff --git a/yii/bootstrap/enum/Enum.php b/yii/bootstrap/enum/Enum.php new file mode 100644 index 0000000..e11cbb4 --- /dev/null +++ b/yii/bootstrap/enum/Enum.php @@ -0,0 +1,26 @@ + + * @since 2.0 + */ +class Enum +{ + const FADE = 'fade'; + const IN = 'in'; + const CLOSE = 'close'; + const DISABLED = 'disabled'; + const ACTIVE = 'active'; + const MODAL = 'modal'; + const HIDE = 'hide'; + const DIALOG = 'dialog'; + const ALERT = 'alert'; +} \ No newline at end of file diff --git a/yii/bootstrap/enum/IconEnum.php b/yii/bootstrap/enum/IconEnum.php deleted file mode 100644 index bebd8a3..0000000 --- a/yii/bootstrap/enum/IconEnum.php +++ /dev/null @@ -1,158 +0,0 @@ - - * @since 2.0 - */ -class IconEnum -{ - const ICON_GLASS = 'icon-glass'; - const ICON_MUSIC = 'icon-music'; - const ICON_SEARCH = 'icon-search'; - const ICON_ENVELOPE = 'icon-envelope'; - const ICON_HEART = 'icon-heart'; - const ICON_STAR = 'icon-star'; - const ICON_STAR_EMPTY = 'icon-star-empty'; - const ICON_USER = 'icon-user'; - const ICON_FILM = 'icon-film'; - const ICON_TH_LARGE = 'icon-th-large'; - const ICON_TH = 'icon-th'; - const ICON_TH_LIST = 'icon-th-list'; - const ICON_OK = 'icon-ok'; - const ICON_REMOVE = 'icon-remove'; - const ICON_ZOOM_IN = 'icon-zoom-in'; - const ICON_ZOOM_OUT = 'icon-zoom-out'; - const ICON_OFF = 'icon-off'; - const ICON_SIGNAL = 'icon-signal'; - const ICON_COG = 'icon-cog'; - const ICON_TRASH = 'icon-trash'; - const ICON_HOME = 'icon-home'; - const ICON_FILE = 'icon-file'; - const ICON_TIME = 'icon-time'; - const ICON_ROAD = 'icon-road'; - const ICON_DOWNLOAD_ALT = 'icon-download-alt'; - const ICON_DOWNLOAD = 'icon-download'; - const ICON_UPLOAD = 'icon-upload'; - const ICON_INBOX = 'icon-inbox'; - const ICON_PLAY_CIRCLE = 'icon-play-circle'; - const ICON_REPEAT = 'icon-repeat'; - const ICON_REFRESH = 'icon-refresh'; - const ICON_LIST_ALT = 'icon-list-alt'; - const ICON_LOCK = 'icon-lock'; - const ICON_FLAG = 'icon-flag'; - const ICON_HEADPHONES = 'icon-headphones'; - const ICON_VOLUME_OFF = 'icon-volume-off'; - const ICON_VOLUME_DOWN = 'icon-volume-down'; - const ICON_VOLUME_UP = 'icon-volume-up'; - const ICON_QRCODE = 'icon-qrcode'; - const ICON_BARCODE = 'icon-barcode'; - const ICON_TAG = 'icon-tag'; - const ICON_TAGS = 'icon-tags'; - const ICON_BOOK = 'icon-book'; - const ICON_BOOKMARK = 'icon-bookmark'; - const ICON_PRINT = 'icon-print'; - const ICON_CAMERA = 'icon-camera'; - const ICON_FONT = 'icon-font'; - const ICON_BOLD = 'icon-bold'; - const ICON_ITALIC = 'icon-italic'; - const ICON_TEXT_HEIGHT = 'icon-text-height'; - const ICON_TEXT_WIDTH = 'icon-text-width'; - const ICON_ALIGN_LEFT = 'icon-align-left'; - const ICON_ALIGN_CENTER = 'icon-align-center'; - const ICON_ALIGN_RIGHT = 'icon-align-right'; - const ICON_ALIGN_JUSTIFY = 'icon-align-justify'; - const ICON_LIST = 'icon-list'; - const ICON_INDENT_LEFT = 'icon-indent-left'; - const ICON_INDENT_RIGHT = 'icon-indent-right'; - const ICON_FACETIME_VIDEO = 'icon-facetime-video'; - const ICON_PICTURE = 'icon-picture'; - const ICON_PENCIL = 'icon-pencil'; - const ICON_MAP_MARKER = 'icon-map-marker'; - const ICON_ADJUST = 'icon-adjust'; - const ICON_TINT = 'icon-tint'; - const ICON_EDIT = 'icon-edit'; - const ICON_SHARE = 'icon-share'; - const ICON_CHECK = 'icon-check'; - const ICON_MOVE = 'icon-move'; - const ICON_STEP_BACKWARD = 'icon-step-backward'; - const ICON_FAST_BACKWARD = 'icon-fast-backward'; - const ICON_BACKWARD = 'icon-backward'; - const ICON_PLAY = 'icon-play'; - const ICON_PAUSE = 'icon-pause'; - const ICON_STOP = 'icon-pause'; - const ICON_FORWARD = 'icon-forward'; - const ICON_FAST_FORWARD = 'icon-fast-forward'; - const ICON_STEP_FORWARD = 'icon-step-forward'; - const ICON_EJECT = 'icon-eject'; - const ICON_CHEVRON_LEFT = 'icon-chevron-left'; - const ICON_CHEVRON_RIGHT = 'icon-chevron-right'; - const ICON_PLUS_SIGN = 'icon-plus-sign'; - const ICON_MINUS_SIGN = 'icon-minus-sign'; - const ICON_REMOVE_SIGN = 'icon-remove-sign'; - const ICON_OK_SIGN = 'icon-ok-sign'; - const ICON_QUESTION_SIGN = 'icon-question-sign'; - const ICON_INFO_SIGN = 'icon-info-sign'; - const ICON_SCREENSHOT = 'icon-screenshot'; - const ICON_REMOVE_CIRCLE = 'icon-remove-circle'; - const ICON_OK_CIRCLE = 'icon-ok-circle'; - const ICON_BAN_CIRCLE = 'icon-ban-circle'; - const ICON_ARROW_LEFT = 'icon-arrow-left'; - const ICON_ARROW_RIGHT = 'icon-arrow-right'; - const ICON_ARROW_UP = 'icon-arrow-up'; - const ICON_ARROW_DOWN = 'icon-arrow-down'; - const ICON_SHARE_ALT = 'icon-share-alt'; - const ICON_RESIZE_FULL = 'icon-resize-full'; - const ICON_RESIZE_SMALL = 'icon-resize-small'; - const ICON_PLUS = 'icon-plus'; - const ICON_MINUS = 'icon-minus'; - const ICON_ASTERISK = 'icon-asterisk'; - const ICON_EXCLAMATION_SIGN = 'icon-exclamation-sign'; - const ICON_GIFT = 'icon-gift'; - const ICON_LEAF = 'icon-leaf'; - const ICON_FIRE = 'icon-fire'; - const ICON_EYE_OPEN = 'icon-eye-open'; - const ICON_EYE_CLOSE = 'icon-eye-close'; - const ICON_WARNING_SIGN = 'icon-warning-sign'; - const ICON_PLANE = 'icon-plane'; - const ICON_CALENDAR = 'icon-calendar'; - const ICON_RANDOM = 'icon-random'; - const ICON_COMMENT = 'icon-comment'; - const ICON_MAGNET = 'icon-magnet'; - const ICON_CHEVRON_UP = 'icon-chevron-up'; - const ICON_CHEVRON_DOWN = 'icon-chevron-down'; - const ICON_RETWEET = 'icon-retweet'; - const ICON_SHOPPING_CART = 'icon-shopping-cart'; - const ICON_FOLDER_CLOSE = 'icon-folder-close'; - const ICON_FOLDER_OPEN = 'icon-folder-open'; - const ICON_RESIZE_VERTICAL = 'icon-resize-vertical'; - const ICON_RESIZE_HORIZONTAL = 'icon-resize-horizontal'; - const ICON_HDD = 'icon-hdd'; - const ICON_BULLHORN = 'icon-bullhorn'; - const ICON_BELL = 'icon-bell'; - const ICON_CERTFICATE = 'icon-certificate'; - const ICON_THUMBS_UP = 'icon-thumbs-up'; - const ICON_THUMBS_DOWN = 'icon-thumbs-down'; - const ICON_HAND_RIGHT = 'icon-hand-right'; - const ICON_HAND_LEFT = 'icon-hand-left'; - const ICON_HAND_UP = 'icon-hand-up'; - const ICON_HAND_DOWN = 'icon-hand-down'; - const ICON_CIRCLE_ARROW_RIGHT = 'icon-circle-arrow-right'; - const ICON_CIRCLE_ARROW_LEFT = 'icon-circle-arrow-left'; - const ICON_CIRCLE_ARROW_UP = 'icon-circle-arrow-up'; - const ICON_CIRCLE_ARROW_DOWN = 'icon-circle-arrow-down'; - const ICON_GLOBE = 'icon-globe'; - const ICON_WRENCH = 'icon-wrench'; - const ICON_TASKS = 'icon-tasks'; - const ICON_FILTER = 'icon-filter'; - const ICON_BRIEFCASE = 'icon-briefcase'; - const ICON_FULLSCREEN = 'icon-fullscreen'; -} \ No newline at end of file diff --git a/yii/bootstrap/enum/ProgressEnum.php b/yii/bootstrap/enum/ProgressEnum.php deleted file mode 100644 index 44a8b51..0000000 --- a/yii/bootstrap/enum/ProgressEnum.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @since 2.0 - */ -class ProgressEnum -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Icon.php b/yii/bootstrap/helpers/Icon.php index 41eb0b9..1be2660 100644 --- a/yii/bootstrap/helpers/Icon.php +++ b/yii/bootstrap/helpers/Icon.php @@ -17,27 +17,5 @@ use yii\helpers\Html; */ class Icon extends base\Icon { - /** - * Generates an icon. - * @param string $icon the icon type. - * @param array $htmlOptions additional HTML attributes. - * @return string the generated icon. - */ - public static function i($icon, $htmlOptions = array()) - { - if (is_string($icon)) - { - if (strpos($icon, 'icon-') === false) - $icon = 'icon-' . implode(' icon-', explode(' ', $icon)); - // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? - if (isset($htmlOptions['class'])) - $htmlOptions['class'] .= ' ' . $icon; - else - $htmlOptions['class'] = $icon; - - return Html::tag('i', '', $htmlOptions); - } - return ''; - } } \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Alert.php b/yii/bootstrap/helpers/base/Alert.php index bc6f899..23899d6 100644 --- a/yii/bootstrap/helpers/base/Alert.php +++ b/yii/bootstrap/helpers/base/Alert.php @@ -7,8 +7,7 @@ namespace yii\bootstrap\helpers\base; -use yii\bootstrap\enum\AlertEnum; -use yii\bootstrap\enum\BootstrapEnum; +use yii\bootstrap\enum\Enum; use yii\helpers\Html; /** @@ -21,6 +20,16 @@ class Alert { /** + * constants + */ + const CLASS_NAME = 'alert'; + const TYPE_DEFAULT = ''; + const TYPE_SUCCESS = 'alert-success'; + const TYPE_INFORMATION = 'alert-info'; + const TYPE_ERROR = 'alert-error'; + const SIZE_BLOCK = 'alert-block'; + + /** * Generates an alert box * @param $message * @param array $htmlOptions @@ -31,14 +40,14 @@ class Alert { // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? if (isset($htmlOptions['class'])) - $htmlOptions['class'] .= ' ' . AlertEnum::CLASS_NAME; + $htmlOptions['class'] .= ' ' . static::CLASS_NAME; else - $htmlOptions['class'] = AlertEnum::CLASS_NAME; + $htmlOptions['class'] = static::CLASS_NAME; ob_start(); echo Html::beginTag('div', $htmlOptions); if ($dismiss) - echo Button::closeLink('×', BootstrapEnum::ALERT); + echo Button::closeLink('×', Enum::ALERT); echo $message; echo Html::endTag('div'); return ob_get_clean(); diff --git a/yii/bootstrap/helpers/base/Assets.php b/yii/bootstrap/helpers/base/Assets.php index 30cd8ae..3f7f7e6 100644 --- a/yii/bootstrap/helpers/base/Assets.php +++ b/yii/bootstrap/helpers/base/Assets.php @@ -6,7 +6,11 @@ */ namespace yii\bootstrap\helpers\base; + use Yii; +use yii\helpers\Json; +use yii\web\JsExpression; + /** * Assets provides methods to register bootstrap assets. @@ -22,4 +26,53 @@ class Assets Yii::$app->getView()->registerAssetBundle($bundle); } + + /** + * Registers plugin events with the API. + * + * @param string $selector the CSS selector. + * @param string[] $events the JavaScript event configuration (name=>handler). + * @param int $position the position of the JavaScript code. + * @return boolean whether the events were registered. + */ + public static function registerEvents($selector, $events = array(), $position = View::POS_END) + { + if (empty($events)) + return; + + $script = ''; + foreach ($events as $name => $handler) { + $handler = ($handler instanceof JsExpression) + ? $handler + : new JsExpression($handler); + + $script .= ";jQuery(document).ready(function (){jQuery('{$selector}').on('{$name}', {$handler});});"; + } + if (!empty($script)) + Yii::$app->getView()>registerJs($script, array('position' => $position), static::getUniqueScriptId()); + } + + /** + * Registers a specific Bootstrap plugin using the given selector and options. + * + * @param string $selector the CSS selector. + * @param string $name the name of the plugin + * @param array $options the JavaScript options for the plugin. + * @param int $position the position of the JavaScript code. + */ + public static function registerPlugin($selector, $name, $options = array(), $position = View::POS_END) + { + $options = !empty($options) ? Json::encode($options) : ''; + $script = ";jQuery(document).ready(function (){jQuery('{$selector}').{$name}({$options});});"; + Yii::$app->getView()->registerJs($script, array('position'=>$position)); + } + + /** + * Generates a "somewhat" random id string. + * @return string the id. + */ + public static function getUniqueScriptId() + { + return uniqid(time() . '#', true); + } } \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Button.php b/yii/bootstrap/helpers/base/Button.php index 2ae9da5..c0ea329 100644 --- a/yii/bootstrap/helpers/base/Button.php +++ b/yii/bootstrap/helpers/base/Button.php @@ -7,9 +7,7 @@ namespace yii\bootstrap\helpers\base; -use yii\bootstrap\enum\AlertEnum; -use yii\bootstrap\enum\ButtonEnum; -use yii\bootstrap\enum\BootstrapEnum; +use yii\bootstrap\enum\Enum; use yii\helpers\Html; /** @@ -21,6 +19,24 @@ use yii\helpers\Html; class Button { /** + * constants + */ + const TYPE_DEFAULT = 'btn'; + const TYPE_PRIMARY = 'btn-primary'; + const TYPE_INFO = 'btn-info'; + const TYPE_SUCCESS = 'btn-success'; + const TYPE_WARNING = 'btn-warning'; + const TYPE_DANGER = 'btn-danger'; + const TYPE_INVERSE = 'btn-inverse'; + const TYPE_LINK = 'btn-link'; + + const SIZE_DEFAULT = ''; + const SIZE_LARGE = 'btn-large'; + const SIZE_SMALL = 'btn-small'; + const SIZE_MINI = 'btn-mini'; + const SIZE_BLOCK = 'btn-block'; + + /** * Returns a dismissal alert link * @param string $text * @param string $dismiss what to dismiss (alert or modal) @@ -28,7 +44,7 @@ class Button */ public static function closeLink($text = '×', $dismiss = null) { - $options = array('class' => BootstrapEnum::CLOSE); + $options = array('class' => Enum::CLOSE); if(null !== $dismiss) $options['data-dismiss'] = $dismiss; return Html::a($text, '#', $options); @@ -42,7 +58,7 @@ class Button */ public static function closeButton($text = '×', $dismiss = null) { - $options = array('type' => 'button', 'class' => BootstrapEnum::CLOSE); + $options = array('type' => 'button', 'class' => Enum::CLOSE); if(null !== $dismiss) $options['data-dismiss'] = $dismiss; @@ -60,9 +76,9 @@ class Button { // TODO: consider method add or append to ArrayHelper class if (isset($htmlOptions['class'])) - $htmlOptions['class'] .= ' ' . ButtonEnum::TYPE_LINK; + $htmlOptions['class'] .= ' ' . static::TYPE_LINK; else - $htmlOptions['class'] = ButtonEnum::TYPE_LINK; + $htmlOptions['class'] = static::TYPE_LINK; return Html::a($label, '#', $htmlOptions); } diff --git a/yii/bootstrap/helpers/base/Icon.php b/yii/bootstrap/helpers/base/Icon.php index 47b0b05..a11d7e6 100644 --- a/yii/bootstrap/helpers/base/Icon.php +++ b/yii/bootstrap/helpers/base/Icon.php @@ -7,8 +7,6 @@ namespace yii\bootstrap\helpers\base; -use yii\bootstrap\enum\IconEnum; - /** * Icon allows you to render Bootstrap Glyphicons sets * @@ -17,5 +15,171 @@ use yii\bootstrap\enum\IconEnum; */ class Icon { + /** + * constants + */ + const ICON_GLASS = 'icon-glass'; + const ICON_MUSIC = 'icon-music'; + const ICON_SEARCH = 'icon-search'; + const ICON_ENVELOPE = 'icon-envelope'; + const ICON_HEART = 'icon-heart'; + const ICON_STAR = 'icon-star'; + const ICON_STAR_EMPTY = 'icon-star-empty'; + const ICON_USER = 'icon-user'; + const ICON_FILM = 'icon-film'; + const ICON_TH_LARGE = 'icon-th-large'; + const ICON_TH = 'icon-th'; + const ICON_TH_LIST = 'icon-th-list'; + const ICON_OK = 'icon-ok'; + const ICON_REMOVE = 'icon-remove'; + const ICON_ZOOM_IN = 'icon-zoom-in'; + const ICON_ZOOM_OUT = 'icon-zoom-out'; + const ICON_OFF = 'icon-off'; + const ICON_SIGNAL = 'icon-signal'; + const ICON_COG = 'icon-cog'; + const ICON_TRASH = 'icon-trash'; + const ICON_HOME = 'icon-home'; + const ICON_FILE = 'icon-file'; + const ICON_TIME = 'icon-time'; + const ICON_ROAD = 'icon-road'; + const ICON_DOWNLOAD_ALT = 'icon-download-alt'; + const ICON_DOWNLOAD = 'icon-download'; + const ICON_UPLOAD = 'icon-upload'; + const ICON_INBOX = 'icon-inbox'; + const ICON_PLAY_CIRCLE = 'icon-play-circle'; + const ICON_REPEAT = 'icon-repeat'; + const ICON_REFRESH = 'icon-refresh'; + const ICON_LIST_ALT = 'icon-list-alt'; + const ICON_LOCK = 'icon-lock'; + const ICON_FLAG = 'icon-flag'; + const ICON_HEADPHONES = 'icon-headphones'; + const ICON_VOLUME_OFF = 'icon-volume-off'; + const ICON_VOLUME_DOWN = 'icon-volume-down'; + const ICON_VOLUME_UP = 'icon-volume-up'; + const ICON_QRCODE = 'icon-qrcode'; + const ICON_BARCODE = 'icon-barcode'; + const ICON_TAG = 'icon-tag'; + const ICON_TAGS = 'icon-tags'; + const ICON_BOOK = 'icon-book'; + const ICON_BOOKMARK = 'icon-bookmark'; + const ICON_PRINT = 'icon-print'; + const ICON_CAMERA = 'icon-camera'; + const ICON_FONT = 'icon-font'; + const ICON_BOLD = 'icon-bold'; + const ICON_ITALIC = 'icon-italic'; + const ICON_TEXT_HEIGHT = 'icon-text-height'; + const ICON_TEXT_WIDTH = 'icon-text-width'; + const ICON_ALIGN_LEFT = 'icon-align-left'; + const ICON_ALIGN_CENTER = 'icon-align-center'; + const ICON_ALIGN_RIGHT = 'icon-align-right'; + const ICON_ALIGN_JUSTIFY = 'icon-align-justify'; + const ICON_LIST = 'icon-list'; + const ICON_INDENT_LEFT = 'icon-indent-left'; + const ICON_INDENT_RIGHT = 'icon-indent-right'; + const ICON_FACETIME_VIDEO = 'icon-facetime-video'; + const ICON_PICTURE = 'icon-picture'; + const ICON_PENCIL = 'icon-pencil'; + const ICON_MAP_MARKER = 'icon-map-marker'; + const ICON_ADJUST = 'icon-adjust'; + const ICON_TINT = 'icon-tint'; + const ICON_EDIT = 'icon-edit'; + const ICON_SHARE = 'icon-share'; + const ICON_CHECK = 'icon-check'; + const ICON_MOVE = 'icon-move'; + const ICON_STEP_BACKWARD = 'icon-step-backward'; + const ICON_FAST_BACKWARD = 'icon-fast-backward'; + const ICON_BACKWARD = 'icon-backward'; + const ICON_PLAY = 'icon-play'; + const ICON_PAUSE = 'icon-pause'; + const ICON_STOP = 'icon-pause'; + const ICON_FORWARD = 'icon-forward'; + const ICON_FAST_FORWARD = 'icon-fast-forward'; + const ICON_STEP_FORWARD = 'icon-step-forward'; + const ICON_EJECT = 'icon-eject'; + const ICON_CHEVRON_LEFT = 'icon-chevron-left'; + const ICON_CHEVRON_RIGHT = 'icon-chevron-right'; + const ICON_PLUS_SIGN = 'icon-plus-sign'; + const ICON_MINUS_SIGN = 'icon-minus-sign'; + const ICON_REMOVE_SIGN = 'icon-remove-sign'; + const ICON_OK_SIGN = 'icon-ok-sign'; + const ICON_QUESTION_SIGN = 'icon-question-sign'; + const ICON_INFO_SIGN = 'icon-info-sign'; + const ICON_SCREENSHOT = 'icon-screenshot'; + const ICON_REMOVE_CIRCLE = 'icon-remove-circle'; + const ICON_OK_CIRCLE = 'icon-ok-circle'; + const ICON_BAN_CIRCLE = 'icon-ban-circle'; + const ICON_ARROW_LEFT = 'icon-arrow-left'; + const ICON_ARROW_RIGHT = 'icon-arrow-right'; + const ICON_ARROW_UP = 'icon-arrow-up'; + const ICON_ARROW_DOWN = 'icon-arrow-down'; + const ICON_SHARE_ALT = 'icon-share-alt'; + const ICON_RESIZE_FULL = 'icon-resize-full'; + const ICON_RESIZE_SMALL = 'icon-resize-small'; + const ICON_PLUS = 'icon-plus'; + const ICON_MINUS = 'icon-minus'; + const ICON_ASTERISK = 'icon-asterisk'; + const ICON_EXCLAMATION_SIGN = 'icon-exclamation-sign'; + const ICON_GIFT = 'icon-gift'; + const ICON_LEAF = 'icon-leaf'; + const ICON_FIRE = 'icon-fire'; + const ICON_EYE_OPEN = 'icon-eye-open'; + const ICON_EYE_CLOSE = 'icon-eye-close'; + const ICON_WARNING_SIGN = 'icon-warning-sign'; + const ICON_PLANE = 'icon-plane'; + const ICON_CALENDAR = 'icon-calendar'; + const ICON_RANDOM = 'icon-random'; + const ICON_COMMENT = 'icon-comment'; + const ICON_MAGNET = 'icon-magnet'; + const ICON_CHEVRON_UP = 'icon-chevron-up'; + const ICON_CHEVRON_DOWN = 'icon-chevron-down'; + const ICON_RETWEET = 'icon-retweet'; + const ICON_SHOPPING_CART = 'icon-shopping-cart'; + const ICON_FOLDER_CLOSE = 'icon-folder-close'; + const ICON_FOLDER_OPEN = 'icon-folder-open'; + const ICON_RESIZE_VERTICAL = 'icon-resize-vertical'; + const ICON_RESIZE_HORIZONTAL = 'icon-resize-horizontal'; + const ICON_HDD = 'icon-hdd'; + const ICON_BULLHORN = 'icon-bullhorn'; + const ICON_BELL = 'icon-bell'; + const ICON_CERTFICATE = 'icon-certificate'; + const ICON_THUMBS_UP = 'icon-thumbs-up'; + const ICON_THUMBS_DOWN = 'icon-thumbs-down'; + const ICON_HAND_RIGHT = 'icon-hand-right'; + const ICON_HAND_LEFT = 'icon-hand-left'; + const ICON_HAND_UP = 'icon-hand-up'; + const ICON_HAND_DOWN = 'icon-hand-down'; + const ICON_CIRCLE_ARROW_RIGHT = 'icon-circle-arrow-right'; + const ICON_CIRCLE_ARROW_LEFT = 'icon-circle-arrow-left'; + const ICON_CIRCLE_ARROW_UP = 'icon-circle-arrow-up'; + const ICON_CIRCLE_ARROW_DOWN = 'icon-circle-arrow-down'; + const ICON_GLOBE = 'icon-globe'; + const ICON_WRENCH = 'icon-wrench'; + const ICON_TASKS = 'icon-tasks'; + const ICON_FILTER = 'icon-filter'; + const ICON_BRIEFCASE = 'icon-briefcase'; + const ICON_FULLSCREEN = 'icon-fullscreen'; + + /** + * Generates an icon. + * @param string $icon the icon type. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated icon. + */ + public static function i($icon, $htmlOptions = array()) + { + if (is_string($icon)) + { + if (strpos($icon, 'icon-') === false) + $icon = 'icon-' . implode(' icon-', explode(' ', $icon)); + + // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? + if (isset($htmlOptions['class'])) + $htmlOptions['class'] .= ' ' . $icon; + else + $htmlOptions['class'] = $icon; + return Html::tag('i', '', $htmlOptions); + } + return ''; + } } \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Progress.php b/yii/bootstrap/helpers/base/Progress.php index a13a44f..8006f66 100644 --- a/yii/bootstrap/helpers/base/Progress.php +++ b/yii/bootstrap/helpers/base/Progress.php @@ -7,8 +7,6 @@ namespace yii\bootstrap\helpers\base; -use yii\bootstrap\enum\ProgressEnum; - /** * Progress provides methods to make use of bootstrap progress bars in your application * diff --git a/yii/bootstrap/widgets/Modal.php b/yii/bootstrap/widgets/Modal.php index c591944..15e874b 100644 --- a/yii/bootstrap/widgets/Modal.php +++ b/yii/bootstrap/widgets/Modal.php @@ -11,8 +11,7 @@ use Yii; use yii\helpers\Html; use yii\helpers\ArrayHelper; use yii\bootstrap\helpers\Button; -use yii\bootstrap\enum\BootstrapEnum; -use yii\web\JsExpression; +use yii\bootstrap\enum\Enum; /** * Modal renders a bootstrap modal on the page for its use on your application. @@ -27,7 +26,7 @@ use yii\web\JsExpression; * 'footer' => '//modal/_footer', // we can also use view paths * 'buttonOptions' => array( * 'label' => 'Show Modal', - * 'class' => \yii\bootstrap\enum\ButtonEnum::TYPE_DEFAULT + * 'class' => \yii\bootstrap\enum\Button::TYPE_DEFAULT * ) * )); * ``` @@ -35,7 +34,7 @@ use yii\web\JsExpression; * @author Antonio Ramirez * @since 2.0 */ -class Modal extends base\BootstrapWidget +class Modal extends base\Widget { /** * @var array The additional HTML attributes of the button that will show the modal. If empty array, only @@ -140,14 +139,14 @@ class Modal extends base\BootstrapWidget $this->defaultOption('id', $this->getId()); $this->selector = '#' . ArrayHelper::getValue($this->options, 'id'); - $this->defaultOption('role', BootstrapEnum::DIALOG); + $this->defaultOption('role', Enum::DIALOG); $this->defaultOption('tabindex', '-1'); - $this->addOption('class', BootstrapEnum::MODAL); - $this->addOption('class', BootstrapEnum::HIDE); + $this->addOption('class', Enum::MODAL); + $this->addOption('class', Enum::HIDE); if ($this->fade) - $this->addOption('class', BootstrapEnum::FADE); + $this->addOption('class', Enum::FADE); $this->initPluginOptions(); $this->initPluginEvents(); @@ -204,7 +203,7 @@ class Modal extends base\BootstrapWidget $this->buttonOptions['data-toggle'] = isset($this->buttonOptions['data-toggle']) ? $this->buttonOptions['data-toggle'] - : BootstrapEnum::MODAL; + : Enum::MODAL; if ($this->remote !== null && !isset($this->buttonOptions['data-remote'])) $this->buttonOptions['data-remote'] = Html::url($this->remote); @@ -230,13 +229,13 @@ class Modal extends base\BootstrapWidget */ public function renderModal() { - echo Html::beginTag('div', $this->options) . PHP_EOL; + echo Html::beginTag('div', $this->options); $this->renderModalHeader(); $this->renderModalBody(); $this->renderModalFooter(); - echo Html::endTag('div') . PHP_EOL; + echo Html::endTag('div'); } /** @@ -244,11 +243,11 @@ class Modal extends base\BootstrapWidget */ public function renderModalHeader() { - echo '' . PHP_EOL; + echo Html::endTag('div'); } /** @@ -256,9 +255,9 @@ class Modal extends base\BootstrapWidget */ public function renderModalBody() { - echo '' . PHP_EOL; + echo Html::endTag('div'); } /** @@ -267,9 +266,9 @@ class Modal extends base\BootstrapWidget public function renderModalFooter() { - echo '' . PHP_EOL; + echo Html::endTag('div'); } /** diff --git a/yii/bootstrap/widgets/base/BootstrapWidget.php b/yii/bootstrap/widgets/base/BootstrapWidget.php deleted file mode 100644 index 042f6f9..0000000 --- a/yii/bootstrap/widgets/base/BootstrapWidget.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @since 2.0 - */ -class BootstrapWidget extends Widget -{ - - /** - * @var bool whether to register the asset - */ - public $responsive = true; - - /** - * @var array the HTML attributes for the widget container tag. - */ - public $options = array(); - - /** - * @var string the widget name - */ - protected $name; - - /** - * @var string the jQuery selector of the widget - */ - protected $selector; - - /** - * Initializes the widget. - */ - public function init() - { - $this->view->registerAssetBundle(($this->responsive ? 'yii/bootstrap' : 'yii/bootstrap-responsive')); - } - - /** - * Registers plugin events with the API. - * @param string $selector the CSS selector. - * @param string[] $events the JavaScript event configuration (name=>handler). - * @param int $position the position of the JavaScript code. - * @return boolean whether the events were registered. - */ - protected function registerEvents($selector, $events = array(), $position = View::POS_END) - { - if (empty($events)) - return; - - $script = ''; - foreach ($events as $name => $handler) { - $handler = ($handler instanceof JsExpression) - ? $handler - : new JsExpression($handler); - - $script .= ";jQuery(document).ready(function (){jQuery('{$selector}').on('{$name}', {$handler});});"; - } - if (!empty($script)) - $this->view->registerJs($script, array('position' => $position), $this->getUniqueScriptId()); - } - - /** - * Registers a specific Bootstrap plugin using the given selector and options. - * @param string $selector the CSS selector. - * @param array $options the JavaScript options for the plugin. - * @param int $position the position of the JavaScript code. - * @throws \yii\base\InvalidCallException - */ - public function registerPlugin($selector, $options = array(), $position = View::POS_END) - { - if(null === $this->name) - throw new InvalidCallException(); - - $options = !empty($options) ? Json::encode($options) : ''; - $script = ";jQuery(document).ready(function (){jQuery('{$selector}').{$this->name}({$options});});"; - $this->view->registerJs($script, array('position'=>$position)); - } - - /** - * Generates a "somewhat" random id string. - * @return string the id. - * @todo not sure it should be here or - */ - protected function getUniqueScriptId() - { - return uniqid(time() . '#', true); - } - - /** - * Adds a new option. If the key does not exists, it will create one, if it exists it will append the value - * and also makes sure the uniqueness of them. - * - * @param string $key - * @param mixed $value - * @param string $glue - * @return array - */ - protected function addOption($key, $value, $glue = ' ') - { - if (isset($this->options[$key])) { - if (!is_array($this->options[$key])) - $this->options[$key] = explode($glue, $this->options[$key]); - $this->options[$key][] = $value; - $this->options[$key] = array_unique($this->options[$key]); - $this->options[$key] = implode($glue, $this->options[$key]); - } else - $this->options[$key] = $value; - return $this->options; - } - - /** - * Sets the default value for an item if not set. - * @param string $key the name of the item. - * @param mixed $value the default value. - * @return array - */ - protected function defaultOption($key, $value) - { - if (!isset($this->options[$key])) - $this->options[$key] = $value; - return $this->options; - } -} \ No newline at end of file diff --git a/yii/bootstrap/widgets/base/Widget.php b/yii/bootstrap/widgets/base/Widget.php new file mode 100644 index 0000000..822f761 --- /dev/null +++ b/yii/bootstrap/widgets/base/Widget.php @@ -0,0 +1,126 @@ + + * @since 2.0 + */ +class Widget extends \yii\base\Widget +{ + + /** + * @var bool whether to register the asset + */ + public $responsive = true; + + /** + * @var array the HTML attributes for the widget container tag. + */ + public $options = array(); + + /** + * @var string the widget name + */ + protected $name; + + /** + * @var string the jQuery selector of the widget + */ + protected $selector; + + /** + * Initializes the widget. + */ + public function init() + { + // ensure bundle + Assets::registerBundle($this->responsive); + } + + /** + * Registers plugin events with the API. + * @param string $selector the CSS selector. + * @param string[] $events the JavaScript event configuration (name=>handler). + * @param int $position the position of the JavaScript code. + * @return boolean whether the events were registered. + */ + protected function registerEvents($selector, $events = array(), $position = View::POS_END) + { + Assets::registerEvents($selector, $events, $position); + } + + /** + * Registers a specific Bootstrap plugin using the given selector and options. + * @param string $selector the CSS selector. + * @param array $options the JavaScript options for the plugin. + * @param int $position the position of the JavaScript code. + * @throws \yii\base\InvalidCallException + */ + public function registerPlugin($selector, $options = array(), $position = View::POS_END) + { + if(null === $this->name) + throw new InvalidCallException(); + + Assets::registerPlugin($selector, $this->name, $options, $position); + } + + /** + * Generates a "somewhat" random id string. + * @return string the id. + * @todo not sure it should be here or + */ + protected function getUniqueScriptId() + { + return uniqid(time() . '#', true); + } + + /** + * Adds a new option. If the key does not exists, it will create one, if it exists it will append the value + * and also makes sure the uniqueness of them. + * + * @param string $key + * @param mixed $value + * @param string $glue + * @return array + */ + protected function addOption($key, $value, $glue = ' ') + { + if (isset($this->options[$key])) { + if (!is_array($this->options[$key])) + $this->options[$key] = explode($glue, $this->options[$key]); + $this->options[$key][] = $value; + $this->options[$key] = array_unique($this->options[$key]); + $this->options[$key] = implode($glue, $this->options[$key]); + } else + $this->options[$key] = $value; + return $this->options; + } + + /** + * Sets the default value for an item if not set. + * @param string $key the name of the item. + * @param mixed $value the default value. + * @return array + */ + protected function defaultOption($key, $value) + { + if (!isset($this->options[$key])) + $this->options[$key] = $value; + return $this->options; + } +} \ No newline at end of file From ab695d1118d522d403cbf79677589abaee449309 Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Sun, 19 May 2013 22:37:57 +0200 Subject: [PATCH 03/14] remove from master (update track) --- yii/helpers/Inflector.php | 18 -- yii/helpers/base/Inflector.php | 523 ----------------------------------------- 2 files changed, 541 deletions(-) delete mode 100644 yii/helpers/Inflector.php delete mode 100644 yii/helpers/base/Inflector.php diff --git a/yii/helpers/Inflector.php b/yii/helpers/Inflector.php deleted file mode 100644 index 5ffe0fe..0000000 --- a/yii/helpers/Inflector.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @since 2.0 - */ -class Inflector extends base\Inflector -{ -} diff --git a/yii/helpers/base/Inflector.php b/yii/helpers/base/Inflector.php deleted file mode 100644 index 8c2d487..0000000 --- a/yii/helpers/base/Inflector.php +++ /dev/null @@ -1,523 +0,0 @@ - - * @since 2.0 - */ -class Inflector -{ - - /** - * @var array rules of plural words - */ - protected static $plural = array( - 'rules' => array( - '/(s)tatus$/i' => '\1\2tatuses', - '/(quiz)$/i' => '\1zes', - '/^(ox)$/i' => '\1\2en', - '/([m|l])ouse$/i' => '\1ice', - '/(matr|vert|ind)(ix|ex)$/i' => '\1ices', - '/(x|ch|ss|sh)$/i' => '\1es', - '/([^aeiouy]|qu)y$/i' => '\1ies', - '/(hive)$/i' => '\1s', - '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', - '/sis$/i' => 'ses', - '/([ti])um$/i' => '\1a', - '/(p)erson$/i' => '\1eople', - '/(m)an$/i' => '\1en', - '/(c)hild$/i' => '\1hildren', - '/(buffal|tomat)o$/i' => '\1\2oes', - '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i', - '/us$/i' => 'uses', - '/(alias)$/i' => '\1es', - '/(ax|cris|test)is$/i' => '\1es', - '/s$/' => 's', - '/^$/' => '', - '/$/' => 's', - ), - 'uninflected' => array( - '.*[nrlm]ese', - '.*deer', - '.*fish', - '.*measles', - '.*ois', - '.*pox', - '.*sheep', - 'people' - ), - 'irregular' => array( - 'atlas' => 'atlases', - 'beef' => 'beefs', - 'brother' => 'brothers', - 'cafe' => 'cafes', - 'child' => 'children', - 'cookie' => 'cookies', - 'corpus' => 'corpuses', - 'cow' => 'cows', - 'ganglion' => 'ganglions', - 'genie' => 'genies', - 'genus' => 'genera', - 'graffito' => 'graffiti', - 'hoof' => 'hoofs', - 'loaf' => 'loaves', - 'man' => 'men', - 'money' => 'monies', - 'mongoose' => 'mongooses', - 'move' => 'moves', - 'mythos' => 'mythoi', - 'niche' => 'niches', - 'numen' => 'numina', - 'occiput' => 'occiputs', - 'octopus' => 'octopuses', - 'opus' => 'opuses', - 'ox' => 'oxen', - 'penis' => 'penises', - 'person' => 'people', - 'sex' => 'sexes', - 'soliloquy' => 'soliloquies', - 'testis' => 'testes', - 'trilby' => 'trilbys', - 'turf' => 'turfs' - ) - ); - /** - * @var array the rules to singular inflector - */ - protected static $singular = array( - 'rules' => array( - '/(s)tatuses$/i' => '\1\2tatus', - '/^(.*)(menu)s$/i' => '\1\2', - '/(quiz)zes$/i' => '\\1', - '/(matr)ices$/i' => '\1ix', - '/(vert|ind)ices$/i' => '\1ex', - '/^(ox)en/i' => '\1', - '/(alias)(es)*$/i' => '\1', - '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', - '/([ftw]ax)es/i' => '\1', - '/(cris|ax|test)es$/i' => '\1is', - '/(shoe|slave)s$/i' => '\1', - '/(o)es$/i' => '\1', - '/ouses$/' => 'ouse', - '/([^a])uses$/' => '\1us', - '/([m|l])ice$/i' => '\1ouse', - '/(x|ch|ss|sh)es$/i' => '\1', - '/(m)ovies$/i' => '\1\2ovie', - '/(s)eries$/i' => '\1\2eries', - '/([^aeiouy]|qu)ies$/i' => '\1y', - '/([lr])ves$/i' => '\1f', - '/(tive)s$/i' => '\1', - '/(hive)s$/i' => '\1', - '/(drive)s$/i' => '\1', - '/([^fo])ves$/i' => '\1fe', - '/(^analy)ses$/i' => '\1sis', - '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', - '/([ti])a$/i' => '\1um', - '/(p)eople$/i' => '\1\2erson', - '/(m)en$/i' => '\1an', - '/(c)hildren$/i' => '\1\2hild', - '/(n)ews$/i' => '\1\2ews', - '/eaus$/' => 'eau', - '/^(.*us)$/' => '\\1', - '/s$/i' => '' - ), - 'uninflected' => array( - '.*[nrlm]ese', - '.*deer', - '.*fish', - '.*measles', - '.*ois', - '.*pox', - '.*sheep', - '.*ss' - ), - 'irregular' => array( - 'foes' => 'foe', - 'waves' => 'wave', - 'curves' => 'curve' - ) - ); - - /** - * @var array list of words that should not be inflected - */ - protected static $uninflected = array( - 'Amoyese', - 'bison', - 'Borghese', - 'bream', - 'breeches', - 'britches', - 'buffalo', - 'cantus', - 'carp', - 'chassis', - 'clippers', - 'cod', - 'coitus', - 'Congoese', - 'contretemps', - 'corps', - 'debris', - 'diabetes', - 'djinn', - 'eland', - 'elk', - 'equipment', - 'Faroese', - 'flounder', - 'Foochowese', - 'gallows', - 'Genevese', - 'Genoese', - 'Gilbertese', - 'graffiti', - 'headquarters', - 'herpes', - 'hijinks', - 'Hottentotese', - 'information', - 'innings', - 'jackanapes', - 'Kiplingese', - 'Kongoese', - 'Lucchese', - 'mackerel', - 'Maltese', - '.*?media', - 'mews', - 'moose', - 'mumps', - 'Nankingese', - 'news', - 'nexus', - 'Niasese', - 'Pekingese', - 'Piedmontese', - 'pincers', - 'Pistoiese', - 'pliers', - 'Portuguese', - 'proceedings', - 'rabies', - 'rice', - 'rhinoceros', - 'salmon', - 'Sarawakese', - 'scissors', - 'sea[- ]bass', - 'series', - 'Shavese', - 'shears', - 'siemens', - 'species', - 'swine', - 'testes', - 'trousers', - 'trout', - 'tuna', - 'Vermontese', - 'Wenchowese', - 'whiting', - 'wildebeest', - 'Yengeese' - ); - - /** - * @var array map of special chars and its translation - */ - protected static $transliteration = array( - '/ä|æ|ǽ/' => 'ae', - '/ö|œ/' => 'oe', - '/ü/' => 'ue', - '/Ä/' => 'Ae', - '/Ü/' => 'Ue', - '/Ö/' => 'Oe', - '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A', - '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a', - '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', - '/ç|ć|ĉ|ċ|č/' => 'c', - '/Ð|Ď|Đ/' => 'D', - '/ð|ď|đ/' => 'd', - '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E', - '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e', - '/Ĝ|Ğ|Ġ|Ģ/' => 'G', - '/ĝ|ğ|ġ|ģ/' => 'g', - '/Ĥ|Ħ/' => 'H', - '/ĥ|ħ/' => 'h', - '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I', - '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i', - '/Ĵ/' => 'J', - '/ĵ/' => 'j', - '/Ķ/' => 'K', - '/ķ/' => 'k', - '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L', - '/ĺ|ļ|ľ|ŀ|ł/' => 'l', - '/Ñ|Ń|Ņ|Ň/' => 'N', - '/ñ|ń|ņ|ň|ʼn/' => 'n', - '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O', - '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o', - '/Ŕ|Ŗ|Ř/' => 'R', - '/ŕ|ŗ|ř/' => 'r', - '/Ś|Ŝ|Ş|Ș|Š/' => 'S', - '/ś|ŝ|ş|ș|š|ſ/' => 's', - '/Ţ|Ț|Ť|Ŧ/' => 'T', - '/ţ|ț|ť|ŧ/' => 't', - '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U', - '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u', - '/Ý|Ÿ|Ŷ/' => 'Y', - '/ý|ÿ|ŷ/' => 'y', - '/Ŵ/' => 'W', - '/ŵ/' => 'w', - '/Ź|Ż|Ž/' => 'Z', - '/ź|ż|ž/' => 'z', - '/Æ|Ǽ/' => 'AE', - '/ß/' => 'ss', - '/IJ/' => 'IJ', - '/ij/' => 'ij', - '/Œ/' => 'OE', - '/ƒ/' => 'f' - ); - - /** - * Returns the plural of a $word - * - * @param string $word the word to pluralize - * @return string - */ - public static function pluralize($word) - { - $unInflected = ArrayHelper::merge(static::$plural['uninflected'], static::$uninflected); - $irregular = array_keys(static::$plural['irregular']); - - $unInflectedRegex = '(?:' . implode('|', $unInflected) . ')'; - $irregularRegex = '(?:' . implode('|', $irregular) . ')'; - - if (preg_match('/(.*)\\b(' . $irregularRegex . ')$/i', $word, $regs)) - return $regs[1] . substr($word, 0, 1) . substr(static::$plural['irregular'][strtolower($regs[2])], 1); - - if (preg_match('/^(' . $unInflectedRegex . ')$/i', $word, $regs)) - return $word; - - foreach (static::$plural['rules'] as $rule => $replacement) { - if (preg_match($rule, $word)) { - return preg_replace($rule, $replacement, $word); - } - } - return $word; - } - - /** - * Returns the singular of the $word - * - * @param string $word the english word to singularize - * @return string Singular noun. - */ - public static function singularize($word) - { - - $unInflected = ArrayHelper::merge(static::$singular['uninflected'], static::$uninflected); - - $irregular = array_merge( - static::$singular['irregular'], - array_flip(static::$plural['irregular']) - ); - - $unInflectedRegex = '(?:' . implode('|', $unInflected) . ')'; - $irregularRegex = '(?:' . implode('|', array_keys($irregular)) . ')'; - - - if (preg_match('/(.*)\\b(' . $irregularRegex . ')$/i', $word, $regs)) - return $regs[1] . substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1); - - - if (preg_match('/^(' . $unInflectedRegex . ')$/i', $word, $regs)) - return $word; - - - foreach (static::$singular['rules'] as $rule => $replacement) { - if (preg_match($rule, $word)) { - return preg_replace($rule, $replacement, $word); - } - } - return $word; - } - - /** - * Converts an underscored or CamelCase word into a English - * sentence. - * - * The titleize function converts text like "WelcomePage", - * "welcome_page" or "welcome page" to this "Welcome - * Page". - * If second parameter is set to 'first' it will only - * capitalize the first character of the title. - * - * @param string $word Word to format as tile - * @param string $uppercase If set to 'first' it will only uppercase the - * first character. Otherwise it will uppercase all - * the words in the title. - * @return string Text formatted as title - */ - public static function titleize($word, $uppercase = '') - { - $uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords'; - return $uppercase(static::humanize(static::underscore($word))); - } - - /** - * Returns given word as CamelCased - * - * Converts a word like "send_email" to "SendEmail". It - * will remove non alphanumeric character from the word, so - * "who's online" will be converted to "WhoSOnline" - * - * @see variablize - * @param string $word Word to convert to camel case - * @return string UpperCamelCasedWord - */ - public static function camelize($word) - { - return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word))); - } - - /** - * Converts a word "into_it_s_underscored_version" - * - * Convert any "CamelCased" or "ordinary Word" into an - * "underscored_word". - * - * This can be really useful for creating friendly URLs. - * - * @access public - * @static - * @param string $word Word to underscore - * @return string Underscored word - */ - public static function underscore($word) - { - return strtolower( - preg_replace( - '/[^A-Z^a-z^0-9]+/', - '_', - preg_replace( - '/([a-zd])([A-Z])/', - '1_2', - preg_replace('/([A-Z]+)([A-Z][a-z])/', '1_2', $word) - ) - ) - ); - } - - /** - * Returns a human-readable string from $word - * - * @param string $word the string to humanize - * @param bool $uppercase whether to set all words to uppercase or not - * @return string - */ - public static function humanize($word, $uppercase = false) - { - $word = str_replace('_', ' ', preg_replace('/_id$/', '', $word)); - return $uppercase ? ucwords($word) : ucfirst($word); - } - - /** - * Same as camelize but first char is in lowercase - * - * Converts a word like "send_email" to "sendEmail". It - * will remove non alphanumeric character from the word, so - * "who's online" will be converted to "whoSOnline" - * - * @param string $word to lowerCamelCase - * @return string - */ - public static function variablize($word) - { - $word = static::camelize($word); - return strtolower($word[0]) . substr($word, 1); - } - - /** - * Converts a class name to its table name (pluralized) - * naming conventions. For example, converts "Person" to "people" - * - * @param string $class_name the class name for getting related table_name - * @return string - */ - public static function tableize($class_name) - { - return static::pluralize(static::underscore($class_name)); - } - - /** - * Returns a string with all spaces converted to given replacement and - * non word characters removed. Maps special characters to ASCII using - * `Inflector::$transliteration`. - * - * @param string $string An arbitrary string to convert. - * @param string $replacement The replacement to use for spaces. - * @return string The converted string. - */ - public static function slug($string, $replacement = '-') - { - - $map = static::$transliteration + array( - '/[^\w\s]/' => ' ', - '/\\s+/' => $replacement, - '/(?<=[a-z])([A-Z])/' => $replacement . '\\1', - str_replace(':rep', preg_quote($replacement, '/'), '/^[:rep]+|[:rep]+$/') => '' - ); - return preg_replace(array_keys($map), array_values($map), $string); - } - - /** - * Converts a table name to its class name. For example, converts "people" to "Person" - * - * @param string $table_name - * @return string - */ - public static function classify($table_name) - { - return static::camelize(static::singularize($table_name)); - } - - /** - * Converts number to its ordinal English form. - * - * This method converts 13 to 13th, 2 to 2nd ... - * - * @param int $number the number to get its ordinal value - * @return string - */ - public static function ordinalize($number) - { - if (in_array(($number % 100), range(11, 13))) { - return $number . 'th'; - } else { - switch (($number % 10)) { - case 1: - return $number . 'st'; - break; - case 2: - return $number . 'nd'; - break; - case 3: - return $number . 'rd'; - default: - return $number . 'th'; - break; - } - } - } -} From 2551273356458c3b9a01caa4838373bac6bf8330 Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Mon, 20 May 2013 01:37:08 +0200 Subject: [PATCH 04/14] new proposed structure --- yii/bootstrap/Modal.php | 300 +++++++++++++++++++++++++++++++ yii/bootstrap/Widget.php | 132 ++++++++++++++ yii/bootstrap/enum/Enum.php | 26 --- yii/bootstrap/helpers/Alert.php | 19 -- yii/bootstrap/helpers/Assets.php | 19 -- yii/bootstrap/helpers/Button.php | 19 -- yii/bootstrap/helpers/Icon.php | 21 --- yii/bootstrap/helpers/Progress.php | 19 -- yii/bootstrap/helpers/base/Alert.php | 55 ------ yii/bootstrap/helpers/base/Assets.php | 78 --------- yii/bootstrap/helpers/base/Button.php | 85 --------- yii/bootstrap/helpers/base/Icon.php | 185 ------------------- yii/bootstrap/helpers/base/Progress.php | 19 -- yii/bootstrap/widgets/Modal.php | 302 -------------------------------- yii/bootstrap/widgets/base/Widget.php | 126 ------------- 15 files changed, 432 insertions(+), 973 deletions(-) create mode 100644 yii/bootstrap/Modal.php create mode 100644 yii/bootstrap/Widget.php delete mode 100644 yii/bootstrap/enum/Enum.php delete mode 100644 yii/bootstrap/helpers/Alert.php delete mode 100644 yii/bootstrap/helpers/Assets.php delete mode 100644 yii/bootstrap/helpers/Button.php delete mode 100644 yii/bootstrap/helpers/Icon.php delete mode 100644 yii/bootstrap/helpers/Progress.php delete mode 100644 yii/bootstrap/helpers/base/Alert.php delete mode 100644 yii/bootstrap/helpers/base/Assets.php delete mode 100644 yii/bootstrap/helpers/base/Button.php delete mode 100644 yii/bootstrap/helpers/base/Icon.php delete mode 100644 yii/bootstrap/helpers/base/Progress.php delete mode 100644 yii/bootstrap/widgets/Modal.php delete mode 100644 yii/bootstrap/widgets/base/Widget.php diff --git a/yii/bootstrap/Modal.php b/yii/bootstrap/Modal.php new file mode 100644 index 0000000..601525c --- /dev/null +++ b/yii/bootstrap/Modal.php @@ -0,0 +1,300 @@ +widget(Modal::className(), array( + * 'id' => 'myModal', + * 'header' => 'Modal Heading', + * 'content' => '

One fine body...

', + * 'footer' => '//modal/_footer', // we can also use view paths + * 'buttonOptions' => array( + * 'label' => 'Show Modal', + * 'class' => \yii\bootstrap\enum\Button::TYPE_DEFAULT + * ) + * )); + * ``` + * @see http://twitter.github.io/bootstrap/javascript.html#modals + * @author Antonio Ramirez + * @since 2.0 + */ +class Modal extends Widget +{ + /** + * @var array The additional HTML attributes of the button that will show the modal. If empty array, only + * the markup of the modal will be rendered on the page, so users can easily call the modal manually with their own + * scripts. The following special attributes are available: + *
    + *
  • label: string, the label of the button
  • + *
+ * + * For available options of the button trigger, see http://twitter.github.com/bootstrap/javascript.html#modals. + */ + public $buttonOptions = array(); + + /** + * @var boolean indicates whether the modal should use transitions. Defaults to 'true'. + */ + public $fade = true; + + /** + * @var bool $keyboard, closes the modal when escape key is pressed. + */ + public $keyboard = true; + + /** + * @var bool $show, shows the modal when initialized. + */ + public $show = false; + + /** + * @var mixed includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn't close + * the modal on click. + */ + public $backdrop = true; + + /** + * @var mixed the remote url. If a remote url is provided, content will be loaded via jQuery's load method and + * injected into the .modal-body of the modal. + */ + public $remote; + + /** + * @var string a javascript function that will be invoked immediately when the `show` instance method is called. + */ + public $onShow; + + /** + * @var string a javascript function that will be invoked when the modal has been made visible to the user + * (will wait for css transitions to complete). + */ + public $onShown; + + /** + * @var string a javascript function that will be invoked immediately when the hide instance method has been called. + */ + public $onHide; + + /** + * @var string a javascript function that will be invoked when the modal has finished being hidden from the user + * (will wait for css transitions to complete). + */ + public $onHidden; + + /** + * @var string[] the Javascript event handlers. + */ + protected $events = array(); + + /** + * @var array $pluginOptions the plugin options. + */ + protected $pluginOptions = array(); + + /** + * @var string + */ + public $closeText = '×'; + + /** + * @var string header content. Header can also be a path to a view file. + */ + public $header; + + /** + * @var string body of modal. Body can also be a path to a view file. + */ + public $content; + + /** + * @var string footer content. Content can also be a path to a view file. + */ + public $footer; + + /** + * Widget's init method + */ + public function init() + { + parent::init(); + + $this->name = 'modal'; + + $this->defaultOption('id', $this->getId()); + + $this->defaultOption('role', 'dialog'); + $this->defaultOption('tabindex', '-1'); + + $this->addOption('class', 'modal'); + $this->addOption('class', 'hide'); + + if ($this->fade) + $this->addOption('class', 'fade'); + + $this->initPluginOptions(); + $this->initPluginEvents(); + } + + /** + * Initialize plugin events if any + */ + public function initPluginEvents() + { + foreach (array('onShow', 'onShown', 'onHide', 'onHidden') as $event) { + if ($this->{$event} !== null) { + $modalEvent = strtolower(substr($event, 2)); + if ($this->{$event} instanceof JsExpression) + $this->events[$modalEvent] = $this->$event; + else + $this->events[$modalEvent] = new JsExpression($this->{$event}); + } + } + } + + /** + * Initialize plugin options. + * ***Important***: The display of the button overrides the initialization of the modal bootstrap widget. + */ + public function initPluginOptions() + { + if (null !== $this->remote) + $this->pluginOptions['remote'] = Html::url($this->remote); + + foreach (array('backdrop', 'keyboard', 'show') as $option) { + $this->pluginOptions[$option] = isset($this->pluginOptions[$option]) + ? $this->pluginOptions[$option] + : $this->{$option}; + } + } + + /** + * Widget's run method + */ + public function run() + { + $this->renderModal(); + $this->renderButton(); + $this->registerScript(); + } + + /** + * Renders the button that will open the modal if its options have been configured + */ + public function renderButton() + { + if (!empty($this->buttonOptions)) { + + $this->buttonOptions['data-toggle'] = isset($this->buttonOptions['data-toggle']) + ? $this->buttonOptions['data-toggle'] + : 'modal'; + + if ($this->remote !== null && !isset($this->buttonOptions['data-remote'])) + $this->buttonOptions['data-remote'] = Html::url($this->remote); + + $label = ArrayHelper::remove($this->buttonOptions, 'label', 'Button'); + $name = ArrayHelper::remove($this->buttonOptions, 'name'); + $value = ArrayHelper::remove($this->buttonOptions, 'value'); + + $attr = isset($this->buttonOptions['data-remote']) + ? 'data-target' + : 'href'; + + $this->buttonOptions[$attr] = isset($this->buttonOptions[$attr]) + ? $this->buttonOptions[$attr] + : '#' . ArrayHelper::getValue($this->options, 'id'); + + echo Html::button($label, $name, $value, $this->buttonOptions); + } + } + + /** + * Renders the modal markup + */ + public function renderModal() + { + echo Html::beginTag('div', $this->options); + + $this->renderModalHeader(); + $this->renderModalBody(); + $this->renderModalFooter(); + + echo Html::endTag('div'); + } + + /** + * Renders the header HTML markup of the modal + */ + public function renderModalHeader() + { + echo Html::beginTag('div', array('class'=>'modal-header')); + if ($this->closeText) + echo Html::button($this->closeText, null, null, array('data-dismiss' => 'modal', 'class'=>'close')); + echo $this->renderSection($this->header); + echo Html::endTag('div'); + } + + /** + * Renders the HTML markup for the body of the modal + */ + public function renderModalBody() + { + echo Html::beginTag('div', array('class'=>'modal-body')); + echo $this->renderSection($this->content); + echo Html::endTag('div'); + } + + /** + * Renders the HTML markup for the footer of the modal + */ + public function renderModalFooter() + { + + echo Html::beginTag('div', array('class'=>'modal-footer')); + echo $this->renderSection($this->footer); + echo Html::endTag('div'); + } + + /** + * Renders a section. If the section is a view file, the returned string will be the contents of the view file, + * otherwise, it will return the string in the $section variable. + * @param string $section + * @return string + */ + public function renderSection($section) + { + $viewFile = Yii::getAlias($section); + if (is_file($viewFile)) + return $this->view->renderFile($viewFile, array(), $this); + return $section; + } + + /** + * Registers client scripts + */ + public function registerScript() + { + $id = '#' . ArrayHelper::getValue($this->options, 'id'); + // do we render a button? If so, bootstrap will handle its behavior through its + // mark-up, otherwise, register the plugin. + if(empty($this->buttonOptions)) + $this->registerPlugin($id, $this->pluginOptions); + + // register events + $this->registerEvents($id, $this->events); + } + +} \ No newline at end of file diff --git a/yii/bootstrap/Widget.php b/yii/bootstrap/Widget.php new file mode 100644 index 0000000..2995afa --- /dev/null +++ b/yii/bootstrap/Widget.php @@ -0,0 +1,132 @@ + + * @since 2.0 + */ +class Widget extends \yii\base\Widget +{ + + /** + * @var bool whether to register the asset + */ + public static $responsive = true; + + /** + * @var array the HTML attributes for the widget container tag. + */ + public $options = array(); + + /** + * @var string the widget name (ie. modal, typeahead, tab) + */ + protected $name; + + /** + * Initializes the widget. + */ + public function init() + { + // ensure bundle + $this->registerBundle(static::$responsive); + } + + /** + * Registers plugin events with the API. + * @param string $selector the CSS selector. + * @param string[] $events the JavaScript event configuration (name=>handler). + * @param int $position the position of the JavaScript code. + * @return boolean whether the events were registered. + * @todo To be discussed + */ + protected function registerEvents($selector, $events = array(), $position = View::POS_END) + { + if (empty($events)) + return; + + $script = ''; + foreach ($events as $name => $handler) { + $handler = ($handler instanceof JsExpression) + ? $handler + : new JsExpression($handler); + + $script .= ";jQuery(document).ready(function (){jQuery('{$selector}').on('{$name}', {$handler});});"; + } + if (!empty($script)) + $this->view->registerJs($script, array('position' => $position)); + } + + /** + * Registers a specific Bootstrap plugin using the given selector and options. + * + * @param string $selector the CSS selector + * @param array $options the Javascript options for the plugin + * @param int $position the position of the JavaScript code + */ + public function registerPlugin($selector, $options = array(), $position = View::POS_END) + { + $options = !empty($options) ? Json::encode($options) : ''; + $script = ";jQuery(document).ready(function (){jQuery('{$selector}').{$this->name}({$options});});"; + $this->view->registerJs($script, array('position' => $position)); + } + + /** + * Registers bootstrap bundle + * @param bool $responsive + */ + public function registerBundle($responsive = false) + { + $bundle = $responsive ? 'yii/bootstrap' : 'yii/bootstrap-responsive'; + + $this->view->registerAssetBundle($bundle); + } + + + /** + * Adds a new option. If the key does not exists, it will create one, if it exists it will append the value + * and also makes sure the uniqueness of them. + * + * @param string $key + * @param mixed $value + * @param string $glue + * @return array + */ + protected function addOption($key, $value, $glue = ' ') + { + if (isset($this->options[$key])) { + if (!is_array($this->options[$key])) + $this->options[$key] = explode($glue, $this->options[$key]); + $this->options[$key][] = $value; + $this->options[$key] = array_unique($this->options[$key]); + $this->options[$key] = implode($glue, $this->options[$key]); + } else + $this->options[$key] = $value; + return $this->options; + } + + /** + * Sets the default value for an item if not set. + * @param string $key the name of the item. + * @param mixed $value the default value. + * @return array + */ + protected function defaultOption($key, $value) + { + if (!isset($this->options[$key])) + $this->options[$key] = $value; + return $this->options; + } +} \ No newline at end of file diff --git a/yii/bootstrap/enum/Enum.php b/yii/bootstrap/enum/Enum.php deleted file mode 100644 index e11cbb4..0000000 --- a/yii/bootstrap/enum/Enum.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - */ -class Enum -{ - const FADE = 'fade'; - const IN = 'in'; - const CLOSE = 'close'; - const DISABLED = 'disabled'; - const ACTIVE = 'active'; - const MODAL = 'modal'; - const HIDE = 'hide'; - const DIALOG = 'dialog'; - const ALERT = 'alert'; -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Alert.php b/yii/bootstrap/helpers/Alert.php deleted file mode 100644 index 58139bd..0000000 --- a/yii/bootstrap/helpers/Alert.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @since 2.0 - */ -class Alert extends base\Alert -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Assets.php b/yii/bootstrap/helpers/Assets.php deleted file mode 100644 index e03b04f..0000000 --- a/yii/bootstrap/helpers/Assets.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @since 2.0 - */ -class Assets extends base\Assets -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Button.php b/yii/bootstrap/helpers/Button.php deleted file mode 100644 index 1448838..0000000 --- a/yii/bootstrap/helpers/Button.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @since 2.0 - */ -class Button extends base\Button -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Icon.php b/yii/bootstrap/helpers/Icon.php deleted file mode 100644 index 1be2660..0000000 --- a/yii/bootstrap/helpers/Icon.php +++ /dev/null @@ -1,21 +0,0 @@ - - * @since 2.0 - */ -class Icon extends base\Icon -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/Progress.php b/yii/bootstrap/helpers/Progress.php deleted file mode 100644 index 4e5bc7f..0000000 --- a/yii/bootstrap/helpers/Progress.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @since 2.0 - */ -class Progress extends base\Progress -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Alert.php b/yii/bootstrap/helpers/base/Alert.php deleted file mode 100644 index 23899d6..0000000 --- a/yii/bootstrap/helpers/base/Alert.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @since 2.0 - */ -class Alert -{ - - /** - * constants - */ - const CLASS_NAME = 'alert'; - const TYPE_DEFAULT = ''; - const TYPE_SUCCESS = 'alert-success'; - const TYPE_INFORMATION = 'alert-info'; - const TYPE_ERROR = 'alert-error'; - const SIZE_BLOCK = 'alert-block'; - - /** - * Generates an alert box - * @param $message - * @param array $htmlOptions - * @param bool $dismiss whether to display dismissal link or not - * @return string - */ - public static function create($message, $htmlOptions = array(), $dismiss = true) - { - // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? - if (isset($htmlOptions['class'])) - $htmlOptions['class'] .= ' ' . static::CLASS_NAME; - else - $htmlOptions['class'] = static::CLASS_NAME; - - ob_start(); - echo Html::beginTag('div', $htmlOptions); - if ($dismiss) - echo Button::closeLink('×', Enum::ALERT); - echo $message; - echo Html::endTag('div'); - return ob_get_clean(); - } -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Assets.php b/yii/bootstrap/helpers/base/Assets.php deleted file mode 100644 index 3f7f7e6..0000000 --- a/yii/bootstrap/helpers/base/Assets.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @since 2.0 - */ -class Assets -{ - public static function registerBundle($responsive = false) - { - $bundle = $responsive ? 'yii/bootstrap' : 'yii/bootstrap-responsive'; - - Yii::$app->getView()->registerAssetBundle($bundle); - } - - /** - * Registers plugin events with the API. - * - * @param string $selector the CSS selector. - * @param string[] $events the JavaScript event configuration (name=>handler). - * @param int $position the position of the JavaScript code. - * @return boolean whether the events were registered. - */ - public static function registerEvents($selector, $events = array(), $position = View::POS_END) - { - if (empty($events)) - return; - - $script = ''; - foreach ($events as $name => $handler) { - $handler = ($handler instanceof JsExpression) - ? $handler - : new JsExpression($handler); - - $script .= ";jQuery(document).ready(function (){jQuery('{$selector}').on('{$name}', {$handler});});"; - } - if (!empty($script)) - Yii::$app->getView()>registerJs($script, array('position' => $position), static::getUniqueScriptId()); - } - - /** - * Registers a specific Bootstrap plugin using the given selector and options. - * - * @param string $selector the CSS selector. - * @param string $name the name of the plugin - * @param array $options the JavaScript options for the plugin. - * @param int $position the position of the JavaScript code. - */ - public static function registerPlugin($selector, $name, $options = array(), $position = View::POS_END) - { - $options = !empty($options) ? Json::encode($options) : ''; - $script = ";jQuery(document).ready(function (){jQuery('{$selector}').{$name}({$options});});"; - Yii::$app->getView()->registerJs($script, array('position'=>$position)); - } - - /** - * Generates a "somewhat" random id string. - * @return string the id. - */ - public static function getUniqueScriptId() - { - return uniqid(time() . '#', true); - } -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Button.php b/yii/bootstrap/helpers/base/Button.php deleted file mode 100644 index c0ea329..0000000 --- a/yii/bootstrap/helpers/base/Button.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @since 2.0 - */ -class Button -{ - /** - * constants - */ - const TYPE_DEFAULT = 'btn'; - const TYPE_PRIMARY = 'btn-primary'; - const TYPE_INFO = 'btn-info'; - const TYPE_SUCCESS = 'btn-success'; - const TYPE_WARNING = 'btn-warning'; - const TYPE_DANGER = 'btn-danger'; - const TYPE_INVERSE = 'btn-inverse'; - const TYPE_LINK = 'btn-link'; - - const SIZE_DEFAULT = ''; - const SIZE_LARGE = 'btn-large'; - const SIZE_SMALL = 'btn-small'; - const SIZE_MINI = 'btn-mini'; - const SIZE_BLOCK = 'btn-block'; - - /** - * Returns a dismissal alert link - * @param string $text - * @param string $dismiss what to dismiss (alert or modal) - * @return string the dismissal alert link - */ - public static function closeLink($text = '×', $dismiss = null) - { - $options = array('class' => Enum::CLOSE); - if(null !== $dismiss) - $options['data-dismiss'] = $dismiss; - return Html::a($text, '#', $options); - } - - /** - * Returns a dismissal button - * @param string $text the text to use for the close button - * @param string $dismiss what to dismiss (alert or modal) - * @return string the dismissal button - */ - public static function closeButton($text = '×', $dismiss = null) - { - $options = array('type' => 'button', 'class' => Enum::CLOSE); - if(null !== $dismiss) - $options['data-dismiss'] = $dismiss; - - return Html::button($text, null, null, $options); - } - - - /** - * Returns a link button - * @param string $label the button label - * @param array $htmlOptions the HTML attributes of the button - * @return string the generated button - */ - public static function link($label, $htmlOptions = array()) - { - // TODO: consider method add or append to ArrayHelper class - if (isset($htmlOptions['class'])) - $htmlOptions['class'] .= ' ' . static::TYPE_LINK; - else - $htmlOptions['class'] = static::TYPE_LINK; - - return Html::a($label, '#', $htmlOptions); - } -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Icon.php b/yii/bootstrap/helpers/base/Icon.php deleted file mode 100644 index a11d7e6..0000000 --- a/yii/bootstrap/helpers/base/Icon.php +++ /dev/null @@ -1,185 +0,0 @@ - - * @since 2.0 - */ -class Icon -{ - /** - * constants - */ - const ICON_GLASS = 'icon-glass'; - const ICON_MUSIC = 'icon-music'; - const ICON_SEARCH = 'icon-search'; - const ICON_ENVELOPE = 'icon-envelope'; - const ICON_HEART = 'icon-heart'; - const ICON_STAR = 'icon-star'; - const ICON_STAR_EMPTY = 'icon-star-empty'; - const ICON_USER = 'icon-user'; - const ICON_FILM = 'icon-film'; - const ICON_TH_LARGE = 'icon-th-large'; - const ICON_TH = 'icon-th'; - const ICON_TH_LIST = 'icon-th-list'; - const ICON_OK = 'icon-ok'; - const ICON_REMOVE = 'icon-remove'; - const ICON_ZOOM_IN = 'icon-zoom-in'; - const ICON_ZOOM_OUT = 'icon-zoom-out'; - const ICON_OFF = 'icon-off'; - const ICON_SIGNAL = 'icon-signal'; - const ICON_COG = 'icon-cog'; - const ICON_TRASH = 'icon-trash'; - const ICON_HOME = 'icon-home'; - const ICON_FILE = 'icon-file'; - const ICON_TIME = 'icon-time'; - const ICON_ROAD = 'icon-road'; - const ICON_DOWNLOAD_ALT = 'icon-download-alt'; - const ICON_DOWNLOAD = 'icon-download'; - const ICON_UPLOAD = 'icon-upload'; - const ICON_INBOX = 'icon-inbox'; - const ICON_PLAY_CIRCLE = 'icon-play-circle'; - const ICON_REPEAT = 'icon-repeat'; - const ICON_REFRESH = 'icon-refresh'; - const ICON_LIST_ALT = 'icon-list-alt'; - const ICON_LOCK = 'icon-lock'; - const ICON_FLAG = 'icon-flag'; - const ICON_HEADPHONES = 'icon-headphones'; - const ICON_VOLUME_OFF = 'icon-volume-off'; - const ICON_VOLUME_DOWN = 'icon-volume-down'; - const ICON_VOLUME_UP = 'icon-volume-up'; - const ICON_QRCODE = 'icon-qrcode'; - const ICON_BARCODE = 'icon-barcode'; - const ICON_TAG = 'icon-tag'; - const ICON_TAGS = 'icon-tags'; - const ICON_BOOK = 'icon-book'; - const ICON_BOOKMARK = 'icon-bookmark'; - const ICON_PRINT = 'icon-print'; - const ICON_CAMERA = 'icon-camera'; - const ICON_FONT = 'icon-font'; - const ICON_BOLD = 'icon-bold'; - const ICON_ITALIC = 'icon-italic'; - const ICON_TEXT_HEIGHT = 'icon-text-height'; - const ICON_TEXT_WIDTH = 'icon-text-width'; - const ICON_ALIGN_LEFT = 'icon-align-left'; - const ICON_ALIGN_CENTER = 'icon-align-center'; - const ICON_ALIGN_RIGHT = 'icon-align-right'; - const ICON_ALIGN_JUSTIFY = 'icon-align-justify'; - const ICON_LIST = 'icon-list'; - const ICON_INDENT_LEFT = 'icon-indent-left'; - const ICON_INDENT_RIGHT = 'icon-indent-right'; - const ICON_FACETIME_VIDEO = 'icon-facetime-video'; - const ICON_PICTURE = 'icon-picture'; - const ICON_PENCIL = 'icon-pencil'; - const ICON_MAP_MARKER = 'icon-map-marker'; - const ICON_ADJUST = 'icon-adjust'; - const ICON_TINT = 'icon-tint'; - const ICON_EDIT = 'icon-edit'; - const ICON_SHARE = 'icon-share'; - const ICON_CHECK = 'icon-check'; - const ICON_MOVE = 'icon-move'; - const ICON_STEP_BACKWARD = 'icon-step-backward'; - const ICON_FAST_BACKWARD = 'icon-fast-backward'; - const ICON_BACKWARD = 'icon-backward'; - const ICON_PLAY = 'icon-play'; - const ICON_PAUSE = 'icon-pause'; - const ICON_STOP = 'icon-pause'; - const ICON_FORWARD = 'icon-forward'; - const ICON_FAST_FORWARD = 'icon-fast-forward'; - const ICON_STEP_FORWARD = 'icon-step-forward'; - const ICON_EJECT = 'icon-eject'; - const ICON_CHEVRON_LEFT = 'icon-chevron-left'; - const ICON_CHEVRON_RIGHT = 'icon-chevron-right'; - const ICON_PLUS_SIGN = 'icon-plus-sign'; - const ICON_MINUS_SIGN = 'icon-minus-sign'; - const ICON_REMOVE_SIGN = 'icon-remove-sign'; - const ICON_OK_SIGN = 'icon-ok-sign'; - const ICON_QUESTION_SIGN = 'icon-question-sign'; - const ICON_INFO_SIGN = 'icon-info-sign'; - const ICON_SCREENSHOT = 'icon-screenshot'; - const ICON_REMOVE_CIRCLE = 'icon-remove-circle'; - const ICON_OK_CIRCLE = 'icon-ok-circle'; - const ICON_BAN_CIRCLE = 'icon-ban-circle'; - const ICON_ARROW_LEFT = 'icon-arrow-left'; - const ICON_ARROW_RIGHT = 'icon-arrow-right'; - const ICON_ARROW_UP = 'icon-arrow-up'; - const ICON_ARROW_DOWN = 'icon-arrow-down'; - const ICON_SHARE_ALT = 'icon-share-alt'; - const ICON_RESIZE_FULL = 'icon-resize-full'; - const ICON_RESIZE_SMALL = 'icon-resize-small'; - const ICON_PLUS = 'icon-plus'; - const ICON_MINUS = 'icon-minus'; - const ICON_ASTERISK = 'icon-asterisk'; - const ICON_EXCLAMATION_SIGN = 'icon-exclamation-sign'; - const ICON_GIFT = 'icon-gift'; - const ICON_LEAF = 'icon-leaf'; - const ICON_FIRE = 'icon-fire'; - const ICON_EYE_OPEN = 'icon-eye-open'; - const ICON_EYE_CLOSE = 'icon-eye-close'; - const ICON_WARNING_SIGN = 'icon-warning-sign'; - const ICON_PLANE = 'icon-plane'; - const ICON_CALENDAR = 'icon-calendar'; - const ICON_RANDOM = 'icon-random'; - const ICON_COMMENT = 'icon-comment'; - const ICON_MAGNET = 'icon-magnet'; - const ICON_CHEVRON_UP = 'icon-chevron-up'; - const ICON_CHEVRON_DOWN = 'icon-chevron-down'; - const ICON_RETWEET = 'icon-retweet'; - const ICON_SHOPPING_CART = 'icon-shopping-cart'; - const ICON_FOLDER_CLOSE = 'icon-folder-close'; - const ICON_FOLDER_OPEN = 'icon-folder-open'; - const ICON_RESIZE_VERTICAL = 'icon-resize-vertical'; - const ICON_RESIZE_HORIZONTAL = 'icon-resize-horizontal'; - const ICON_HDD = 'icon-hdd'; - const ICON_BULLHORN = 'icon-bullhorn'; - const ICON_BELL = 'icon-bell'; - const ICON_CERTFICATE = 'icon-certificate'; - const ICON_THUMBS_UP = 'icon-thumbs-up'; - const ICON_THUMBS_DOWN = 'icon-thumbs-down'; - const ICON_HAND_RIGHT = 'icon-hand-right'; - const ICON_HAND_LEFT = 'icon-hand-left'; - const ICON_HAND_UP = 'icon-hand-up'; - const ICON_HAND_DOWN = 'icon-hand-down'; - const ICON_CIRCLE_ARROW_RIGHT = 'icon-circle-arrow-right'; - const ICON_CIRCLE_ARROW_LEFT = 'icon-circle-arrow-left'; - const ICON_CIRCLE_ARROW_UP = 'icon-circle-arrow-up'; - const ICON_CIRCLE_ARROW_DOWN = 'icon-circle-arrow-down'; - const ICON_GLOBE = 'icon-globe'; - const ICON_WRENCH = 'icon-wrench'; - const ICON_TASKS = 'icon-tasks'; - const ICON_FILTER = 'icon-filter'; - const ICON_BRIEFCASE = 'icon-briefcase'; - const ICON_FULLSCREEN = 'icon-fullscreen'; - - /** - * Generates an icon. - * @param string $icon the icon type. - * @param array $htmlOptions additional HTML attributes. - * @return string the generated icon. - */ - public static function i($icon, $htmlOptions = array()) - { - if (is_string($icon)) - { - if (strpos($icon, 'icon-') === false) - $icon = 'icon-' . implode(' icon-', explode(' ', $icon)); - - // TODO: this method may should be added to ArrayHelper::add or ArrayHelper::append? - if (isset($htmlOptions['class'])) - $htmlOptions['class'] .= ' ' . $icon; - else - $htmlOptions['class'] = $icon; - - return Html::tag('i', '', $htmlOptions); - } - return ''; - } -} \ No newline at end of file diff --git a/yii/bootstrap/helpers/base/Progress.php b/yii/bootstrap/helpers/base/Progress.php deleted file mode 100644 index 8006f66..0000000 --- a/yii/bootstrap/helpers/base/Progress.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @since 2.0 - */ -class Progress -{ - -} \ No newline at end of file diff --git a/yii/bootstrap/widgets/Modal.php b/yii/bootstrap/widgets/Modal.php deleted file mode 100644 index 15e874b..0000000 --- a/yii/bootstrap/widgets/Modal.php +++ /dev/null @@ -1,302 +0,0 @@ -widget(Modal::className(), array( - * 'id' => 'myModal', - * 'header' => 'Modal Heading', - * 'content' => '

One fine body...

', - * 'footer' => '//modal/_footer', // we can also use view paths - * 'buttonOptions' => array( - * 'label' => 'Show Modal', - * 'class' => \yii\bootstrap\enum\Button::TYPE_DEFAULT - * ) - * )); - * ``` - * @see http://twitter.github.io/bootstrap/javascript.html#modals - * @author Antonio Ramirez - * @since 2.0 - */ -class Modal extends base\Widget -{ - /** - * @var array The additional HTML attributes of the button that will show the modal. If empty array, only - * the markup of the modal will be rendered on the page, so users can easily call the modal manually with their own - * scripts. The following special attributes are available: - *
    - *
  • label: string, the label of the button
  • - *
- * - * For available options of the button trigger, see http://twitter.github.com/bootstrap/javascript.html#modals. - */ - public $buttonOptions = array(); - - /** - * @var boolean indicates whether the modal should use transitions. Defaults to 'true'. - */ - public $fade = true; - - /** - * @var bool $keyboard, closes the modal when escape key is pressed. - */ - public $keyboard = true; - - /** - * @var bool $show, shows the modal when initialized. - */ - public $show = false; - - /** - * @var mixed includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn't close - * the modal on click. - */ - public $backdrop = true; - - /** - * @var mixed the remote url. If a remote url is provided, content will be loaded via jQuery's load method and - * injected into the .modal-body of the modal. - */ - public $remote; - - /** - * @var string a javascript function that will be invoked immediately when the `show` instance method is called. - */ - public $onShow; - - /** - * @var string a javascript function that will be invoked when the modal has been made visible to the user - * (will wait for css transitions to complete). - */ - public $onShown; - - /** - * @var string a javascript function that will be invoked immediately when the hide instance method has been called. - */ - public $onHide; - - /** - * @var string a javascript function that will be invoked when the modal has finished being hidden from the user - * (will wait for css transitions to complete). - */ - public $onHidden; - - /** - * @var string[] the Javascript event handlers. - */ - protected $events = array(); - - /** - * @var array $pluginOptions the plugin options. - */ - protected $pluginOptions = array(); - - /** - * @var string - */ - public $closeText = '×'; - - /** - * @var string header content. Header can also be a path to a view file. - */ - public $header; - - /** - * @var string body of modal. Body can also be a path to a view file. - */ - public $content; - - /** - * @var string footer content. Content can also be a path to a view file. - */ - public $footer; - - /** - * Widget's init method - */ - public function init() - { - parent::init(); - - $this->name = 'modal'; - - $this->defaultOption('id', $this->getId()); - $this->selector = '#' . ArrayHelper::getValue($this->options, 'id'); - - $this->defaultOption('role', Enum::DIALOG); - $this->defaultOption('tabindex', '-1'); - - $this->addOption('class', Enum::MODAL); - $this->addOption('class', Enum::HIDE); - - if ($this->fade) - $this->addOption('class', Enum::FADE); - - $this->initPluginOptions(); - $this->initPluginEvents(); - } - - /** - * Initialize plugin events if any - */ - public function initPluginEvents() - { - foreach (array('onShow', 'onShown', 'onHide', 'onHidden') as $event) { - if ($this->{$event} !== null) { - $modalEvent = strtolower(substr($event, 2)); - if ($this->{$event} instanceof JsExpression) - $this->events[$modalEvent] = $this->$event; - else - $this->events[$modalEvent] = new JsExpression($this->{$event}); - } - } - } - - /** - * Initialize plugin options. - * ***Important***: The display of the button overrides the initialization of the modal bootstrap widget. - */ - public function initPluginOptions() - { - if (null !== $this->remote) - $this->pluginOptions['remote'] = Html::url($this->remote); - - foreach (array('backdrop', 'keyboard', 'show') as $option) { - $this->pluginOptions[$option] = isset($this->pluginOptions[$option]) - ? $this->pluginOptions[$option] - : $this->{$option}; - } - } - - /** - * Widget's run method - */ - public function run() - { - $this->renderModal(); - $this->renderButton(); - $this->registerScript(); - } - - /** - * Renders the button that will open the modal if its options have been configured - */ - public function renderButton() - { - if (!empty($this->buttonOptions)) { - - $this->buttonOptions['data-toggle'] = isset($this->buttonOptions['data-toggle']) - ? $this->buttonOptions['data-toggle'] - : Enum::MODAL; - - if ($this->remote !== null && !isset($this->buttonOptions['data-remote'])) - $this->buttonOptions['data-remote'] = Html::url($this->remote); - - $label = ArrayHelper::remove($this->buttonOptions, 'label', 'Button'); - $name = ArrayHelper::remove($this->buttonOptions, 'name'); - $value = ArrayHelper::remove($this->buttonOptions, 'value'); - - $attr = isset($this->buttonOptions['data-remote']) - ? 'data-target' - : 'href'; - - $this->buttonOptions[$attr] = isset($this->buttonOptions[$attr]) - ? $this->buttonOptions[$attr] - : $this->selector; - - echo Html::button($label, $name, $value, $this->buttonOptions); - } - } - - /** - * Renders the modal markup - */ - public function renderModal() - { - echo Html::beginTag('div', $this->options); - - $this->renderModalHeader(); - $this->renderModalBody(); - $this->renderModalFooter(); - - echo Html::endTag('div'); - } - - /** - * Renders the header HTML markup of the modal - */ - public function renderModalHeader() - { - echo Html::beginTag('div', array('class'=>'modal-header')); - if ($this->closeText) - echo Button::closeButton($this->closeText, Enum::MODAL); - echo $this->renderSection($this->header); - echo Html::endTag('div'); - } - - /** - * Renders the HTML markup for the body of the modal - */ - public function renderModalBody() - { - echo Html::beginTag('div', array('class'=>'modal-body')); - echo $this->renderSection($this->content); - echo Html::endTag('div'); - } - - /** - * Renders the HTML markup for the footer of the modal - */ - public function renderModalFooter() - { - - echo Html::beginTag('div', array('class'=>'modal-footer')); - echo $this->renderSection($this->footer); - echo Html::endTag('div'); - } - - /** - * Renders a section. If the section is a view file, the returned string will be the contents of the view file, - * otherwise, it will return the string in the $section variable. - * @param string $section - * @return string - */ - public function renderSection($section) - { - $viewFile = Yii::getAlias($section); - if (is_file($viewFile)) - return $this->view->renderFile($viewFile, array(), $this); - return $section; - } - - /** - * Registers client scripts - */ - public function registerScript() - { - // do we render a button? If so, bootstrap will handle its behavior through its - // mark-up, otherwise, register the plugin. - if(empty($this->buttonOptions)) - $this->registerPlugin($this->selector, $this->pluginOptions); - - // register events - $this->registerEvents($this->selector, $this->events); - } - -} \ No newline at end of file diff --git a/yii/bootstrap/widgets/base/Widget.php b/yii/bootstrap/widgets/base/Widget.php deleted file mode 100644 index 822f761..0000000 --- a/yii/bootstrap/widgets/base/Widget.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @since 2.0 - */ -class Widget extends \yii\base\Widget -{ - - /** - * @var bool whether to register the asset - */ - public $responsive = true; - - /** - * @var array the HTML attributes for the widget container tag. - */ - public $options = array(); - - /** - * @var string the widget name - */ - protected $name; - - /** - * @var string the jQuery selector of the widget - */ - protected $selector; - - /** - * Initializes the widget. - */ - public function init() - { - // ensure bundle - Assets::registerBundle($this->responsive); - } - - /** - * Registers plugin events with the API. - * @param string $selector the CSS selector. - * @param string[] $events the JavaScript event configuration (name=>handler). - * @param int $position the position of the JavaScript code. - * @return boolean whether the events were registered. - */ - protected function registerEvents($selector, $events = array(), $position = View::POS_END) - { - Assets::registerEvents($selector, $events, $position); - } - - /** - * Registers a specific Bootstrap plugin using the given selector and options. - * @param string $selector the CSS selector. - * @param array $options the JavaScript options for the plugin. - * @param int $position the position of the JavaScript code. - * @throws \yii\base\InvalidCallException - */ - public function registerPlugin($selector, $options = array(), $position = View::POS_END) - { - if(null === $this->name) - throw new InvalidCallException(); - - Assets::registerPlugin($selector, $this->name, $options, $position); - } - - /** - * Generates a "somewhat" random id string. - * @return string the id. - * @todo not sure it should be here or - */ - protected function getUniqueScriptId() - { - return uniqid(time() . '#', true); - } - - /** - * Adds a new option. If the key does not exists, it will create one, if it exists it will append the value - * and also makes sure the uniqueness of them. - * - * @param string $key - * @param mixed $value - * @param string $glue - * @return array - */ - protected function addOption($key, $value, $glue = ' ') - { - if (isset($this->options[$key])) { - if (!is_array($this->options[$key])) - $this->options[$key] = explode($glue, $this->options[$key]); - $this->options[$key][] = $value; - $this->options[$key] = array_unique($this->options[$key]); - $this->options[$key] = implode($glue, $this->options[$key]); - } else - $this->options[$key] = $value; - return $this->options; - } - - /** - * Sets the default value for an item if not set. - * @param string $key the name of the item. - * @param mixed $value the default value. - * @return array - */ - protected function defaultOption($key, $value) - { - if (!isset($this->options[$key])) - $this->options[$key] = $value; - return $this->options; - } -} \ No newline at end of file From 0d41a25eb401864b4d4f9c5d151b84a620599580 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 19 May 2013 20:37:10 -0400 Subject: [PATCH 05/14] Added support for View::POS_READY. --- yii/base/View.php | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/yii/base/View.php b/yii/base/View.php index a00b22c..04eaacc 100644 --- a/yii/base/View.php +++ b/yii/base/View.php @@ -58,6 +58,11 @@ class View extends Component */ const POS_END = 3; /** + * The location of registered JavaScript code block. + * This means the JavaScript code block will be enclosed within `jQuery(document).ready()`. + */ + const POS_READY = 4; + /** * This is internally used as the placeholder for receiving the content registered for the head section. */ const PL_HEAD = ''; @@ -630,24 +635,26 @@ class View extends Component /** * Registers a JS code block. * @param string $js the JS code block to be registered - * @param array $options the HTML attributes for the script tag. A special option - * named "position" is supported which specifies where the JS script tag should be inserted - * in a page. The possible values of "position" are: + * @param integer $position the position at which the JS script tag should be inserted + * in a page. The possible values are: * * - [[POS_HEAD]]: in the head section * - [[POS_BEGIN]]: at the beginning of the body section * - [[POS_END]]: at the end of the body section + * - [[POS_READY]]: enclosed within jQuery(document).ready(). This is the default value. + * Note that by using this position, the method will automatically register the jquery js file. * * @param string $key the key that identifies the JS code block. If null, it will use * $js as the key. If two JS code blocks are registered with the same key, the latter * will overwrite the former. */ - public function registerJs($js, $options = array(), $key = null) + public function registerJs($js, $position = self::POS_READY, $key = null) { - $position = isset($options['position']) ? $options['position'] : self::POS_END; - unset($options['position']); $key = $key ?: $js; - $this->js[$position][$key] = Html::script($js, $options); + $this->js[$position][$key] = $js; + if ($position === self::POS_READY) { + $this->registerAssetBundle('yii/jquery'); + } } /** @@ -659,7 +666,7 @@ class View extends Component * * - [[POS_HEAD]]: in the head section * - [[POS_BEGIN]]: at the beginning of the body section - * - [[POS_END]]: at the end of the body section + * - [[POS_END]]: at the end of the body section. This is the default value. * * @param string $key the key that identifies the JS script file. If null, it will use * $url as the key. If two JS files are registered with the same key, the latter @@ -697,7 +704,7 @@ class View extends Component $lines[] = implode("\n", $this->jsFiles[self::POS_HEAD]); } if (!empty($this->js[self::POS_HEAD])) { - $lines[] = implode("\n", $this->js[self::POS_HEAD]); + $lines[] = Html::script(implode("\n", $this->js[self::POS_HEAD]), array('type' => 'text/javascript')); } return empty($lines) ? '' : implode("\n", $lines) . "\n"; } @@ -714,7 +721,7 @@ class View extends Component $lines[] = implode("\n", $this->jsFiles[self::POS_BEGIN]); } if (!empty($this->js[self::POS_BEGIN])) { - $lines[] = implode("\n", $this->js[self::POS_BEGIN]); + $lines[] = Html::script(implode("\n", $this->js[self::POS_BEGIN]), array('type' => 'text/javascript')); } return empty($lines) ? '' : implode("\n", $lines) . "\n"; } @@ -731,7 +738,11 @@ class View extends Component $lines[] = implode("\n", $this->jsFiles[self::POS_END]); } if (!empty($this->js[self::POS_END])) { - $lines[] = implode("\n", $this->js[self::POS_END]); + $lines[] = Html::script(implode("\n", $this->js[self::POS_END]), array('type' => 'text/javascript')); + } + if (!empty($this->js[self::POS_READY])) { + $js = "jQuery(document).ready(function(){\n{" . implode("\n", $this->js[self::POS_READY]) . "}\n});"; + $lines[] = Html::script($js, array('type' => 'text/javascript')); } return empty($lines) ? '' : implode("\n", $lines) . "\n"; } From f3d23ec0e97b67c48b0857f293ca123d7437a028 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 19 May 2013 21:22:12 -0400 Subject: [PATCH 06/14] Fixed framework path. --- apps/bootstrap/yii | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) mode change 100644 => 100755 apps/bootstrap/yii diff --git a/apps/bootstrap/yii b/apps/bootstrap/yii old mode 100644 new mode 100755 index cee771a..fa8db10 --- a/apps/bootstrap/yii +++ b/apps/bootstrap/yii @@ -13,9 +13,8 @@ defined('YII_DEBUG') or define('YII_DEBUG', true); // fcgi doesn't have STDIN defined by default defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); -$frameworkPath = __DIR__ . '/../../yii'; - -require($frameworkPath . '/Yii.php'); +require(__DIR__ . '/vendor/yiisoft/yii2/yii.php'); +require(__DIR__ . '/vendor/autoload.php'); $config = require(__DIR__ . '/config/console.php'); From 520e5b954ad85d326fd196c946213334bffab52c Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Mon, 20 May 2013 08:19:22 +0200 Subject: [PATCH 07/14] refactored code after feedback --- yii/bootstrap/Modal.php | 36 +++++++++++------------------------ yii/bootstrap/Widget.php | 49 ++++++++++++++++++++---------------------------- 2 files changed, 31 insertions(+), 54 deletions(-) diff --git a/yii/bootstrap/Modal.php b/yii/bootstrap/Modal.php index 601525c..5e287c5 100644 --- a/yii/bootstrap/Modal.php +++ b/yii/bootstrap/Modal.php @@ -21,10 +21,11 @@ use yii\helpers\ArrayHelper; * 'id' => 'myModal', * 'header' => 'Modal Heading', * 'content' => '

One fine body...

', - * 'footer' => '//modal/_footer', // we can also use view paths + * 'footer' => 'Modal Footer', + * // if we wish to display a modal button * 'buttonOptions' => array( * 'label' => 'Show Modal', - * 'class' => \yii\bootstrap\enum\Button::TYPE_DEFAULT + * 'class' => 'btn btn-primary' * ) * )); * ``` @@ -139,11 +140,11 @@ class Modal extends Widget $this->defaultOption('role', 'dialog'); $this->defaultOption('tabindex', '-1'); - $this->addOption('class', 'modal'); - $this->addOption('class', 'hide'); + $this->addClassName('modal'); + $this->addClassName('hide'); if ($this->fade) - $this->addOption('class', 'fade'); + $this->addClassName('fade'); $this->initPluginOptions(); $this->initPluginEvents(); @@ -243,7 +244,7 @@ class Modal extends Widget echo Html::beginTag('div', array('class'=>'modal-header')); if ($this->closeText) echo Html::button($this->closeText, null, null, array('data-dismiss' => 'modal', 'class'=>'close')); - echo $this->renderSection($this->header); + echo $this->header; echo Html::endTag('div'); } @@ -253,7 +254,7 @@ class Modal extends Widget public function renderModalBody() { echo Html::beginTag('div', array('class'=>'modal-body')); - echo $this->renderSection($this->content); + echo $this->content; echo Html::endTag('div'); } @@ -264,37 +265,22 @@ class Modal extends Widget { echo Html::beginTag('div', array('class'=>'modal-footer')); - echo $this->renderSection($this->footer); + echo $this->footer; echo Html::endTag('div'); } /** - * Renders a section. If the section is a view file, the returned string will be the contents of the view file, - * otherwise, it will return the string in the $section variable. - * @param string $section - * @return string - */ - public function renderSection($section) - { - $viewFile = Yii::getAlias($section); - if (is_file($viewFile)) - return $this->view->renderFile($viewFile, array(), $this); - return $section; - } - - /** * Registers client scripts */ public function registerScript() { - $id = '#' . ArrayHelper::getValue($this->options, 'id'); // do we render a button? If so, bootstrap will handle its behavior through its // mark-up, otherwise, register the plugin. if(empty($this->buttonOptions)) - $this->registerPlugin($id, $this->pluginOptions); + $this->registerPlugin('modal', $this->pluginOptions); // register events - $this->registerEvents($id, $this->events); + $this->registerEvents($this->events); } } \ No newline at end of file diff --git a/yii/bootstrap/Widget.php b/yii/bootstrap/Widget.php index 2995afa..c50349f 100644 --- a/yii/bootstrap/Widget.php +++ b/yii/bootstrap/Widget.php @@ -31,11 +31,6 @@ class Widget extends \yii\base\Widget public $options = array(); /** - * @var string the widget name (ie. modal, typeahead, tab) - */ - protected $name; - - /** * Initializes the widget. */ public function init() @@ -48,11 +43,10 @@ class Widget extends \yii\base\Widget * Registers plugin events with the API. * @param string $selector the CSS selector. * @param string[] $events the JavaScript event configuration (name=>handler). - * @param int $position the position of the JavaScript code. * @return boolean whether the events were registered. * @todo To be discussed */ - protected function registerEvents($selector, $events = array(), $position = View::POS_END) + protected function registerEvents($selector, $events = array()) { if (empty($events)) return; @@ -63,24 +57,24 @@ class Widget extends \yii\base\Widget ? $handler : new JsExpression($handler); - $script .= ";jQuery(document).ready(function (){jQuery('{$selector}').on('{$name}', {$handler});});"; + $script .= ";jQuery('{$selector}').on('{$name}', {$handler});"; } if (!empty($script)) - $this->view->registerJs($script, array('position' => $position)); + $this->view->registerJs($script); } /** * Registers a specific Bootstrap plugin using the given selector and options. * - * @param string $selector the CSS selector + * @param string $name the name of the javascript widget to initialize * @param array $options the Javascript options for the plugin - * @param int $position the position of the JavaScript code */ - public function registerPlugin($selector, $options = array(), $position = View::POS_END) + public function registerPlugin($name, $options = array()) { + $selector = '#' . ArrayHelper::getValue($this->options, 'id'); $options = !empty($options) ? Json::encode($options) : ''; - $script = ";jQuery(document).ready(function (){jQuery('{$selector}').{$this->name}({$options});});"; - $this->view->registerJs($script, array('position' => $position)); + $script = ";jQuery('{$selector}').{$name}({$options});"; + $this->view->registerJs($script); } /** @@ -89,31 +83,28 @@ class Widget extends \yii\base\Widget */ public function registerBundle($responsive = false) { - $bundle = $responsive ? 'yii/bootstrap' : 'yii/bootstrap-responsive'; - + $bundle = $responsive ? 'yii/bootstrap-responsive' : 'yii/bootstrap'; $this->view->registerAssetBundle($bundle); } /** - * Adds a new option. If the key does not exists, it will create one, if it exists it will append the value - * and also makes sure the uniqueness of them. + * Adds a new class to options. If the class key does not exists, it will create one, if it exists it will append + * the value and also makes sure the uniqueness of them. * - * @param string $key - * @param mixed $value - * @param string $glue + * @param string $class * @return array */ - protected function addOption($key, $value, $glue = ' ') + protected function addClassName($class) { - if (isset($this->options[$key])) { - if (!is_array($this->options[$key])) - $this->options[$key] = explode($glue, $this->options[$key]); - $this->options[$key][] = $value; - $this->options[$key] = array_unique($this->options[$key]); - $this->options[$key] = implode($glue, $this->options[$key]); + if (isset($this->options['class'])) { + if (!is_array($this->options['class'])) + $this->options['class'] = explode(' ', $this->options['class']); + $this->options['class'][] = $class; + $this->options['class'] = array_unique($this->options['class']); + $this->options['class'] = implode(' ', $this->options['class']); } else - $this->options[$key] = $value; + $this->options['class'] = $class; return $this->options; } From 5e5b629df4a64580be443ed5553d3b83c9b5e901 Mon Sep 17 00:00:00 2001 From: Veaceslav Medvedev Date: Mon, 20 May 2013 11:28:33 +0300 Subject: [PATCH 08/14] Update AccessRule.php --- yii/web/AccessRule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yii/web/AccessRule.php b/yii/web/AccessRule.php index e565e18..3897769 100644 --- a/yii/web/AccessRule.php +++ b/yii/web/AccessRule.php @@ -124,7 +124,7 @@ class AccessRule extends Component */ protected function matchController($controller) { - return empty($this->controllers) || in_array($controller->id, $this->controllers, true); + return empty($this->controllers) || in_array($controller->uniqueId, $this->controllers, true); } /** From 5f23f631ba2ad1d50bc402e40dd7974164a3b316 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Mon, 20 May 2013 07:55:05 -0400 Subject: [PATCH 09/14] hashing the key for registerCss and registerJs. --- yii/base/View.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yii/base/View.php b/yii/base/View.php index 04eaacc..cf92741 100644 --- a/yii/base/View.php +++ b/yii/base/View.php @@ -614,7 +614,7 @@ class View extends Component */ public function registerCss($css, $options = array(), $key = null) { - $key = $key ?: $css; + $key = $key ?: md5($css); $this->css[$key] = Html::style($css, $options); } @@ -650,7 +650,7 @@ class View extends Component */ public function registerJs($js, $position = self::POS_READY, $key = null) { - $key = $key ?: $js; + $key = $key ?: md5($js); $this->js[$position][$key] = $js; if ($position === self::POS_READY) { $this->registerAssetBundle('yii/jquery'); From 241b6fc49aeb390a8e492154936c3e17c3f0eb56 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Mon, 20 May 2013 08:41:20 -0400 Subject: [PATCH 10/14] Modified the IAssetConvert interface. --- yii/web/AssetBundle.php | 4 ++-- yii/web/AssetConverter.php | 11 +++++------ yii/web/IAssetConverter.php | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/yii/web/AssetBundle.php b/yii/web/AssetBundle.php index 37577dd..daa533f 100644 --- a/yii/web/AssetBundle.php +++ b/yii/web/AssetBundle.php @@ -135,10 +135,10 @@ class AssetBundle extends Object $this->publish($view->getAssetManager()); foreach ($this->js as $js) { - $view->registerJsFile($js, $this->jsOptions); + $view->registerJsFile($this->baseUrl . '/' . $js, $this->jsOptions); } foreach ($this->css as $css) { - $view->registerCssFile($css, $this->cssOptions); + $view->registerCssFile($this->baseUrl . '/' . $css, $this->cssOptions); } } diff --git a/yii/web/AssetConverter.php b/yii/web/AssetConverter.php index 4fde1fc..cfad360 100644 --- a/yii/web/AssetConverter.php +++ b/yii/web/AssetConverter.php @@ -34,13 +34,12 @@ class AssetConverter extends Component implements IAssetConverter * Converts a given asset file into a CSS or JS file. * @param string $asset the asset file path, relative to $basePath * @param string $basePath the directory the $asset is relative to. - * @param string $baseUrl the URL corresponding to $basePath - * @return string the URL to the converted asset file. + * @return string the converted asset file path, relative to $basePath. */ - public function convert($asset, $basePath, $baseUrl) + public function convert($asset, $basePath) { $pos = strrpos($asset, '.'); - if ($pos !== false) { + if ($pos === false) { $ext = substr($asset, $pos + 1); if (isset($this->commands[$ext])) { list ($ext, $command) = $this->commands[$ext]; @@ -54,9 +53,9 @@ class AssetConverter extends Component implements IAssetConverter exec($command, $output); Yii::info("Converted $asset into $result: " . implode("\n", $output), __METHOD__); } - return "$baseUrl/$result"; + return $result; } } - return "$baseUrl/$asset"; + return $asset; } } diff --git a/yii/web/IAssetConverter.php b/yii/web/IAssetConverter.php index d1d1da0..6021963 100644 --- a/yii/web/IAssetConverter.php +++ b/yii/web/IAssetConverter.php @@ -19,9 +19,7 @@ interface IAssetConverter * Converts a given asset file into a CSS or JS file. * @param string $asset the asset file path, relative to $basePath * @param string $basePath the directory the $asset is relative to. - * @param string $baseUrl the URL corresponding to $basePath - * @return string the URL to the converted asset file. If the given asset does not - * need conversion, "$baseUrl/$asset" should be returned. + * @return string the converted asset file path, relative to $basePath. */ - public function convert($asset, $basePath, $baseUrl); + public function convert($asset, $basePath); } From 73437c57128d59ba7c5099f5bd1474e311fbac77 Mon Sep 17 00:00:00 2001 From: Alexander Kochetov Date: Mon, 20 May 2013 17:24:36 +0400 Subject: [PATCH 11/14] Twitter bootstrap updated to 2.3.2 --- yii/assets/bootstrap/css/bootstrap-responsive.css | 2 +- yii/assets/bootstrap/css/bootstrap.css | 11 +++++++- yii/assets/bootstrap/js/bootstrap.js | 32 +++++++++++++---------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/yii/assets/bootstrap/css/bootstrap-responsive.css b/yii/assets/bootstrap/css/bootstrap-responsive.css index fcd72f7..09e88ce 100644 --- a/yii/assets/bootstrap/css/bootstrap-responsive.css +++ b/yii/assets/bootstrap/css/bootstrap-responsive.css @@ -1,5 +1,5 @@ /*! - * Bootstrap Responsive v2.3.1 + * Bootstrap Responsive v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 diff --git a/yii/assets/bootstrap/css/bootstrap.css b/yii/assets/bootstrap/css/bootstrap.css index 2f56af3..b725064 100644 --- a/yii/assets/bootstrap/css/bootstrap.css +++ b/yii/assets/bootstrap/css/bootstrap.css @@ -1,5 +1,5 @@ /*! - * Bootstrap v2.3.1 + * Bootstrap v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 @@ -3009,6 +3009,15 @@ table th[class*="span"], display: block; } +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + .pull-right > .dropdown-menu { right: 0; left: auto; diff --git a/yii/assets/bootstrap/js/bootstrap.js b/yii/assets/bootstrap/js/bootstrap.js index c298ee4..643e71c 100644 --- a/yii/assets/bootstrap/js/bootstrap.js +++ b/yii/assets/bootstrap/js/bootstrap.js @@ -1,5 +1,5 @@ /* =================================================== - * bootstrap-transition.js v2.3.1 + * bootstrap-transition.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#transitions * =================================================== * Copyright 2012 Twitter, Inc. @@ -58,7 +58,7 @@ }) }(window.jQuery);/* ========================================================== - * bootstrap-alert.js v2.3.1 + * bootstrap-alert.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#alerts * ========================================================== * Copyright 2012 Twitter, Inc. @@ -156,7 +156,7 @@ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) }(window.jQuery);/* ============================================================ - * bootstrap-button.js v2.3.1 + * bootstrap-button.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#buttons * ============================================================ * Copyright 2012 Twitter, Inc. @@ -260,7 +260,7 @@ }) }(window.jQuery);/* ========================================================== - * bootstrap-carousel.js v2.3.1 + * bootstrap-carousel.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#carousel * ========================================================== * Copyright 2012 Twitter, Inc. @@ -466,7 +466,7 @@ }) }(window.jQuery);/* ============================================================= - * bootstrap-collapse.js v2.3.1 + * bootstrap-collapse.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#collapse * ============================================================= * Copyright 2012 Twitter, Inc. @@ -632,7 +632,7 @@ }) }(window.jQuery);/* ============================================================ - * bootstrap-dropdown.js v2.3.1 + * bootstrap-dropdown.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html#dropdowns * ============================================================ * Copyright 2012 Twitter, Inc. @@ -685,6 +685,10 @@ clearMenus() if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $('