e52abefd by Chris Boden

Added MenuWidget

1 parent 3b5668b0
1 // Lines of code vs jQuery: +30ish
2 // Performance gain: Yes
3 // Time tanken vs jQuery implementation: substantially less
4 // Does it work: Fuck yes (jQuery didn't, dear jQuery: LEARN TO CLONE PROPERLY!)
5 // Native JavaScript: Tried, tested and true!
6
7 var MenuWidget = function() {
8 var init = function(e) {
9 jQuery(document).ajaxSuccess(doLinks);
10 doLinks();
11 }
12
13 var doLinks = function() {
14 var Links = document.getElementsByTagName('a');
15 for (var i = 0, len = Links.length; i < len; i++) {
16 var strRel = ' ' + Links[i].rel + ' ';
17 if (strRel.indexOf(' TzMenuDone ') != -1) {
18 continue;
19 }
20
21 var strClass = ' ' + Links[i].className + ' ';
22 if (strClass.indexOf(' TzAddMenuItem ') != -1) {
23 Links[i].onclick = function() { return false; };
24 addEvent(Links[i], 'click', addLink);
25 }
26
27 if (strClass.indexOf(' TzDelMenuItem ') != -1) {
28 Links[i].onclick = function() { return false; };
29 addEvent(Links[i], 'click', delLink);
30 }
31 }
32 }
33
34 var addLink = function(e) {
35 var p = e.target;
36 while (p.tagName != 'body' && p.className != 'TzMenuPageList') {
37 p = p.parentNode;
38 }
39 if (p.tagName == 'body') {
40 console.error('Something missing in widget!');
41 return;
42 }
43
44 var Container = document.createElement('span');
45 Container.className = 'TzPageContainer';
46
47 var Copy = p.getElementsByTagName('select')[0].cloneNode(true);
48 Copy.id = '';
49
50 var Del = document.createElement('a');
51 Del.href = '#';
52 Del.appendChild(document.createTextNode('Del'));
53 Del.onclick = function() { return false; };
54 Del.className = 'TzDelMenuItem';
55 addEvent(Del, 'click', delLink);
56
57 Container.appendChild(Copy);
58 Container.appendChild(Del);
59 p.appendChild(Container);
60 }
61
62 var delLink = function(e) {
63 var Container = e.target;
64 while (Container.tagName != 'body' && Container.className != 'TzPageContainer') {
65 Container = Container.parentNode;
66 }
67 if (Container.tagName == 'body') {
68 console.error('Container not found');
69 return;
70 }
71
72 Container.parentNode.removeChild(Container);
73 }
74
75 addEvent(window, 'load', init);
76 }();
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 class MenuWidget extends WP_Widget {
3 public static function init() {
4 register_widget(__CLASS__);
5
6 if (is_admin()) {
7 _enqueue_script('tz-menu-widget', plugins_url('MenuWidget.js', __FILE__), Array('addEvent','jQuery'));
8 }
9 }
10
11 public function __construct() {
12 static $options = Array(
13 'classname' => ''
14 , 'description' => 'Configurable menu to site hierarchy'
15 );
16
17 parent::__construct('tz-menu-widget', 'Menu', $options);
18 }
19
20 public function widget($args, $instance) {
21 static $all_pages = false;
22
23 foreach ($instance['pages'] as $page) {
24 if ($instance['inclusive'] == 0) {
25 $instance['child_of'] = $page;
26 _list_pages($instance);
27 continue;
28 }
29
30 if (!$all_pages) {
31 $all_pages = get_pages(Array('sort_column' => 'menu_order'));
32 }
33
34 $instance['exclude'] = '';
35 $children = Array($page);
36 foreach ($all_pages as $key => $wp_page) {
37 if ($wp_page->post_parent == $page || in_array($wp_page->post_parent, $children)) {
38 $children[] = $wp_page->ID;
39 }
40
41 if (!in_array($wp_page->ID, $children)) {
42 if (!empty($instance['exclude'])) {
43 $instance['exclude'] .= ',';
44 }
45 $instance['exclude'] .= $wp_page->ID;
46 }
47 }
48
49 _list_pages($instance);
50 }
51 }
52
53 public function update($new_instance, $old_instance) {
54 $instance = $old_instance;
55
56 $instance['pages'] = Array();
57
58 $instance['title_li'] = strip_tags(stripslashes($new_instance['title_li']));
59 $instance['pages'] = (array)$new_instance['pages']; // (int)strip_tags(stripslashes($new_instance['page']));
60 $instance['depth'] = (int)strip_tags(stripslashes($new_instance['depth']));
61 $instance['inclusive'] = ($new_instance['inclusive'] == 'on' ? 1 : 0);
62
63 return $instance;
64 }
65
66 public function form($instance) {
67 $instance = _parse_args((array)$instance, Array('title_li' => '', 'pages' => Array(0 => ''), 'depth' => '', 'inclusive' => ''));
68 $checked = ($instance['inclusive'] == 1 ? ' checked="checked" ' : '');
69
70 ?>
71 <p>
72 <label for="<?php echo $this->get_field_id('title_li'); ?>">Title</label>
73 <br /><input type="text" id="<?php echo $this->get_field_id('title_li'); ?>" name="<?php echo $this->get_field_name('title_li'); ?>" value="<?php echo attribute_escape($instance['title_li']); ?>" />
74 </p>
75
76 <p class="TzMenuPageList">
77 <label>Page(s)</label> <a href="#" class="TzAddMenuItem">Add Another</a>
78 <?php
79 foreach ($instance['pages'] as $key => $page) {
80 echo '<span class="TzPageContainer">';
81 _dropdown_pages(Array('name' => $this->get_field_name('pages') . '[]', 'selected' => attribute_escape($instance['pages'][$key]), 'sort_column' => 'menu_order', 'echo' => 1));
82 if ($key > 0) {
83 echo '<a href="#" class="TzDelMenuItem">Del</a>';
84 }
85 echo '</span>';
86 }
87 ?>
88 </p>
89
90 <p>
91 <label for="<?php echo $this->get_field_id('depth'); ?>">Depth</label> &nbsp;(0 for infinite)
92 <br /><input type="text" size="2" maxlength="2" id="<?php echo $this->get_field_id('depth'); ?>" name="<?php echo $this->get_field_name('depth'); ?>" value="<?php echo attribute_escape($instance['depth']); ?>" />
93 </p>
94
95 <p>
96 <input type="checkbox" id="<?php echo $this->get_field_id('inclusive'); ?>" name="<?php echo $this->get_field_name('inclusive'); ?>" <?php echo $checked; ?> />
97 <label for="<?php echo $this->get_field_id('inclusive'); ?>">Show Selected (vs just children)</label>
98 </p>
99 <?php
100 }
101 }
102 ?>
...\ No newline at end of file ...\ No newline at end of file
...@@ -11,7 +11,7 @@ class WP_Option implements ArrayAccess, Countable { ...@@ -11,7 +11,7 @@ class WP_Option implements ArrayAccess, Countable {
11 $this->_ns = $ns; 11 $this->_ns = $ns;
12 $this->_data = get_option($ns); 12 $this->_data = get_option($ns);
13 13
14 if (!is_null($defaults) && is_array($defaults)) { 14 if (is_array($defaults)) {
15 foreach ($this->_data as $key => $val) { 15 foreach ($this->_data as $key => $val) {
16 $defaults[$key] = $val; 16 $defaults[$key] = $val;
17 } 17 }
...@@ -53,5 +53,10 @@ class WP_Option implements ArrayAccess, Countable { ...@@ -53,5 +53,10 @@ class WP_Option implements ArrayAccess, Countable {
53 array_merge($this->_data, $data); 53 array_merge($this->_data, $data);
54 $this->save(); 54 $this->save();
55 } 55 }
56
57 public function dump() {
58 echo "Here\n";
59 print_r($this->_data);
60 }
56 } 61 }
57 ?>
...\ No newline at end of file ...\ No newline at end of file
62 ?>
......
1 /**
2 * addEvent & removeEvent -- cross-browser event handling
3 * Copyright (C) 2006-2007 Dao Gottwald
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * Contact information:
20 * Dao Gottwald <dao at design-noir.de>
21 *
22 * @version 1.1.7
23 */
24
25 function addEvent(o, type, fn) {
26 o.addEventListener(type, fn, false);
27 }
28 function removeEvent(o, type, fn) {
29 o.removeEventListener(type, fn, false);
30 }
31 /*@cc_on if (!window.addEventListener) {
32 var addEvent = function(o, type, fn) {
33 if (!o._events) o._events = {};
34 var queue = o._events[type];
35 if (!queue) {
36 o._events[type] = [fn];
37 if (!o._events._callback)
38 o._events._callback = function(e) { Event._callListeners(e, o) };
39 o.attachEvent("on" + type, o._events._callback);
40 } else if (Event._fnIndex(o, type, fn) == -1)
41 queue.push(fn);
42 else return;
43 Event._mem.push([o, type, fn]);
44 };
45 var removeEvent = function(o, type, fn) {
46 var i = Event._fnIndex(o, type, fn);
47 if (i < 0) return;
48 var queue = o._events[type];
49 if (queue.calling) {
50 delete queue[i];
51 if (queue.removeListeners)
52 queue.removeListeners.push(i);
53 else
54 queue.removeListeners = [i];
55 } else
56 if (queue.length == 1)
57 Event._detach(o, type);
58 else
59 queue.splice(i, 1);
60 };
61 var Event = {
62 AT_TARGET: 2,
63 BUBBLING_PHASE: 3,
64 stopPropagation: function() { this.cancelBubble = true },
65 preventDefault: function() { this.returnValue = false },
66 _mem: [],
67 _callListeners: function(e, o) {
68 e.stopPropagation = this.stopPropagation;
69 e.preventDefault = this.preventDefault;
70 e.currentTarget = o;
71 e.target = e.srcElement;
72 e.eventPhase = e.currentTarget == e.target ? this.AT_TARGET : this.BUBBLING_PHASE;
73 switch (e.type) {
74 case "mouseover":
75 e.relatedTarget = e.fromElement;
76 break;
77 case "mouseout":
78 e.relatedTarget = e.toElement;
79 }
80 var queue = o._events[e.type];
81 queue.calling = true;
82 for (var i = 0, l = queue.length; i < l; i++)
83 if (queue[i])
84 queue[i].call(o,e);
85 queue.calling = null;
86 if (!queue.removeListeners)
87 return;
88 if (queue.length == queue.removeListeners.length) {
89 this._detach(o, e.type);
90 return;
91 }
92 queue.removeListeners = queue.removeListeners.sort(function(a,b){return a-b});
93 var i = queue.removeListeners.length;
94 while (i--)
95 queue.splice(queue.removeListeners[i], 1);
96 if (queue.length == 0)
97 this._detach(o, e.type);
98 else
99 queue.removeListeners = null;
100 },
101 _detach: function(o, type) {
102 o.detachEvent("on" + type, o._events._callback);
103 delete o._events[type];
104 },
105 _fnIndex: function(o, type, fn) {
106 var queue = o._events[type];
107 if (queue)
108 for (var i = 0, l = queue.length; i < l; i++)
109 if (queue[i] == fn)
110 return i;
111 return -1;
112 },
113 _cleanup: function() {
114 for (var m, i = 0; m = this._mem[i]; i++)
115 if (m[1] != "unload" || m[2] == this._cleanup)
116 removeEvent(m[0], m[1], m[2]);
117 }
118 };
119 addEvent(window, "unload", Event._cleanup);
120 } @*/
...@@ -10,27 +10,26 @@ Author: Tenzing ...@@ -10,27 +10,26 @@ Author: Tenzing
10 die('PHP version 5.2.2 or greater is required'); 10 die('PHP version 5.2.2 or greater is required');
11 } 11 }
12 12
13 new TzTools(); 13 TzTools::load();
14 14
15 class TzTools { 15 class TzTools {
16 public function __construct() { 16 public static function load() {
17 set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__)); 17 // set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__));
18 spl_autoload_register(Array('TzTools', 'loader')); 18 spl_autoload_register(Array(__CLASS__, 'autoloader'));
19 19
20 require_once(dirname(__FILE__) . '/wp_functions.php'); 20 require_once(dirname(__FILE__) . '/wp_functions.php');
21 21
22 add_action('wp_print_scripts', Array('TzTools', 'registerScripts')); 22 _register_script('addEvent', plugins_url('addEvent.js', __FILE__));
23 }
24
25 public static function registerScripts() {
26 _register_script('xmlhttpHandler', plugins_url('xmlhttpHandler.js', __FILE__)); 23 _register_script('xmlhttpHandler', plugins_url('xmlhttpHandler.js', __FILE__));
24
25 add_action('widgets_init', Array('MenuWidget', 'init'));
27 } 26 }
28 27
29 public static function loader($class) { 28 public static function autoloader($class) {
30 $file = dirname(__FILE__) . '/' . $class . '.php'; 29 $file = dirname(__FILE__) . '/' . $class . '.php';
31 if (is_file($file)) { 30 if (is_file($file)) {
32 require($file); 31 require($file);
33 } 32 }
34 } 33 }
35 } 34 }
36 ?>
...\ No newline at end of file ...\ No newline at end of file
35 ?>
......
...@@ -52,4 +52,40 @@ function _nonce_field() { ...@@ -52,4 +52,40 @@ function _nonce_field() {
52 $params = func_get_args(); 52 $params = func_get_args();
53 return call_user_func_array('wp_nonce_field', $params); 53 return call_user_func_array('wp_nonce_field', $params);
54 } 54 }
55 ?>
...\ No newline at end of file ...\ No newline at end of file
55
56 function _loginout() {
57 $params = func_get_args();
58 return call_user_func_array('wp_loginout', $params);
59 }
60
61 // I made this one because register_sidebar_widget() is fucked
62 function _register_sidebar_widget() {
63 $params = func_get_args();
64 return call_user_func_array('wp_register_sidebar_widget', $params);
65 }
66
67 function _register_widget_control() {
68 $params = func_get_args();
69 return call_user_func_array('wp_register_widget_control', $params);
70 }
71
72 function _parse_args() {
73 $params = func_get_args();
74 return call_user_func_array('wp_parse_args', $params);
75 }
76
77 function _get_sidebars_widgets() {
78 $params = func_get_args();
79 return call_user_func_array('wp_get_sidebars_widgets', $params);
80 }
81
82 function _list_pages() {
83 $params = func_get_args();
84 return call_user_func_array('wp_list_pages', $params);
85 }
86
87 function _dropdown_pages() {
88 $params = func_get_args();
89 return call_user_func_array('wp_dropdown_pages', $params);
90 }
91 ?>
......