sufia 7.0.0.beta4 → 7.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -1
  3. data/.rubocop_todo.yml +1 -2
  4. data/.travis.yml +1 -0
  5. data/Gemfile +18 -9
  6. data/README.md +23 -3
  7. data/app/assets/javascripts/sufia.js +4 -1
  8. data/app/assets/javascripts/sufia/app.js +15 -3
  9. data/app/assets/javascripts/sufia/autocomplete.es6 +51 -0
  10. data/app/assets/javascripts/sufia/autocomplete/language.es6 +25 -0
  11. data/app/assets/javascripts/sufia/autocomplete/location.es6 +24 -0
  12. data/app/assets/javascripts/sufia/autocomplete/subject.es6 +26 -0
  13. data/app/assets/javascripts/sufia/batch_edit.js +8 -5
  14. data/app/assets/javascripts/sufia/permissions/control.es6 +7 -3
  15. data/app/assets/javascripts/sufia/save_work/required_fields.es6 +10 -4
  16. data/app/assets/javascripts/sufia/save_work/save_work_control.es6 +14 -4
  17. data/app/assets/stylesheets/sufia/_fixedsticky.scss +23 -21
  18. data/app/assets/stylesheets/sufia/_form-progress.scss +16 -7
  19. data/app/assets/stylesheets/sufia/_header.scss +2 -1
  20. data/app/assets/stylesheets/sufia/_settings.scss +4 -0
  21. data/app/controllers/api/items_controller.rb +2 -2
  22. data/app/controllers/api/zotero_controller.rb +1 -1
  23. data/app/controllers/citations_controller.rb +0 -2
  24. data/app/controllers/concerns/sufia/batch_edits_controller_behavior.rb +7 -7
  25. data/app/controllers/concerns/sufia/batch_uploads_controller_behavior.rb +9 -3
  26. data/app/controllers/concerns/sufia/singular_subresource_controller.rb +6 -1
  27. data/app/controllers/concerns/sufia/transfers_controller_behavior.rb +1 -1
  28. data/app/controllers/concerns/sufia/users_controller_behavior.rb +3 -3
  29. data/app/controllers/concerns/sufia/works_controller_behavior.rb +11 -4
  30. data/app/controllers/my/highlights_controller.rb +1 -1
  31. data/app/forms/sufia/forms/batch_edit_form.rb +10 -6
  32. data/app/forms/sufia/forms/batch_upload_form.rb +2 -2
  33. data/app/forms/sufia/forms/collection_form.rb +4 -0
  34. data/app/forms/sufia/forms/work_form.rb +4 -0
  35. data/app/helpers/sufia/blacklight_override.rb +0 -20
  36. data/app/helpers/sufia/collections_helper.rb +12 -0
  37. data/app/helpers/sufia/sufia_helper_behavior.rb +84 -56
  38. data/app/jobs/batch_create_job.rb +18 -2
  39. data/app/jobs/content_depositor_change_event_job.rb +13 -6
  40. data/app/jobs/create_work_job.rb +6 -2
  41. data/app/models/batch_upload_item.rb +15 -0
  42. data/app/models/concerns/sufia/ability.rb +7 -4
  43. data/app/models/concerns/sufia/user.rb +0 -11
  44. data/app/models/concerns/sufia/work_behavior.rb +1 -0
  45. data/app/models/concerns/sufia/works/featured.rb +23 -0
  46. data/app/models/file_download_stat.rb +9 -12
  47. data/app/models/file_view_stat.rb +5 -15
  48. data/app/models/proxy_deposit_request.rb +11 -7
  49. data/app/models/sufia/statistic.rb +65 -0
  50. data/app/models/work_view_stat.rb +5 -16
  51. data/app/presenters/file_usage.rb +3 -4
  52. data/app/presenters/sufia/file_set_presenter.rb +1 -3
  53. data/app/presenters/sufia/trophy_presenter.rb +28 -0
  54. data/app/presenters/sufia/user_profile_presenter.rb +1 -1
  55. data/app/presenters/work_usage.rb +5 -4
  56. data/app/search_builders/deposit_search_builder.rb +4 -3
  57. data/app/search_builders/parent_collection_search_builder.rb +1 -1
  58. data/app/services/sufia/collection_member_service.rb +1 -1
  59. data/app/services/sufia/user_stat_importer.rb +11 -6
  60. data/app/views/_controls.html.erb +11 -9
  61. data/app/views/batch_edits/edit.html.erb +8 -2
  62. data/app/views/catalog/_index_list_default.html.erb +2 -1
  63. data/app/views/curation_concerns/base/_form_metadata.html.erb +1 -1
  64. data/app/views/curation_concerns/base/_form_progress.html.erb +1 -1
  65. data/app/views/curation_concerns/base/_form_relationships.html.erb +1 -1
  66. data/app/views/curation_concerns/base/_guts4form.html.erb +6 -2
  67. data/app/views/curation_concerns/base/_items.html.erb +1 -1
  68. data/app/views/curation_concerns/base/edit.html.erb +1 -1
  69. data/app/views/curation_concerns/base/new.html.erb +1 -1
  70. data/app/views/curation_concerns/file_sets/_permission.html.erb +5 -1
  71. data/app/views/curation_concerns/file_sets/media_display/_default.html.erb +1 -1
  72. data/app/views/curation_concerns/file_sets/show.html.erb +1 -1
  73. data/app/views/dashboard/_index_partials/_heading_actions.html.erb +1 -1
  74. data/app/views/{error → errors}/404.html.erb +0 -0
  75. data/app/views/records/edit_fields/_based_near.html.erb +8 -0
  76. data/app/views/records/edit_fields/_language.html.erb +8 -0
  77. data/app/views/records/edit_fields/_subject.html.erb +8 -0
  78. data/app/views/stats/work.html.erb +1 -1
  79. data/app/views/sufia/batch_uploads/_form.html.erb +1 -1
  80. data/app/views/sufia/homepage/_home_header.html.erb +1 -1
  81. data/app/views/sufia/homepage/_sortable_featured.html.erb +1 -1
  82. data/app/views/transfers/new.html.erb +3 -1
  83. data/app/views/users/_contributions.html.erb +1 -1
  84. data/config/locales/sufia.en.yml +3 -2
  85. data/config/routes.rb +0 -7
  86. data/lib/generators/sufia/install_generator.rb +0 -24
  87. data/lib/generators/sufia/templates/catalog_controller.rb +4 -3
  88. data/lib/generators/sufia/templates/config/sufia.rb +4 -2
  89. data/lib/generators/sufia/upgrade700_generator.rb +7 -9
  90. data/lib/generators/sufia/work_generator.rb +56 -0
  91. data/lib/sufia.rb +4 -1
  92. data/lib/sufia/arkivo/actor.rb +1 -1
  93. data/lib/sufia/configuration.rb +15 -3
  94. data/lib/sufia/engine.rb +1 -10
  95. data/lib/sufia/version.rb +1 -1
  96. data/spec/controllers/api/items_controller_spec.rb +20 -7
  97. data/spec/controllers/sufia/batch_uploads_controller_spec.rb +4 -3
  98. data/spec/controllers/transfers_controller_spec.rb +3 -11
  99. data/spec/controllers/users_controller_spec.rb +2 -1
  100. data/spec/features/batch_edit_spec.rb +17 -2
  101. data/spec/forms/sufia/forms/batch_edit_form_spec.rb +2 -0
  102. data/spec/forms/sufia/forms/batch_upload_form_spec.rb +1 -1
  103. data/spec/helpers/blacklight_helper_spec.rb +36 -26
  104. data/spec/helpers/{generic_work_helper_spec.rb → sufia/collections_helper_spec.rb} +1 -1
  105. data/spec/helpers/sufia_helper_spec.rb +70 -32
  106. data/spec/javascripts/autocomplete_spec.js.coffee +7 -7
  107. data/spec/javascripts/save_work_spec.js +20 -20
  108. data/spec/lib/sufia/configuration_spec.rb +30 -0
  109. data/spec/lib/sufia/user_stat_importer_spec.rb +21 -36
  110. data/spec/models/file_download_stat_spec.rb +8 -8
  111. data/spec/models/file_view_stat_spec.rb +8 -8
  112. data/spec/models/generic_work_spec.rb +24 -0
  113. data/spec/models/proxy_deposit_request_spec.rb +2 -4
  114. data/spec/models/sufia/ability_spec.rb +7 -13
  115. data/spec/models/user_spec.rb +0 -14
  116. data/spec/models/work_view_stat_spec.rb +22 -8
  117. data/spec/presenters/sufia/file_usage_spec.rb +0 -4
  118. data/spec/presenters/sufia/trophy_presenter_spec.rb +46 -0
  119. data/spec/presenters/sufia/user_profile_presenter_spec.rb +4 -1
  120. data/spec/presenters/sufia/work_usage_spec.rb +8 -17
  121. data/spec/routing/route_spec.rb +0 -6
  122. data/spec/spec_helper.rb +8 -2
  123. data/spec/test_app_templates/lib/generators/test_app_generator.rb +4 -0
  124. data/spec/views/batch_edits/edit.html.erb_spec.rb +8 -2
  125. data/spec/views/catalog/_index_list_default.html.erb_spec.rb +8 -6
  126. data/spec/views/curation_concerns/base/_form.html.erb_spec.rb +3 -0
  127. data/spec/views/curation_concerns/file_sets/_permission.html.erb_spec.rb +16 -0
  128. data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +0 -2
  129. data/spec/views/records/edit_fields/_based_near.html.erb_spec.rb +20 -0
  130. data/spec/views/records/edit_fields/_language.html.erb_spec.rb +20 -0
  131. data/spec/views/records/edit_fields/_subject.html.erb_spec.rb +20 -0
  132. data/spec/views/{homepage → sufia/homepage}/_announcement.html.erb_spec.rb +0 -0
  133. data/spec/views/{homepage → sufia/homepage}/_featured_works.html.erb_spec.rb +0 -0
  134. data/spec/views/{homepage → sufia/homepage}/_home_header.html.erb_spec.rb +0 -0
  135. data/spec/views/sufia/homepage/_sortable_featured.html.erb_spec.rb +21 -0
  136. data/spec/views/users/edit.html.erb_spec.rb +5 -5
  137. data/spec/views/users/show.html.erb_spec.rb +5 -3
  138. data/sufia.gemspec +4 -3
  139. data/tasks/noid.rake +2 -2
  140. data/tasks/sufia-dev.rake +1 -1
  141. metadata +73 -68
  142. data/app/assets/javascripts/sufia/edit_metadata.js +0 -87
  143. data/app/controllers/authorities_controller.rb +0 -19
  144. data/app/helpers/generic_work_helper.rb +0 -10
  145. data/app/helpers/sufia_url_helper.rb +0 -14
  146. data/app/models/concerns/sufia/file_stat_utils.rb +0 -33
  147. data/app/models/concerns/sufia/work_stat_utils.rb +0 -33
  148. data/app/models/geo_names_resource.rb +0 -18
  149. data/app/models/local_authority.rb +0 -101
  150. data/app/models/local_authority_entry.rb +0 -3
  151. data/app/models/subject_local_authority_entry.rb +0 -2
  152. data/app/views/curation_concerns/generic_works/_generic_work.html.erb +0 -3
  153. data/app/views/error/401.html.erb +0 -18
  154. data/app/views/error/500.html.erb +0 -9
  155. data/app/views/error/single_use_error.html.erb +0 -19
  156. data/lib/generators/sufia/geonames_username_config_generator.rb +0 -20
  157. data/spec/controllers/authorities_controller_spec.rb +0 -18
  158. data/spec/fixtures/cities15000.tsv +0 -149
  159. data/spec/fixtures/genreForms.nt +0 -471
  160. data/spec/fixtures/lexvo.rdf +0 -3108
  161. data/spec/helpers/sufia_url_helper_spec.rb +0 -18
  162. data/spec/models/geo_names_resource_spec.rb +0 -30
  163. data/spec/models/local_authority_spec.rb +0 -108
  164. data/vendor/assets/javascripts/almond.js +0 -430
@@ -1,18 +0,0 @@
1
- describe SufiaUrlHelper do
2
- let(:document) { SolrDocument.new(id: 'foo123') }
3
-
4
- describe "#track_collection_path" do
5
- subject { helper.track_collection_path(document) }
6
- it { is_expected.to eq '/catalog/foo123/track' }
7
- end
8
-
9
- describe "#track_file_set_path" do
10
- subject { helper.track_file_set_path(document) }
11
- it { is_expected.to eq '/catalog/foo123/track' }
12
- end
13
-
14
- describe "#track_generic_work_path" do
15
- subject { helper.track_generic_work_path(document) }
16
- it { is_expected.to eq '/catalog/foo123/track' }
17
- end
18
- end
@@ -1,30 +0,0 @@
1
- describe GeoNamesResource, type: :model do
2
- before do
3
- state = {
4
- "totalResultsCount" => 1, "geonames" => [{
5
- "countryId" => "1327865",
6
- "adminCode1" => "11",
7
- "countryName" => "Myanmar [Burma]",
8
- "fclName" => "country, state, region,...",
9
- "countryCode" => "MM",
10
- "lng" => "98",
11
- "fcodeName" => "first-order administrative division",
12
- "toponymName" => "Shan State",
13
- "fcl" => "A",
14
- "name" => "Shan State",
15
- "fcode" => "ADM1",
16
- "geonameId" => 1_297_099,
17
- "lat" => "22",
18
- "adminName1" => "Shan",
19
- "population" => 5_815_384
20
- }]
21
- }
22
- ActiveResource::HttpMock.respond_to do |mock|
23
- mock.get "/searchJSON?maxRows=10&q=State&username=", {}, state.to_json
24
- end
25
- end
26
- it "finds locations" do
27
- hits = described_class.find_location("State")
28
- expect(hits).not_to be_nil
29
- end
30
- end
@@ -1,108 +0,0 @@
1
- describe LocalAuthority, type: :model do
2
- def harvest_nt
3
- LocalAuthority.harvest_rdf("genres", [fixture_path + '/genreForms.nt'])
4
- end
5
-
6
- def harvest_tsv
7
- LocalAuthority.harvest_tsv("geo", [fixture_path + '/cities15000.tsv'], prefix: 'http://sws.geonames.org/')
8
- end
9
-
10
- it "harvests an ntriples RDF vocab" do
11
- harvest_nt
12
- expect(described_class.count).to eq(1)
13
- expect(LocalAuthorityEntry.count).to eq(6)
14
- end
15
- it "harvests an RDF/XML vocab (w/ an alt predicate)" do
16
- described_class.harvest_rdf("langs", [fixture_path + '/lexvo.rdf'],
17
- format: 'rdfxml',
18
- predicate: ::RDF::URI("http://www.w3.org/2008/05/skos#prefLabel"))
19
- expect(described_class.count).to eq(1)
20
- expect(LocalAuthorityEntry.count).to eq(35)
21
- end
22
- it "harvests TSV vocabs" do
23
- harvest_tsv
24
- expect(described_class.count).to eq(1)
25
- auth = described_class.where(name: "geo").first
26
- expect(LocalAuthorityEntry.where(local_authority_id: auth.id).first.uri).to start_with('http://sws.geonames.org/')
27
- expect(LocalAuthorityEntry.count).to eq(149)
28
- end
29
-
30
- describe "when vocabs are harvested" do
31
- let(:num_auths) { described_class.count }
32
- let(:num_entries) { LocalAuthorityEntry.count }
33
-
34
- before do
35
- harvest_nt
36
- harvest_tsv
37
- end
38
-
39
- it "does not have any initial domain terms" do
40
- expect(DomainTerm.count).to eq(0)
41
- end
42
-
43
- it "does not harvest an RDF vocab twice" do
44
- harvest_nt
45
- expect(described_class.count).to eq(num_auths)
46
- expect(LocalAuthorityEntry.count).to eq(num_entries)
47
- end
48
- it "does not harvest a TSV vocab twice" do
49
- harvest_tsv
50
- expect(described_class.count).to eq(num_auths)
51
- expect(LocalAuthorityEntry.count).to eq(num_entries)
52
- end
53
- it "registers a vocab" do
54
- described_class.register_vocabulary('manuscripts', "geographic", "geo")
55
- expect(DomainTerm.count).to eq(1)
56
- end
57
-
58
- describe "when vocabs are registered" do
59
- before do
60
- described_class.register_vocabulary('manuscripts', "geographic", "geo")
61
- described_class.register_vocabulary('manuscripts', "genre", "genres")
62
- end
63
-
64
- it "has some domain terms" do
65
- expect(DomainTerm.count).to eq(2)
66
- end
67
-
68
- describe "#entries_by_term" do
69
- let(:query) { 'A' }
70
- let(:term) { 'genre' }
71
- let(:model) { 'manuscripts' }
72
- subject { described_class.entries_by_term(model, term, query) }
73
-
74
- context "when the query is empty" do
75
- let(:query) { '' }
76
- it { is_expected.to be_nil }
77
- end
78
-
79
- context "when the model is unregistered" do
80
- let(:model) { 'my_foobar' }
81
- it { is_expected.to be_empty }
82
- end
83
-
84
- context "when the terms is unregistered" do
85
- let(:term) { 'foobar' }
86
- it { is_expected.to be_empty }
87
- end
88
-
89
- context "for subject headings" do
90
- let(:term) { 'subject' }
91
- let(:model) { 'generic_works' }
92
-
93
- before do
94
- SubjectLocalAuthorityEntry.create!(lowerLabel: 'apple', url: 'http://example.com/foo')
95
- end
96
-
97
- it "returns subject terms" do
98
- expect(subject.count).to eq 1
99
- end
100
- end
101
-
102
- it "returns genre terms" do
103
- expect(subject.count).to eq 6
104
- end
105
- end
106
- end
107
- end
108
- end
@@ -1,430 +0,0 @@
1
- /**
2
- * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
3
- * Available via the MIT or new BSD license.
4
- * see: http://github.com/jrburke/almond for details
5
- */
6
- //Going sloppy to avoid 'use strict' string cost, but strict practices should
7
- //be followed.
8
- /*jslint sloppy: true */
9
- /*global setTimeout: false */
10
-
11
- var requirejs, require, define;
12
- (function (undef) {
13
- var main, req, makeMap, handlers,
14
- defined = {},
15
- waiting = {},
16
- config = {},
17
- defining = {},
18
- hasOwn = Object.prototype.hasOwnProperty,
19
- aps = [].slice,
20
- jsSuffixRegExp = /\.js$/;
21
-
22
- function hasProp(obj, prop) {
23
- return hasOwn.call(obj, prop);
24
- }
25
-
26
- /**
27
- * Given a relative module name, like ./something, normalize it to
28
- * a real name that can be mapped to a path.
29
- * @param {String} name the relative name
30
- * @param {String} baseName a real name that the name arg is relative
31
- * to.
32
- * @returns {String} normalized name
33
- */
34
- function normalize(name, baseName) {
35
- var nameParts, nameSegment, mapValue, foundMap, lastIndex,
36
- foundI, foundStarMap, starI, i, j, part,
37
- baseParts = baseName && baseName.split("/"),
38
- map = config.map,
39
- starMap = (map && map['*']) || {};
40
-
41
- //Adjust any relative paths.
42
- if (name && name.charAt(0) === ".") {
43
- //If have a base name, try to normalize against it,
44
- //otherwise, assume it is a top-level require that will
45
- //be relative to baseUrl in the end.
46
- if (baseName) {
47
- name = name.split('/');
48
- lastIndex = name.length - 1;
49
-
50
- // Node .js allowance:
51
- if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
52
- name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
53
- }
54
-
55
- //Lop off the last part of baseParts, so that . matches the
56
- //"directory" and not name of the baseName's module. For instance,
57
- //baseName of "one/two/three", maps to "one/two/three.js", but we
58
- //want the directory, "one/two" for this normalization.
59
- name = baseParts.slice(0, baseParts.length - 1).concat(name);
60
-
61
- //start trimDots
62
- for (i = 0; i < name.length; i += 1) {
63
- part = name[i];
64
- if (part === ".") {
65
- name.splice(i, 1);
66
- i -= 1;
67
- } else if (part === "..") {
68
- if (i === 1 && (name[2] === '..' || name[0] === '..')) {
69
- //End of the line. Keep at least one non-dot
70
- //path segment at the front so it can be mapped
71
- //correctly to disk. Otherwise, there is likely
72
- //no path mapping for a path starting with '..'.
73
- //This can still fail, but catches the most reasonable
74
- //uses of ..
75
- break;
76
- } else if (i > 0) {
77
- name.splice(i - 1, 2);
78
- i -= 2;
79
- }
80
- }
81
- }
82
- //end trimDots
83
-
84
- name = name.join("/");
85
- } else if (name.indexOf('./') === 0) {
86
- // No baseName, so this is ID is resolved relative
87
- // to baseUrl, pull off the leading dot.
88
- name = name.substring(2);
89
- }
90
- }
91
-
92
- //Apply map config if available.
93
- if ((baseParts || starMap) && map) {
94
- nameParts = name.split('/');
95
-
96
- for (i = nameParts.length; i > 0; i -= 1) {
97
- nameSegment = nameParts.slice(0, i).join("/");
98
-
99
- if (baseParts) {
100
- //Find the longest baseName segment match in the config.
101
- //So, do joins on the biggest to smallest lengths of baseParts.
102
- for (j = baseParts.length; j > 0; j -= 1) {
103
- mapValue = map[baseParts.slice(0, j).join('/')];
104
-
105
- //baseName segment has config, find if it has one for
106
- //this name.
107
- if (mapValue) {
108
- mapValue = mapValue[nameSegment];
109
- if (mapValue) {
110
- //Match, update name to the new value.
111
- foundMap = mapValue;
112
- foundI = i;
113
- break;
114
- }
115
- }
116
- }
117
- }
118
-
119
- if (foundMap) {
120
- break;
121
- }
122
-
123
- //Check for a star map match, but just hold on to it,
124
- //if there is a shorter segment match later in a matching
125
- //config, then favor over this star map.
126
- if (!foundStarMap && starMap && starMap[nameSegment]) {
127
- foundStarMap = starMap[nameSegment];
128
- starI = i;
129
- }
130
- }
131
-
132
- if (!foundMap && foundStarMap) {
133
- foundMap = foundStarMap;
134
- foundI = starI;
135
- }
136
-
137
- if (foundMap) {
138
- nameParts.splice(0, foundI, foundMap);
139
- name = nameParts.join('/');
140
- }
141
- }
142
-
143
- return name;
144
- }
145
-
146
- function makeRequire(relName, forceSync) {
147
- return function () {
148
- //A version of a require function that passes a moduleName
149
- //value for items that may need to
150
- //look up paths relative to the moduleName
151
- var args = aps.call(arguments, 0);
152
-
153
- //If first arg is not require('string'), and there is only
154
- //one arg, it is the array form without a callback. Insert
155
- //a null so that the following concat is correct.
156
- if (typeof args[0] !== 'string' && args.length === 1) {
157
- args.push(null);
158
- }
159
- return req.apply(undef, args.concat([relName, forceSync]));
160
- };
161
- }
162
-
163
- function makeNormalize(relName) {
164
- return function (name) {
165
- return normalize(name, relName);
166
- };
167
- }
168
-
169
- function makeLoad(depName) {
170
- return function (value) {
171
- defined[depName] = value;
172
- };
173
- }
174
-
175
- function callDep(name) {
176
- if (hasProp(waiting, name)) {
177
- var args = waiting[name];
178
- delete waiting[name];
179
- defining[name] = true;
180
- main.apply(undef, args);
181
- }
182
-
183
- if (!hasProp(defined, name) && !hasProp(defining, name)) {
184
- throw new Error('No ' + name);
185
- }
186
- return defined[name];
187
- }
188
-
189
- //Turns a plugin!resource to [plugin, resource]
190
- //with the plugin being undefined if the name
191
- //did not have a plugin prefix.
192
- function splitPrefix(name) {
193
- var prefix,
194
- index = name ? name.indexOf('!') : -1;
195
- if (index > -1) {
196
- prefix = name.substring(0, index);
197
- name = name.substring(index + 1, name.length);
198
- }
199
- return [prefix, name];
200
- }
201
-
202
- /**
203
- * Makes a name map, normalizing the name, and using a plugin
204
- * for normalization if necessary. Grabs a ref to plugin
205
- * too, as an optimization.
206
- */
207
- makeMap = function (name, relName) {
208
- var plugin,
209
- parts = splitPrefix(name),
210
- prefix = parts[0];
211
-
212
- name = parts[1];
213
-
214
- if (prefix) {
215
- prefix = normalize(prefix, relName);
216
- plugin = callDep(prefix);
217
- }
218
-
219
- //Normalize according
220
- if (prefix) {
221
- if (plugin && plugin.normalize) {
222
- name = plugin.normalize(name, makeNormalize(relName));
223
- } else {
224
- name = normalize(name, relName);
225
- }
226
- } else {
227
- name = normalize(name, relName);
228
- parts = splitPrefix(name);
229
- prefix = parts[0];
230
- name = parts[1];
231
- if (prefix) {
232
- plugin = callDep(prefix);
233
- }
234
- }
235
-
236
- //Using ridiculous property names for space reasons
237
- return {
238
- f: prefix ? prefix + '!' + name : name, //fullName
239
- n: name,
240
- pr: prefix,
241
- p: plugin
242
- };
243
- };
244
-
245
- function makeConfig(name) {
246
- return function () {
247
- return (config && config.config && config.config[name]) || {};
248
- };
249
- }
250
-
251
- handlers = {
252
- require: function (name) {
253
- return makeRequire(name);
254
- },
255
- exports: function (name) {
256
- var e = defined[name];
257
- if (typeof e !== 'undefined') {
258
- return e;
259
- } else {
260
- return (defined[name] = {});
261
- }
262
- },
263
- module: function (name) {
264
- return {
265
- id: name,
266
- uri: '',
267
- exports: defined[name],
268
- config: makeConfig(name)
269
- };
270
- }
271
- };
272
-
273
- main = function (name, deps, callback, relName) {
274
- var cjsModule, depName, ret, map, i,
275
- args = [],
276
- callbackType = typeof callback,
277
- usingExports;
278
-
279
- //Use name if no relName
280
- relName = relName || name;
281
-
282
- //Call the callback to define the module, if necessary.
283
- if (callbackType === 'undefined' || callbackType === 'function') {
284
- //Pull out the defined dependencies and pass the ordered
285
- //values to the callback.
286
- //Default to [require, exports, module] if no deps
287
- deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
288
- for (i = 0; i < deps.length; i += 1) {
289
- map = makeMap(deps[i], relName);
290
- depName = map.f;
291
-
292
- //Fast path CommonJS standard dependencies.
293
- if (depName === "require") {
294
- args[i] = handlers.require(name);
295
- } else if (depName === "exports") {
296
- //CommonJS module spec 1.1
297
- args[i] = handlers.exports(name);
298
- usingExports = true;
299
- } else if (depName === "module") {
300
- //CommonJS module spec 1.1
301
- cjsModule = args[i] = handlers.module(name);
302
- } else if (hasProp(defined, depName) ||
303
- hasProp(waiting, depName) ||
304
- hasProp(defining, depName)) {
305
- args[i] = callDep(depName);
306
- } else if (map.p) {
307
- map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
308
- args[i] = defined[depName];
309
- } else {
310
- throw new Error(name + ' missing ' + depName);
311
- }
312
- }
313
-
314
- ret = callback ? callback.apply(defined[name], args) : undefined;
315
-
316
- if (name) {
317
- //If setting exports via "module" is in play,
318
- //favor that over return value and exports. After that,
319
- //favor a non-undefined return value over exports use.
320
- if (cjsModule && cjsModule.exports !== undef &&
321
- cjsModule.exports !== defined[name]) {
322
- defined[name] = cjsModule.exports;
323
- } else if (ret !== undef || !usingExports) {
324
- //Use the return value from the function.
325
- defined[name] = ret;
326
- }
327
- }
328
- } else if (name) {
329
- //May just be an object definition for the module. Only
330
- //worry about defining if have a module name.
331
- defined[name] = callback;
332
- }
333
- };
334
-
335
- requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
336
- if (typeof deps === "string") {
337
- if (handlers[deps]) {
338
- //callback in this case is really relName
339
- return handlers[deps](callback);
340
- }
341
- //Just return the module wanted. In this scenario, the
342
- //deps arg is the module name, and second arg (if passed)
343
- //is just the relName.
344
- //Normalize module name, if it contains . or ..
345
- return callDep(makeMap(deps, callback).f);
346
- } else if (!deps.splice) {
347
- //deps is a config object, not an array.
348
- config = deps;
349
- if (config.deps) {
350
- req(config.deps, config.callback);
351
- }
352
- if (!callback) {
353
- return;
354
- }
355
-
356
- if (callback.splice) {
357
- //callback is an array, which means it is a dependency list.
358
- //Adjust args if there are dependencies
359
- deps = callback;
360
- callback = relName;
361
- relName = null;
362
- } else {
363
- deps = undef;
364
- }
365
- }
366
-
367
- //Support require(['a'])
368
- callback = callback || function () {};
369
-
370
- //If relName is a function, it is an errback handler,
371
- //so remove it.
372
- if (typeof relName === 'function') {
373
- relName = forceSync;
374
- forceSync = alt;
375
- }
376
-
377
- //Simulate async callback;
378
- if (forceSync) {
379
- main(undef, deps, callback, relName);
380
- } else {
381
- //Using a non-zero value because of concern for what old browsers
382
- //do, and latest browsers "upgrade" to 4 if lower value is used:
383
- //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
384
- //If want a value immediately, use require('id') instead -- something
385
- //that works in almond on the global level, but not guaranteed and
386
- //unlikely to work in other AMD implementations.
387
- setTimeout(function () {
388
- main(undef, deps, callback, relName);
389
- }, 4);
390
- }
391
-
392
- return req;
393
- };
394
-
395
- /**
396
- * Just drops the config on the floor, but returns req in case
397
- * the config return value is used.
398
- */
399
- req.config = function (cfg) {
400
- return req(cfg);
401
- };
402
-
403
- /**
404
- * Expose module registry for debugging and tooling
405
- */
406
- requirejs._defined = defined;
407
-
408
- define = function (name, deps, callback) {
409
- if (typeof name !== 'string') {
410
- throw new Error('See almond README: incorrect module build, no module name');
411
- }
412
-
413
- //This module may not have dependencies
414
- if (!deps.splice) {
415
- //deps is not an array, so probably means
416
- //an object literal or factory function for
417
- //the value. Adjust args.
418
- callback = deps;
419
- deps = [];
420
- }
421
-
422
- if (!hasProp(defined, name) && !hasProp(waiting, name)) {
423
- waiting[name] = [name, deps, callback];
424
- }
425
- };
426
-
427
- define.amd = {
428
- jQuery: true
429
- };
430
- }());